
Τι Είναι Πραγματικά μια Έκδοση 127 Commit
Το GeekBye v1.7.0 ήταν 127 commit σε έντεκα μέρες. Απ' έξω μοιάζει με εκατό μικρά πράγματα. Από μέσα ήταν δύο μεγάλες λειτουργίες πλεγμένες μαζί — και η μία χτίστηκε σε λάθος σημείο, μετά ξηλώθηκε και ξαναχτίστηκε στη μέση της έκδοσης. Ιδού η ανατομία μιας μεγάλης έκδοσης.
Υπάρχει μια εκδοχή αυτής της ανάρτησης που απλώς απαριθμεί τα πάντα στο GeekBye v1.7.0 — μια ανασχεδιασμένη αρχική οθόνη, μια ροή βαθμονόμησης, μια αναδιπλούμενη πλευρική μπάρα, νέες ρυθμίσεις, και ούτω καθεξής. Θα ήταν ακριβής και δεν θα σου μάθαινε τίποτα. Γιατί η ειλικρινής ιστορία μιας έκδοσης 127 commit δεν είναι η λίστα. Είναι το σχήμα.
Ιδού το σχήμα. Εκατόν είκοσι επτά commit ακούγονται σαν εκατόν είκοσι επτά μικρά πράγματα. Σχεδόν ποτέ δεν είναι. Το v1.7.0 ήταν δύο μεγάλες λειτουργίες, χτισμένες παράλληλα σε μακρόβια branch για περίπου έντεκα μέρες, πλεγμένες μαζί στο τέλος. Το να κατανοήσεις μια μεγάλη έκδοση σημαίνει να κατανοήσεις αυτά τα δύο νήματα — και το ένα σημείο όπου χτίσαμε κάτι σε λάθος θέση και χρειάστηκε να το ξηλώσουμε στην πορεία.
Νήμα ένα: βαθμονόμηση
Το πρώτο νήμα ήταν η βαθμονόμηση — μια αξιολόγηση φωνής με AI για τις επικοινωνιακές σου δεξιότητες. Ξεκινάς μια ζωντανή κλήση με έναν AI «σύμβουλο καριέρας», περνάς μέσα από ένα δομημένο σύνολο φάσεων (προθέρμανση, συμπεριφορική, τεχνική επικοινωνία, απόκριση υπό πίεση, καθορισμός στόχων), και στο τέλος βαθμολογείσαι σε έξι διαστάσεις: αυτοπεποίθηση, σαφήνεια, ακρίβεια, εμπλοκή, ψυχραιμία, συνάφεια. Από κάτω, μετρά και συγκεκριμένες μετρικές ομιλίας — τον ρυθμό ομιλίας σου, τη συχνότητα των λέξεων γεμίσματος, το αν οι παύσεις σου διαβάζονται ως στρατηγικές ή διστακτικές.
Το αποτέλεσμα δεν είναι βαθμός, είναι ένα σημείο εκκίνησης. Η βαθμονόμηση παράγει τα δυνατά σου σημεία, τις περιοχές ανάπτυξής σου, και — κρίσιμα — μια προτεινόμενη δυσκολία από την οποία να ξεκινήσεις να εξασκείσαι. Βαθμονομεί το πού πρέπει το προϊόν να σε συναντήσει. Κάθε δεξιότητα επιστρέφει ως αναπτυσσόμενη κάρτα σχολίων με μια σύνοψη, μια συγκεκριμένη πρόταση, και μια πραγματική παρατιθέμενη ατάκα από την ίδια σου την κλήση ως παράδειγμα. Είναι η λειτουργία πάνω στην οποία χτίζεται η υπόλοιπη εμπειρία εξάσκησης.
Νήμα δύο: ένα ολόκληρο νέο παράθυρο
Το δεύτερο νήμα ήταν μια premium ανασχεδίαση — και το να την αποκαλείς ανασχεδίαση την υποτιμά. Δεν ήταν ένα ξαναβάψιμο των υπαρχουσών οθονών· ήταν ουσιαστικά ένα δεύτερο παράθυρο εφαρμογής, χτισμένο σε έξι ρητές φάσεις: μια αναδιπλούμενη πλευρική μπάρα σε στυλ Notion, ένα αναπτυσσόμενο μενού στην κεφαλίδα που αντικατέστησε την παλιά λίστα συνεδριών, πλοήγηση σε στυλ browser με ιστορικό και breadcrumbs, και premium ανακατασκευές της Αρχικής, των Προφίλ, των Συναντήσεων και των Ρυθμίσεων.
Δύο μεγάλες λειτουργίες. Αυτό ήταν πραγματικά τα 127 commit. Και το πιο δύσκολο κομμάτι της παράδοσής τους δεν ήταν να γράψεις καμία από τις δύο — ήταν το πλέξιμο. Τα δύο branch ήταν αλληλεξαρτώμενα· το ένα έγινε merge στο άλλο, και το branch της βαθμονόμησης χρειάστηκε να τραβήξει μέσα το main branch τέσσερις ξεχωριστές φορές μόνο και μόνο για να μην ξεφύγει από τον συγχρονισμό ενώ η ανασχεδίαση κινούνταν από κάτω του. Το πλήθος των commit δεν είναι το κόστος μιας μεγάλης έκδοσης. Τα μακρόβια branch και η σειρά ενσωμάτωσης είναι.
Το κομμάτι που αξίζει το διάβασμα: χτίσαμε τη βαθμονόμηση σε λάθος μέρος
Ιδού το λάθος, και είναι ένα καλό γιατί είναι τόσο συνηθισμένο.
Το GeekBye έχει έναν σταθερό αρχιτεκτονικό κανόνα: όλες οι λειτουργίες AI ζουν στο backend. Ο client είναι ένα λεπτό κέλυφος που μιλά σε έναν server. Όλοι το ήξεραν αυτό.
Κι όμως η βαθμονόμηση χτίστηκε πρώτα στην τοπική βάση δεδομένων του client. Έναν αποκλειστικό πίνακα, μια μετάπτωση βάσης δεδομένων, ένα repository 254 γραμμών, IPC handlers, και μια δεξαμενή 515 γραμμών ερωτήσεων αξιολόγησης — όλα να ζουν στο μηχάνημα του χρήστη. Λειτουργούσε. Παραβίαζε επίσης σιωπηλά το συμβόλαιο πάνω στο οποίο είναι χτισμένη όλη η εφαρμογή.
Τρεις μέρες αργότερα, ένα commit διέγραψε 680 γραμμές σε οκτώ αρχεία για να τα μεταφέρει όλα στο backend, όπου τα δεδομένα βαθμονόμησης έγιναν ένα κανονικό μοντέλο από τη μεριά του server, και η λογική των ερωτήσεων και η βαθμολόγηση έγιναν υπόθεση του server. Ένα άλλο commit διέγραψε ολοσχερώς τη δεξαμενή 515 γραμμών ερωτήσεων του client. Το diff είναι σχεδόν αστείο: μία εισαγωγή, εξακόσιες ογδόντα διαγραφές.
Κανείς δεν ξεκίνησε να γράψει 680 γραμμές αναλώσιμου κώδικα. Συνέβη με τον τρόπο που αυτό συμβαίνει πάντα: η συντόμευση του client είναι ακριβώς εκεί, είναι πιο γρήγορο να κάνεις πρωτότυπο τοπικά, και το «θα το μεταφέρουμε στο backend αργότερα» μοιάζει αβλαβές. Αλλά όταν η αρχιτεκτονική σου σου λέει ήδη πού βρίσκεται η πηγή αλήθειας, το να το χτίσεις οπουδήποτε αλλού δεν είναι συντόμευση — είναι επανεργασία που έχεις προγραμματίσει εκ των προτέρων για τον εαυτό σου. Το μάθημα που έμεινε: βάλ' το εκεί που λέει το συμβόλαιο, από την πρώτη φορά, ακόμη κι όταν η τοπική εκδοχή στήνεται πιο γρήγορα.
Το σφάλμα που μόνο η ενσωμάτωση μπορούσε να βρει
Άλλη μία απόδειξη, γιατί είναι ο χαρακτηριστικός τρόπος αποτυχίας των μεγάλων εκδόσεων. Μόλις η βαθμονόμηση και η νέα πλοήγηση συνδέθηκαν μεταξύ τους και έτρεχαν πραγματικά, η εφαρμογή άρχισε να ενεργοποιεί ένα rate limit — HTTP 429 — χωρίς προφανή λόγο.
Η αιτία ήταν καθαρά θέμα ενσωμάτωσης. Η κατάσταση βαθμονόμησης γινόταν fetch σε επίπεδο component, οπότε κάθε πλοήγηση την ξανα-fetch-αρε — και το strict mode του React, που εσκεμμένα καλεί δύο φορές τα effects στην ανάπτυξη για να αναδείξει σφάλματα, το διπλασίασε ξανά. Το αποτέλεσμα ήταν τέσσερα έως οκτώ πανομοιότυπα αιτήματα βαθμονόμησης να πυροδοτούνται ανά αλλαγή οθόνης, αρκετά για να ενεργοποιήσουν τον rate limiter του server. Η διόρθωση ενοποίησε το fetching σε μερικές κλήσεις κατά το mount.
Δεν θα μπορούσες να είχες βρει αυτό το σφάλμα δοκιμάζοντας μόνο τη βαθμονόμηση, ή μόνο την πλοήγηση. Υπάρχει μόνο στη ραφή — εκεί όπου συναντιούνται δύο ανεξάρτητα σωστές λειτουργίες. Αυτός είναι ο φόρος που χρεώνει μια μεγάλη έκδοση: το τελευταίο μίλι δεν είναι το χτίσιμο των λειτουργιών, είναι η ανακάλυψη όλων όσων σπάνε μόνο όταν βρεθούν επιτέλους στο ίδιο δωμάτιο.
Τρία πράγματα που δίδαξε μια μεγάλη έκδοση
- Μια έκδοση 127 commit είναι δύο ή τρία μεγάλα θέματα, όχι εκατό μικρά. Βρες τα νήματα. Η δουλειά — και ο κίνδυνος — βρίσκεται στο πώς πλέκονται μαζί, όχι στο πλήθος.
- Βάλε την πηγή αλήθειας εκεί που λέει το συμβόλαιο ότι ζει, από την πρώτη φορά. Διαγράψαμε 680 γραμμές μεταφέροντας τη βαθμονόμηση από τον client στο backend. Η τοπική συντόμευση είναι επανεργασία που έχεις προγραμματίσει εκ των προτέρων· η αρχιτεκτονική σου είχε ήδη πει την απάντηση.
- Η ενσωμάτωση αναδεικνύει αποτυχίες που η απομόνωση δεν μπορεί. Η καταιγίδα των 429 ζούσε στη ραφή ανάμεσα σε δύο σωστές λειτουργίες και εμφανίστηκε μόνο μόλις έτρεξαν μαζί. Προϋπολόγισε ένα πέρασμα ενσωμάτωσης, όχι μόνο δοκιμές ανά λειτουργία.
Αυτό είναι ένα ξαδερφάκι από την εποχή του v1 μιας ιστορίας που θα διηγηθούμε ξανά σε πολύ μεγαλύτερη κλίμακα — δες τι χρειάζεται πραγματικά μια έκδοση 2: 206 commit ειλικρινών καταστάσεων (v2.0.0), όπου η ίδια αλήθεια του «ένας μεγάλος αριθμός είναι στην πραγματικότητα μερικές μεγάλες ιδέες» εκτυλίσσεται σε όλη την ξαναγραφή του v2. Για το προηγούμενο κεφάλαιο στην ιστορία του v1, πώς να μεταδώσεις μια ζωντανή αναφορά χωρίς το τρεμόπαιγμα (v1.6.13)· και για ολόκληρη την πορεία, η ανατομία της παράδοσης λογισμικού στην τελειότητα.