Pavol Rašev
Prijímam nové projekty
Všetky projekty

FirmFlow

White-label appka pre zamestnancov a backend za ňou. Ľudia v nej vidia menu na týždeň, objednajú si obed a pri výdaji ho vyzdvihnú s kartou s čiarovým kódom v mobile. Každá firma má v appke vlastný vizuál a iba moduly, za ktoré platí.

Klient
Fellow Bytes, vlastný produkt
Moja rola
Všetko: mobilná appka, API, administrácia pre firmy
Obdobie
Marec 2026 – dodnes
Stav
Vo vývoji, pripravujem prvé vydanie
Technológie
Expo SDK 57, React Native 0.86, TanStack Query, Symfony 8, API Platform 4, Next.js 16, PostgreSQL, Redis, RabbitMQ
FirmFlow: mobile screen 1
FirmFlow: mobile screen 2
FirmFlow: mobile screen 3

Na čo slúži

FirmFlow vznikol ako správa zamestnancov pre firmy: ľudia, roly, skupiny, notifikácie a audit log. Prvý modul, ktorý zamestnanci používajú každý deň, sú obedy. Appka komunikuje s Canteen, ktorý spravuje menu, objednávky a kredit. FirmFlow rieši, kto je kto.

Mobil nahrádza plastovú kartu do jedálne. Ukáže, čo sa dnes varí, čo máte objednané na týždeň, a čiarový kód, ktorý načítajú pri výdaji, aj v jedálni v suteréne bez signálu.

Domov: dnes, zajtra, kredit a obedy na tento týždeň
Denné menu s pásom kalendára, polievky a hlavné jedlá s alergénmi
Karta zamestnanca s čiarovým kódom Code 128 pre výdaj
Objednávky za tento mesiac so súčtami a stavom vyzdvihnutia

Štyri obrazovky, ktoré zamestnanci naozaj používajú

Expo a React Native s natívnymi záložkami: Liquid Glass na iOS, lišta Material na Androide.

Ako to do seba zapadá

Dva backendy s dvomi úlohami, zámerne oddelené. FirmFlow prihlási zamestnanca a vydá mu krátkodobý token stravníka. S ním appka volá Canteen priamo, takže FirmFlow sa obednej špičky medzi 11:30 a 13:00 vôbec netýka.

Mobilná appkaExpo, React NativeAdmin pre firmyNext.js 16FirmFlow APISymfony 8, API Platformidentita, role, pushCanteen APINestJSmenu, objednávky, kreditPostgreSQL, RedisRabbitMQobjednávky priamotoken stravníka, 15 minpodpísané webhookyzakladanie stravníkov

Rozhodnutia, ktoré stoja za zmienku

  • Funguje aj v jedálni v suteréne.Cache dotazov sa ukladá do SQLite, takže dnešná objednávka sa zobrazí aj bez signálu. Ukladá sa len to, čo je na zozname povolených (allowlist), a číslo karty sa na disk nezapíše nikdy, lebo funguje ako kľúč k pokladni a snapshot sa ukladá ako čistý text.
  • O Face ID rozhoduje systém, nie appka.Refresh token je uložený ešte raz v položke keychainu vytvorenej s requireAuthentication. iOS ani Android ho bez biometrie nevydajú, takže v kóde appky nie je žiadny príznak „overené“, ktorý by sa dal obísť.
  • Token stravníka sa nikdy neukladá na disk.Platí zhruba pätnásť minút, nemá refresh token a drží sa iba v pamäti. Minútu pred vypršaním si ho appka vyžiada nanovo, raz pre všetky prebiehajúce požiadavky.
  • Pravidlá určuje server.Časy uzávierky, ceny a dotácie prichádzajú z API. Lokálna kópia pravidla „dva dni vopred, v časovom pásme jedálne“ sa pri zmene letného času rozíde so serverom a ukáže tlačidlo, ktoré potom zlyhá.
  • Žiadne dvojité obedy.Každá objednávka nesie Idempotency-Key, takže ani opakovaná požiadavka nevytvorí objednávku druhýkrát. Peniaze sa počítajú v celých centoch cez BigInt, nikdy ako desatinné čísla (float).
  • Firmy a oprávnenia rieši backend.Doctrine filter obmedzí každý dotaz na danú firmu. Oprávnenia sú trojice (rola, modul, akcia), kontroluje ich voter a sú v cache v Redise. Appka si lištu so záložkami poskladá podľa toho, čo si firma kúpila a čo rola dovoľuje.
  • Webhooky, ktorým sa dá veriť.Notifikácie z Canteen sú podpísané cez HMAC-SHA256 z časovej značky a tela správy, s vlastným tajným kľúčom pre každú firmu a päťminútovým oknom. Každý Idempotency-Key si systém pamätá 30 dní.

V číslach

  • Mobilná appka: približne 15 600 riadkov TypeScriptu a 189 testov. Test stráži, aby slovenčine, češtine ani angličtine nechýbal žiadny text.
  • Backend: 186 PHP tried, 300 PHPUnit testov v unit, integračných a funkčných sadách, v produkcii tri transporty RabbitMQ.
  • Administrácia pre firmy: Next.js 16, približne 100 testov a CI pri každom pushi.

Na iOS plánujem appku distribuovať ako súkromnú custom app cez Apple Business s kódmi na stiahnutie, keďže zamestnanci používajú vlastné telefóny.