Comande
Una piccola app per le comande, riusata tre volte, dal registro di magazzino di un bar alle comande di un lounge bar, tenendo lo stack e riscrivendo di proposito il dominio.
- Stato
- Online · in attesa del locale
- Ruolo
- Unico sviluppatore
- Periodo
- ago – set 2026
- Piattaforma
- Web · installabile sul telefono (PWA)
- Stack
- Next.js · React · TypeScript · Tailwind · Supabase · Postgres
Problema
A un bar un'app per le comande serve per tre cose: chi è al banco o in sala manda la comanda dal telefono, il bancone la vede arrivare, e a fine serata il titolare legge cosa si è venduto, quando e chi l'ha servito. Il denaro lo gestisce già il registratore di cassa.
Ho costruito una piccola app per questo, e poi l'ho riusata. È nata come registro di magazzino per un bar, derivato dal modulo magazzino e cassa di La Fossa Events. L'ho derivata in un'app per le comande di un altro bar, e poi ho portato lo stesso codice, con lo stesso dominio, in un lounge bar. Lo stack è rimasto sempre lo stesso. Quello che ho riscritto, di proposito, sono il linguaggio e le regole.
Cosa ho costruito
- Comande dal telefono: lo staff tocca le voci del menù, spesso in piedi e con una mano sola, e manda una comanda completa in pochi secondi.
- Il bancone in tempo reale: le comande compaiono sullo schermo del bar appena partono. Il titolare le segna pagate, le ristampa o le annulla, con un motivo.
- La serata si apre da sola e si chiude a mano, e una serata dimenticata si chiude da sola dopo un numero di ore stabilito.
- Resoconti ricalcolati dalle comande: cosa si è venduto, per persona, per prodotto e per ora, a confronto con le serate passate.
- Stampa al bancone con un processo separato sul PC del bar, che legge una coda di stampa dal database.
- Un'interfaccia scura apposta, perché la serata è scura: si usa alle undici di sera in una sala in penombra.



Dove stava andando. Il terzo fork ha reso evidente il passo successivo: la stessa app, installata una volta per ogni locale. Ho cominciato una console per creare e gestire ogni locale, un'app Flutter per Windows, Linux e Android, e un agente di stampa installabile presso clienti diversi. Quel lavoro è in repo private, ed è la prima volta che il progetto è uscito dal browser.
Decisioni
Una comanda è una vendita, l'esatto contrario dell'app da cui deriva.
La prima app era un registro di magazzino, e la sua decisione fondante era "un prelievo non è una vendita". Quando l'ho derivata per prendere le comande di un bar, ho scritto che il dominio era ribaltato di proposito. La vecchia app tiene il magazzino e butta il denaro; questa tiene il denaro e butta il magazzino. Il magazzino di un bar resta vero solo se qualcuno lega ogni consumazione a ciò che consuma, e nessuno lo fa. Un numero che nessuno mantiene mente con l'autorevolezza di un numero.
Niente tavoli, niente conti aperti.
Ogni app di comande ha i tavoli. Questa no. Ogni comanda nasce completa e si paga al registratore di cassa, quindi niente mappa della sala, niente conto diviso e nessuna seconda cassa in concorrenza con quella vera. Ogni esclusione è scritta insieme alla condizione in cui smetterebbe di valere. Per un lounge bar con servizio al tavolo, quella condizione è la prima domanda da fare al titolare.
La sicurezza vive nel database, non nell'interfaccia.
Un trigger crea ogni account come membro dello staff e ignora i metadati inviati dall'utente, perché sono modificabili e chiunque potrebbe nascere titolare. Il ruolo lo scrive dopo una route del server con la chiave segreta. Le guardie TypeScript danno solo forma all'interfaccia; decide la sicurezza a livello di riga. Le comande non hanno nessuna policy di insert, quindi l'unico ingresso è una funzione del database che applica le regole.
Qualità
- 354asserzioni pgTAP sulle regole del database, eseguite in CI a ogni push
- 0errori ammessi negli advisor di sicurezza e prestazioni di Supabase, la build si ferma al primo
- 3app da un'unica base di codice, ciascuna con il suo dominio scritto
Come ci ho lavorato
Spec → ticket → agenti di coding, ogni decisione rivista e presa da me. Ogni fork comincia riscrivendo il glossario e gli ADR, e dichiara quali motivazioni ha ereditato senza ricontrollarle.
Stato e link
- StatoOnline · in attesa del locale
- CodiceSu richiesta