Η λειτουργία ενός εστιατορίου, ενός café ή ενός bar βασίζεται σε μια αλληλουχία ενεργειών που πρέπει να εκτελούνται γρήγορα, σωστά και με συνέπεια. Ένα τραπέζι ανοίγει, μια παραγγελία καταχωρίζεται, τα προϊόντα πρέπει να φτάσουν στον σωστό εκτυπωτή, ο λογαριασμός ενδέχεται να χωριστεί, η πληρωμή πρέπει να καταγραφεί και το τραπέζι να επιστρέψει σε διαθέσιμη κατάσταση.
Καθεμία από αυτές τις ενέργειες μοιάζει απλή όταν εξετάζεται ξεχωριστά. Όταν όμως πρέπει να λειτουργούν όλες μαζί, σε πραγματικό χρόνο και μέσα σε ένα περιβάλλον όπου η ταχύτητα είναι κρίσιμη, το πρόβλημα γίνεται πολύ πιο σύνθετο.
Αυτή ήταν η βασική ιδέα πίσω από το TableMaster. Δεν ήθελα να δημιουργήσω απλώς μια ακόμη φόρμα καταχώρισης παραγγελιών ή ένα οπτικό demo. Στόχος μου ήταν να σχεδιάσω μια ολοκληρωμένη web εφαρμογή που θα μπορούσε να ακολουθήσει την πραγματική λειτουργική ροή ενός χώρου εστίασης, από τη διαχείριση των τραπεζιών μέχρι την εκτύπωση της παραγγελίας και το κλείσιμο του λογαριασμού.
Το TableMaster αναπτύχθηκε με Python και Flask και συνδυάζει table management, παραγγελιοληψία, billing, διαχείριση προϊόντων, χρήστες, audit history, backup λειτουργίες και δικτυακή επικοινωνία με ESC/POS εκτυπωτές μέσα σε ένα responsive περιβάλλον χρήσης.
Το πρόβλημα που ήθελα να λύσω
Σε πολλούς χώρους εστίασης, η πληροφορία διασκορπίζεται ανάμεσα σε διαφορετικά εργαλεία και χειροκίνητες διαδικασίες. Η κατάσταση των τραπεζιών μπορεί να παρακολουθείται οπτικά, οι παραγγελίες να γράφονται ή να καταχωρίζονται σε ξεχωριστό σύστημα και οι αλλαγές να μεταφέρονται προφορικά ανάμεσα στη σάλα, την κουζίνα και το bar.
Αυτή η προσέγγιση μπορεί να λειτουργεί όταν ο φόρτος είναι μικρός. Σε περιόδους αυξημένης κίνησης, όμως, οι πιθανότητες λάθους αυξάνονται. Μια παραγγελία μπορεί να σταλεί στον λάθος εκτυπωτή, μια διαγραφή προϊόντος να μη διαθέτει ιστορικό, ένα τραπέζι να παραμένει λανθασμένα κατειλημμένο ή ένας λογαριασμός να χρειάζεται χειροκίνητους υπολογισμούς για να χωριστεί.
Το TableMaster σχεδιάστηκε ώστε όλες αυτές οι διαδικασίες να αποτελούν τμήματα της ίδιας λειτουργικής ροής. Η κατάσταση ενός τραπεζιού συνδέεται με την ενεργή του παραγγελία. Η παραγγελία συνδέεται με τα προϊόντα, τον χρήστη που την καταχώρισε και τους κατάλληλους εκτυπωτές. Η πληρωμή επηρεάζει την κατάσταση του λογαριασμού και τελικά το ίδιο το τραπέζι.
Με αυτόν τον τρόπο, η εφαρμογή δεν λειτουργεί ως μια συλλογή ανεξάρτητων σελίδων. Λειτουργεί ως ένα σύστημα στο οποίο κάθε ενέργεια έχει συνέπειες και ενημερώνει τα σχετικά δεδομένα.
Γιατί επέλεξα το Flask
Για το backend επέλεξα το Flask, επειδή μου έδωσε την ευελιξία να σχεδιάσω την εφαρμογή γύρω από τις πραγματικές ανάγκες του project, χωρίς να επιβάλει περιττή πολυπλοκότητα.
Το TableMaster ξεκίνησε ως ένα ενιαίο λειτουργικό σύστημα, αλλά όσο αυξάνονταν οι δυνατότητές του έγινε απαραίτητο να οργανωθεί σε διακριτούς τομείς. Οι λειτουργίες χωρίστηκαν σε modules για τα τραπέζια, τις παραγγελίες, το billing, τον κατάλογο προϊόντων, τις ρυθμίσεις και τις διαχειριστικές ενέργειες.
Αυτός ο διαχωρισμός βοήθησε να παραμείνει ο κώδικας πιο κατανοητός και να περιοριστεί η εξάρτηση ανάμεσα σε διαφορετικά χαρακτηριστικά. Παράλληλα, οι υπάρχουσες διευθύνσεις και τα Flask endpoint names διατηρήθηκαν σταθερά, ώστε η αναδιοργάνωση της αρχιτεκτονικής να μη διακόψει τη λειτουργία του interface.
Για την παρουσίαση χρησιμοποιούνται Jinja templates, HTML, CSS και JavaScript. Το περιβάλλον έχει σχεδιαστεί ώστε να προσαρμόζεται σε desktop, tablet και mobile συσκευές, κάτι ιδιαίτερα σημαντικό για μια εφαρμογή που μπορεί να χρησιμοποιηθεί σε διαφορετικά σημεία ενός καταστήματος.
Η SQLite ως βάση της τοπικής λειτουργίας
Για την αποθήκευση των δεδομένων επέλεξα τη SQLite. Η συγκεκριμένη επιλογή διατηρεί την εγκατάσταση ελαφριά και επιτρέπει στην εφαρμογή να λειτουργεί τοπικά, χωρίς να χρειάζεται ξεχωριστός database server.
Η βασική βάση δεδομένων περιλαμβάνει τραπέζια, κρατήσεις, παραγγελίες, προϊόντα, κατηγορίες, υποκατηγορίες, χρήστες, λογαριασμούς, εκτυπωτές, εταιρικά στοιχεία και γενικές ρυθμίσεις.
Μια δεύτερη, ξεχωριστή βάση χρησιμοποιείται για τα audit logs. Ο διαχωρισμός αυτός επιτρέπει στο ιστορικό κρίσιμων ενεργειών να διατηρείται ανεξάρτητα από τα καθημερινά λειτουργικά δεδομένα.
Η χρήση της SQLite δεν σημαίνει ότι η εφαρμογή αντιμετωπίζει τη βάση σαν ένα απλό αρχείο αποθήκευσης. Οι σχέσεις μεταξύ των δεδομένων αποτελούν κεντρικό μέρος του σχεδιασμού. Μια παραγγελία συνδέεται με ένα τραπέζι και έναν χρήστη. Τα προϊόντα συνδέονται με κατηγορίες. Οι κατηγορίες συνδέονται με συγκεκριμένους εκτυπωτές. Οι πληρωμές ενημερώνουν τις ποσότητες που έχουν ήδη εξοφληθεί.
Αυτές οι σχέσεις επιτρέπουν στο TableMaster να διατηρεί μια συνεπή εικόνα της λειτουργίας του καταστήματος.
Διαχείριση τραπεζιών και πραγματική κατάσταση της σάλας
Η οθόνη των τραπεζιών αποτελεί ένα από τα βασικά σημεία της εφαρμογής. Κάθε τραπέζι διαθέτει αριθμό, χωρητικότητα, χώρο και κατάσταση.
Η εφαρμογή μπορεί να ξεχωρίζει τα ελεύθερα, τα κατειλημμένα και τα δεσμευμένα τραπέζια. Η κατάσταση δεν είναι απλώς μια οπτική ένδειξη. Ενημερώνεται ως αποτέλεσμα των ενεργειών που πραγματοποιούνται μέσα στην εφαρμογή.
Όταν προστίθεται μια παραγγελία, το τραπέζι μετατρέπεται σε κατειλημμένο. Όταν ολοκληρώνεται η διαδικασία πληρωμής και κλείνει η ενεργή παραγγελία, το τραπέζι μπορεί να επιστρέψει σε διαθέσιμη κατάσταση.
Η προβολή λαμβάνει επίσης υπόψη κρατήσεις που αφορούν την τρέχουσα ημέρα. Έτσι, ο χρήστης δεν βλέπει μόνο μια στατική κάτοψη, αλλά μια λειτουργική εικόνα της διαθεσιμότητας.
Για τον συγχρονισμό της κατάστασης των τραπεζιών δημιουργείται ένα hash που αντιπροσωπεύει την τρέχουσα συνολική κατάσταση. Το frontend μπορεί να ελέγχει αν το hash έχει αλλάξει και να ανανεώνει την πληροφορία μόνο όταν υπάρχει πραγματική μεταβολή.
Η πλήρης διαδρομή μιας παραγγελίας
Η καταχώριση μιας παραγγελίας είναι περισσότερο από την επιλογή ορισμένων προϊόντων. Κάθε προϊόν μπορεί να διαθέτει ποσότητα, σχόλια και σχετικές υποκατηγορίες ή επιλογές.
Η εφαρμογή αναζητά αν υπάρχει ήδη ενεργή παραγγελία για το συγκεκριμένο τραπέζι. Αν δεν υπάρχει, δημιουργεί μια νέα. Αν υπάρχει, τα νέα προϊόντα προστίθενται στην ίδια ενεργή παραγγελία.
Τα προϊόντα που εμφανίζονται στο περιβάλλον παραγγελιοληψίας προέρχονται μόνο από ενεργές κατηγορίες και ενεργές καταχωρίσεις. Αυτό επιτρέπει σε έναν administrator να απενεργοποιήσει προσωρινά ένα προϊόν χωρίς να διαγράψει το ιστορικό του από προηγούμενες παραγγελίες.
Το TableMaster καταγράφει επίσης ποιος χρήστης δημιούργησε κάθε παραγγελία. Το ιστορικό μπορεί να φιλτραριστεί με βάση την κατάσταση, το τραπέζι, τον χρήστη και το χρονικό διάστημα. Οι administrators μπορούν να βλέπουν τη συνολική δραστηριότητα, ενώ οι υπόλοιποι χρήστες περιορίζονται στις δικές τους παραγγελίες.
Δρομολόγηση προϊόντων στους σωστούς εκτυπωτές
Μία από τις σημαντικότερες λειτουργίες του TableMaster είναι η σύνδεση των κατηγοριών προϊόντων με διαφορετικούς δικτυακούς εκτυπωτές.
Σε έναν πραγματικό χώρο εστίασης, όλα τα προϊόντα δεν πρέπει να εκτυπώνονται στο ίδιο σημείο. Τα ροφήματα μπορεί να πρέπει να φτάσουν στο bar, τα φαγητά στην κουζίνα και ο λογαριασμός σε διαφορετικό εκτυπωτή.
Ο administrator μπορεί να καταχωρίσει ESC/POS εκτυπωτές με τη διεύθυνση IP τους και να αντιστοιχίσει κάθε εκτυπωτή με μία ή περισσότερες κατηγορίες. Όταν αποστέλλεται μια νέα παραγγελία, το TableMaster ομαδοποιεί τα προϊόντα ανάλογα με την κατηγορία τους και δημιουργεί ξεχωριστή εργασία για κάθε σχετικό εκτυπωτή.
Με αυτόν τον τρόπο, μια ενιαία παραγγελία μπορεί να χωριστεί αυτόματα και να φτάσει στα κατάλληλα σημεία του καταστήματος χωρίς να απαιτείται χειροκίνητη επιλογή εκτυπωτή από τον χρήστη.
Σχεδιάζοντας για την περίπτωση αποτυχίας
Η επικοινωνία με έναν δικτυακό εκτυπωτή δεν είναι πάντοτε εγγυημένη. Ο εκτυπωτής μπορεί να είναι κλειστός, να έχει αποσυνδεθεί από το δίκτυο ή να μην απαντά προσωρινά.
Το εύκολο σενάριο θα ήταν η εφαρμογή να εμφανίζει απλώς ένα σφάλμα. Σε ένα πραγματικό περιβάλλον, όμως, αυτό δεν είναι αρκετό. Η παραγγελία δεν πρέπει να χαθεί επειδή ο εκτυπωτής ήταν προσωρινά εκτός λειτουργίας.
Πριν από κάθε εκτύπωση, το TableMaster ελέγχει αν η συσκευή είναι προσβάσιμη μέσω του δικτύου. Αν ο εκτυπωτής είναι διαθέσιμος, η παραγγελία αποστέλλεται άμεσα. Αν δεν είναι, το περιεχόμενο αποθηκεύεται σε μια ουρά εκκρεμών εκτυπώσεων μέσα στη βάση δεδομένων.
Ένας background scheduler ελέγχει περιοδικά την ουρά. Όταν ο εκτυπωτής γίνει ξανά διαθέσιμος, η εργασία αποστέλλεται και αφαιρείται από τη λίστα των εκκρεμοτήτων.
Η ίδια λογική εφαρμόζεται τόσο στις παραγγελίες όσο και στις αποδείξεις εσωτερικής χρήσης. Ο administrator μπορεί να βλέπει τις εκκρεμείς εργασίες και να ακυρώνει κάποια από αυτές όταν αυτό είναι απαραίτητο.
Αυτή η λειτουργία ήταν ένα από τα πιο σημαντικά τεχνικά σημεία του project, επειδή με ανάγκασε να σχεδιάσω όχι μόνο για το επιτυχημένο σενάριο, αλλά και για τις περιπτώσεις όπου μια εξωτερική συσκευή αποτυγχάνει.
Billing, διαχωρισμός λογαριασμού και πληρωμές
Σε ένα εστιατόριο, ο λογαριασμός δεν πληρώνεται πάντοτε ως ένα ενιαίο ποσό. Διαφορετικά άτομα μπορεί να θέλουν να πληρώσουν συγκεκριμένα προϊόντα ή διαφορετικά τμήματα της ίδιας παραγγελίας.
Το TableMaster υποστηρίζει επιμερισμό λογαριασμού σε επίπεδο προϊόντος. Ο χρήστης μπορεί να επιλέξει ποια αντικείμενα εξοφλούνται και η εφαρμογή ενημερώνει τις αντίστοιχες πληρωμένες ποσότητες.
Όταν εξοφληθούν όλα τα προϊόντα μιας παραγγελίας, η κατάστασή της αλλάζει σε πληρωμένη. Παράλληλα, διατηρούνται στοιχεία για το συνολικό ποσό και τη μέθοδο πληρωμής.
Η εφαρμογή μπορεί επίσης να δημιουργήσει και να εκτυπώσει ένα εσωτερικό παραστατικό, χρησιμοποιώντας τα στοιχεία της επιχείρησης, τις τιμές, τους συντελεστές ΦΠΑ και την επιλεγμένη μέθοδο πληρωμής.
Το συγκεκριμένο παραστατικό εξυπηρετεί την εσωτερική λειτουργία της εφαρμογής και δεν παρουσιάζεται ως αντικατάσταση πιστοποιημένου φορολογικού ή ταμειακού μηχανισμού.
Μεταφορά παραγγελιών μεταξύ τραπεζιών
Μια ακόμη πραγματική ανάγκη της εστίασης είναι η μετακίνηση πελατών από ένα τραπέζι σε άλλο.
Το TableMaster επιτρέπει τη μεταφορά της ενεργής παραγγελίας από ένα τραπέζι σε κάποιο άλλο. Αν το τραπέζι προορισμού δεν έχει ενεργή παραγγελία, η υπάρχουσα παραγγελία μεταφέρεται. Αν έχει ήδη, τα προϊόντα των δύο παραγγελιών συγχωνεύονται.
Μετά τη διαδικασία, το τραπέζι προορισμού εμφανίζεται ως κατειλημμένο και το αρχικό τραπέζι απελευθερώνεται όταν δεν διαθέτει άλλες ενεργές παραγγελίες.
Αυτή η λειτουργία δείχνει γιατί ήταν σημαντικό να αντιμετωπιστεί η εφαρμογή ως ένα συνδεδεμένο σύστημα. Η μεταφορά δεν αφορά μόνο την αλλαγή ενός αριθμού. Πρέπει να διατηρεί τα προϊόντα, την ενεργή παραγγελία και τις καταστάσεις και των δύο τραπεζιών σε συνέπεια.
Διαχείριση καταλόγου και Excel workflows
Το TableMaster διαθέτει ολοκληρωμένη διαχείριση κατηγοριών, υποκατηγοριών και προϊόντων.
Οι κατηγορίες μπορούν να περιλαμβάνουν διαφορετικό συντελεστή ΦΠΑ και να συνδέονται με συγκεκριμένους εκτυπωτές. Τα προϊόντα μπορούν να δημιουργηθούν, να επεξεργαστούν, να απενεργοποιηθούν και να επανενεργοποιηθούν.
Για τη διαγραφή προϊόντων και κατηγοριών χρησιμοποιείται λογική απενεργοποίηση. Με αυτόν τον τρόπο, ένα προϊόν μπορεί να αφαιρεθεί από τη διαθέσιμη λίστα χωρίς να καταστραφεί το ιστορικό των παραγγελιών στις οποίες είχε χρησιμοποιηθεί.
Η εφαρμογή υποστηρίζει επίσης εισαγωγή καταλόγου μέσω αρχείου Excel. Τα αρχεία ελέγχονται πριν από την επεξεργασία και χρησιμοποιούνται εργαλεία όπως Pandas και OpenPyXL για τη μετατροπή των spreadsheet δεδομένων σε εγγραφές της εφαρμογής.
Το ιστορικό των παραγγελιών μπορεί επίσης να εξαχθεί σε μορφοποιημένο αρχείο Excel, με φίλτρα ημερομηνίας, κατάστασης, χρήστη και τραπεζιού.
Αυτή η λειτουργία επιτρέπει στην εφαρμογή να συνεργάζεται με ένα εργαλείο που χρησιμοποιείται ήδη ευρέως από επιχειρήσεις, αντί να απαιτεί όλες οι εργασίες να πραγματοποιούνται αποκλειστικά μέσα στο TableMaster.
Χρήστες, ρόλοι και συνεδρίες
Η πρόσβαση πραγματοποιείται μέσω προσωπικού τετραψήφιου PIN. Κάθε χρήστης διαθέτει ρόλο administrator ή staff, ο οποίος καθορίζει τις λειτουργίες και τις πληροφορίες στις οποίες μπορεί να έχει πρόσβαση.
Οι διαχειριστικές ρυθμίσεις είναι διαθέσιμες μόνο στους administrators. Οι απλοί χρήστες μπορούν να εργάζονται με τις καθημερινές λειτουργίες χωρίς να έχουν πρόσβαση στη διαχείριση χρηστών, εκτυπωτών, backups ή εταιρικών στοιχείων.
Οι συνεδρίες διαθέτουν χρόνο αδράνειας, ο οποίος μπορεί να οριστεί από τις ρυθμίσεις. Όταν ο χρόνος αυτός ξεπεραστεί, η συνεδρία καθαρίζεται και ο χρήστης πρέπει να συνδεθεί ξανά.
Η δυνατότητα αυτή είναι ιδιαίτερα χρήσιμη σε κοινόχρηστες συσκευές, όπου ένα tablet ή workstation μπορεί να χρησιμοποιείται διαδοχικά από διαφορετικά μέλη της ομάδας.
Audit history και λογοδοσία
Σε ένα περιβάλλον παραγγελιοληψίας, η διαγραφή ενός προϊόντος από ενεργή παραγγελία είναι σημαντική ενέργεια. Δεν πρέπει να εξαφανίζεται χωρίς να υπάρχει καταγραφή.
Το TableMaster διατηρεί ξεχωριστό audit log για τις διαγραφές προϊόντων. Κάθε καταγραφή περιλαμβάνει το προϊόν, το τραπέζι, τον χρήστη και τη χρονική στιγμή της ενέργειας.
Ο administrator μπορεί να φιλτράρει τα logs με βάση την ημερομηνία και τον χρήστη. Έτσι δημιουργείται ένα βασικό επίπεδο λογοδοσίας, χωρίς να επιβαρύνεται η κύρια βάση δεδομένων με διαφορετικό τύπο ιστορικών δεδομένων.
Ρυθμίσεις, εταιρικά στοιχεία και backup
Η εφαρμογή διαθέτει κεντρικό περιβάλλον ρυθμίσεων για τη διαχείριση προϊόντων, χρηστών, εκτυπωτών, παραστατικών, εταιρικών στοιχείων και γενικών επιλογών.
Ο administrator μπορεί να ορίσει τον εκτυπωτή παραστατικών, να επιλέξει αν θα πραγματοποιείται εκτύπωση κατά το κλείσιμο του τραπεζιού και να ρυθμίσει τον χρόνο λήξης της συνεδρίας.
Τα στοιχεία της επιχείρησης, όπως η επωνυμία, η διεύθυνση, το ΑΦΜ, η ΔΟΥ και το τηλέφωνο, μπορούν να αποθηκευτούν και να χρησιμοποιηθούν κατά τη δημιουργία των εσωτερικών παραστατικών.
Για τη διατήρηση των δεδομένων υπάρχει δυνατότητα εξαγωγής backup. Η κύρια βάση και η βάση των audit logs συγκεντρώνονται σε ένα αρχείο ZIP, το οποίο μπορεί να αποθηκευτεί από τον administrator.
Η λειτουργία restore ελέγχει αν το αρχείο περιλαμβάνει τις απαραίτητες βάσεις, δημιουργεί αντίγραφα των υφιστάμενων αρχείων και προσπαθεί να επαναφέρει τα δεδομένα. Αν παρουσιαστεί σφάλμα, τα προηγούμενα αρχεία μπορούν να επανέλθουν.
Offline friendly σχεδιασμός και PWA στοιχεία
Το TableMaster περιλαμβάνει web app manifest, service worker και ξεχωριστή offline σελίδα.
Αυτό δεν μετατρέπει όλες τις δυναμικές λειτουργίες της εφαρμογής σε πλήρως offline διαδικασίες, αφού οι παραγγελίες και οι βάσεις δεδομένων εξακολουθούν να απαιτούν επικοινωνία με τον τοπικό Flask server. Προσφέρει όμως μια πιο ολοκληρωμένη εμπειρία εγκατάστασης και βασική διαχείριση περιπτώσεων όπου η εφαρμογή δεν μπορεί να επικοινωνήσει προσωρινά με τον server.
Το responsive interface επιτρέπει επίσης στο TableMaster να χρησιμοποιείται από desktop, tablet ή κινητή συσκευή μέσα στο ίδιο τοπικό δίκτυο.
Το σύστημα αδειοδότησης
Το project περιλαμβάνει έναν τοπικό μηχανισμό αδειοδότησης εγκατάστασης. Η εφαρμογή διαβάζει ένα κρυπτογραφημένο license key και το συγκρίνει με ένα αναμενόμενο κλειδί που παράγεται από τη MAC διεύθυνση της συσκευής.
Αν η άδεια δεν είναι διαθέσιμη ή δεν αντιστοιχεί στη συσκευή, η βασική εφαρμογή δεν ξεκινά και εμφανίζεται ειδική σελίδα ενημέρωσης.
Η λειτουργία αυτή δεν αποτελεί σύνθετη cloud licensing πλατφόρμα. Αποτελεί όμως μια πρακτική εφαρμογή κρυπτογράφησης, machine binding και ελέγχου πρόσβασης σε μια τοπική εγκατάσταση.
Αναδιοργανώνοντας την αρχιτεκτονική
Καθώς το TableMaster αποκτούσε περισσότερες λειτουργίες, η διατήρηση όλων των routes σε ένα ενιαίο αρχείο θα έκανε το project δυσκολότερο στη συντήρηση.
Για αυτόν τον λόγο, οι διαδρομές οργανώθηκαν σε ξεχωριστά modules ανά λειτουργικό τομέα. Υπάρχει διαφορετικό module για τον πυρήνα και την αυθεντικοποίηση, τα τραπέζια, τις παραγγελίες, το billing, τον κατάλογο, τις ρυθμίσεις και τις διαχειριστικές ενέργειες.
Παρόμοια οργάνωση χρησιμοποιήθηκε και στο frontend. Τα κοινά CSS components διαχωρίστηκαν από τα styles συγκεκριμένων σελίδων, ενώ τα κοινά JavaScript behaviours οργανώθηκαν ανεξάρτητα από τις λειτουργίες κάθε οθόνης.
Το repository περιλαμβάνει επίσης ελέγχους για Python syntax, αρχικοποίηση βάσεων, parsing των templates, static asset references, route coverage και απουσία ευαίσθητων runtime αρχείων από το δημόσιο repository.
Η αναδιοργάνωση αυτή ήταν σημαντικό βήμα, επειδή μετέτρεψε το TableMaster από μια εφαρμογή που απλώς λειτουργεί σε ένα project που μπορεί να συνεχίσει να εξελίσσεται.
Οι σημαντικότερες τεχνικές προκλήσεις
Η μεγαλύτερη πρόκληση δεν ήταν η δημιουργία μιας συγκεκριμένης φόρμας ή ενός route. Ήταν η διατήρηση της συνέπειας ανάμεσα σε πολλές διαφορετικές ενέργειες.
Όταν μεταφέρεται μια παραγγελία, πρέπει να ενημερωθούν δύο τραπέζια. Όταν διαγράφεται το τελευταίο προϊόν μιας παραγγελίας, πρέπει να εξεταστεί αν η παραγγελία και το τραπέζι παραμένουν ενεργά. Όταν μια εκτύπωση αποτυγχάνει, πρέπει να διατηρηθεί χωρίς να διπλοεκτυπωθεί αργότερα. Όταν ο λογαριασμός χωρίζεται, πρέπει να καταγράφεται ποια προϊόντα έχουν ήδη εξοφληθεί.
Η SQLite δημιούργησε επίσης πραγματικές προκλήσεις σε λειτουργίες που εκτελούνται από διαφορετικά threads. Σε σημεία όπου μπορούσε να παρουσιαστεί προσωρινό database lock, προστέθηκε μηχανισμός επαναπροσπάθειας αντί η εργασία να απορρίπτεται αμέσως.
Αυτές οι περιπτώσεις με βοήθησαν να κατανοήσω καλύτερα ότι η αξιοπιστία μιας εφαρμογής δεν καθορίζεται από το πώς λειτουργεί όταν όλα πηγαίνουν σωστά. Καθορίζεται από το πώς συμπεριφέρεται όταν μια συσκευή δεν απαντά, μια βάση είναι προσωρινά κλειδωμένη ή ένας χρήστης εκτελεί μια μη αναμενόμενη ακολουθία ενεργειών.
Τι έμαθα από την ανάπτυξη του TableMaster
Το TableMaster ήταν ένα από τα projects που με βοήθησαν να συνδέσω διαφορετικές περιοχές της ανάπτυξης λογισμικού μέσα σε ένα ενιαίο σύστημα.
Χρειάστηκε να σχεδιάσω το database schema, να οργανώσω Flask routes, να δημιουργήσω responsive interfaces, να διαχειριστώ sessions και ρόλους, να επεξεργαστώ αρχεία Excel και να επικοινωνήσω με πραγματικές δικτυακές συσκευές.
Το σημαντικότερο μάθημα ήταν ότι μια επιχειρησιακή εφαρμογή δεν πρέπει να σχεδιάζεται μόνο γύρω από τις οθόνες της. Πρέπει να σχεδιάζεται γύρω από τις πραγματικές διαδικασίες των ανθρώπων που θα τη χρησιμοποιούν.
Η οθόνη των τραπεζιών, για παράδειγμα, δεν έχει αξία μόνο επειδή δείχνει χρωματισμένα κουτιά. Έχει αξία επειδή αντικατοπτρίζει την πραγματική κατάσταση των παραγγελιών. Η ουρά εκτυπώσεων δεν έχει αξία μόνο ως τεχνικό χαρακτηριστικό. Έχει αξία επειδή προστατεύει μια παραγγελία όταν ένας εκτυπωτής αποτύχει.
Αυτή η σύνδεση ανάμεσα στην τεχνική υλοποίηση και στην πραγματική λειτουργική ανάγκη είναι το στοιχείο που θεωρώ σημαντικότερο στο project.
Περιορισμοί και επόμενα βήματα
Παρότι το TableMaster διαθέτει ήδη μια ολοκληρωμένη λειτουργική βάση, υπάρχουν αρκετοί τομείς που μπορούν να εξελιχθούν.
Η αυθεντικοποίηση μπορεί να ενισχυθεί με hashed PINs, CSRF protection, αυστηρότερα permissions και πιο ολοκληρωμένη διαχείριση μυστικών και ρυθμίσεων.
Η βάση δεδομένων μπορεί μελλοντικά να μεταφερθεί σε PostgreSQL για εγκαταστάσεις με μεγαλύτερο αριθμό ταυτόχρονων χρηστών ή πολλαπλά καταστήματα. Παράλληλα, ένα database migration system θα επέτρεπε ασφαλέστερη εξέλιξη του schema.
Η ουρά των εκτυπώσεων θα μπορούσε να μεταφερθεί σε ανεξάρτητο worker service, με αναλυτικότερα retry policies, μοναδικά job identifiers και καλύτερη προστασία από διπλές εκτυπώσεις.
Στα μελλοντικά βήματα μπορούν επίσης να προστεθούν inventory management, αναλυτικό reservations workflow, dashboards πωλήσεων, live kitchen display, push notifications, API integrations και συγχρονισμός πολλαπλών εγκαταστάσεων.
Σε επίπεδο deployment, μια production έκδοση θα μπορούσε να χρησιμοποιεί WSGI server, reverse proxy, HTTPS, centralized logging και αυτοματοποιημένο update mechanism.
Τελικές σκέψεις
Το TableMaster ξεκίνησε από την ανάγκη να οργανωθούν οι καθημερινές λειτουργίες ενός χώρου εστίασης μέσα σε ένα ενιαίο σύστημα.
Στην πορεία εξελίχθηκε σε μια ολοκληρωμένη εφαρμογή που συνδυάζει backend development, database design, responsive frontend, δικτυακή επικοινωνία, background εργασίες, audit logging και επιχειρησιακή λογική.
Δεν δημιουργήθηκε ως ένα θεωρητικό παράδειγμα Flask. Δημιουργήθηκε ως μια προσπάθεια να μεταφραστεί μια πραγματική επιχειρησιακή διαδικασία σε λογισμικό.
Αυτό είναι και το βασικό στοιχείο που αντιπροσωπεύει για εμένα το TableMaster. Την ικανότητα να παρατηρώ μια σύνθετη καθημερινή ροή, να τη χωρίζω σε διαχειρίσιμα τεχνικά προβλήματα και να δημιουργώ μια λύση που συνδέει όλα αυτά τα μέρη σε ένα συνεπές και επεκτάσιμο σύστημα.
