Canteen
Objednávky a výdaj obedov vo firemných jedálňach. Zamestnanci si obed vyberú na webe alebo na kiosku, kuchyňa vie počty vopred a pri výdaji stačí načítať kartu.
- Klient
- Fellow Bytes, vlastný produkt
- Moja rola
- Architektúra, všetky štyri frontendy, API
- Obdobie
- Apríl 2026 – dodnes
- Stav
- Vo vývoji, pracujem na offline režime
- Technológie
- Next.js 16, React 19, Vite PWA, NestJS, Prisma, PostgreSQL, Redis, Socket.IO, Python


Prečo vznikol
Firemná jedáleň varí pre zamestnancov niekoľkých firiem. Každý zamestnanec má nárok na jeden dotovaný obed denne a firme sa účtuje podľa počtu takých obedov, ktoré jej ľudia zjedli, nie podľa sumy. Tento počet sa zvyčajne vedie na papierových zoznamoch a na konci mesiaca v tabuľke.
Kuchyňa nevie, koľko má navariť, na výdaji hľadajú mená vo vytlačenom zozname a vyúčtovanie znamená deň ručného počítania. Canteen nahrádza všetky tri jedným systémom, do ktorého prevádzkovateľ, kuchyňa, výdaj aj zamestnanci vidia každý zo svojej strany.
Štyri aplikácie, jedno API
Každá rola dostane obrazovku, ktorú potrebuje, a nič navyše. Všetky štyri komunikujú s tým istým NestJS API. Typy, formátovanie súm a biznis pravidlá sú v spoločných balíčkoch, takže sa aplikácie nemôžu rozísť v tom, čo znamená dotácia alebo uzávierka objednávok.

Výdajný terminál
- Po načítaní karty sa otvoria dnešné objednávky stravníka. Čítačka sa správa ako klávesnica, takže funguje akákoľvek USB čítačka.
- Terminály sú prepojené naživo. Obed vydaný na jednom z ostatných zmizne, cieľ je pod 200 ms.
- Dotovaný obed a všetko navyše sú samostatné objednávky, pretože firma platí za každý dotovaný obed.
- Výdaj je jedno ťuknutie a požiadavka je idempotentná: dvojité ťuknutie alebo opakovanie po výpadku spojenia vydá obed iba raz.


Web pre zamestnancov
Týždeň dopredu, denné menu s alergénmi, priebežný súčet, ktorý ukazuje, čo pokryje dotácia, a história objednávok s kreditom.

Kiosk
Stravník priloží kartu, na veľkých dotykových tlačidlách vyberie deň a jedlá a potvrdí. Kiosky sa s jedálňou spárujú cez QR kód a každé zariadenie má limit požiadaviek.

Administrácia
Menu, firmy, zamestnanci, kredit, kiosky a mesačný report na vyúčtovanie, ktorý predtým znamenal deň počítania. Report sa pripraví na pozadí a príde ako XLSX.
Ako to do seba zapadá
Rozhodnutia, ktoré stoja za zmienku
- Dáta firiem oddeľuje databáza.Každá požiadavka nastaví na svojom spojení aktuálnu firmu cez
SET LOCALa PostgreSQL row-level security (pravidlá prístupu k jednotlivým riadkom) filtruje každý dotaz. ZabudnutýWHEREtak nemôže jednej firme ukázať objednávky inej firmy. - Výdaj funguje aj bez internetu.Kiosk aj terminál zapíšu každú akciu najprv do offline fronty v IndexedDB a keď sa spojenie vráti, odošlú ju znova. Každý záznam nesie svoj
Idempotency-Key, takže opakované odoslanie po timeoute nemôže vydať obed dvakrát. - Menu nikto neprepisuje.Kuchyňa už teraz píše týždenné menu vo Worde. Malá služba v Pythone z toho
.docxvytiahne jedlá, dni a alergény. Ceny sa pri zverejnení menu doplnia z cenníka platného k danému dátumu. - Účty personálu je ťažké ukradnúť.Refresh tokeny sa pri každom použití vymenia a ukladajú sa ako hash. Keď niekto použije starý token, zneplatní sa celý reťazec. Personál si môže zapnúť druhý faktor TOTP (kód z autentifikačnej appky) s obnovovacími kódmi.
- Uzávierka mesiaca beží na pozadí.Report na vyúčtovanie počíta worker v BullMQ a hotový príde ako XLSX s notifikáciou. Požiadavka tak nemusí čakať otvorená, kým sa spočíta celý mesiac obedov.
Kde je projekt dnes
398 commitov od apríla 2026 a 123 testovacích súborov vo Vitest a Playwright. Objednávky, výdaj, kiosk, reporty a prihlásenie s druhým faktorom sú hotové. Teraz pracujem na odolnosti voči výpadkom internetu. Ďalší krok je malý lokálny server (edge node) v každej jedálni, aby sa kiosk a terminál videli, aj keď budova stratí pripojenie.
Z rovnakého backendu čerpá aj FirmFlow, mobilná appka, v ktorej si zamestnanci obed objednajú a vyzdvihnú.