Case study · klientská aplikácia
Cenové ponuky
AGROSPA
Single-page aplikácia na tvorbu cenových ponúk pre slovenský trh. Marže, DPH a zľavy v centoch, IČO autofill z registra a PDF, ktoré obsahuje iba to, čo má zákazník vidieť.
Kontext
Obchodník potrebuje vystaviť ponuku priamo u zákazníka — často na telefóne alebo staršom notebooku. Excel je pomalý a chyby v zaokrúhľovaní sa hľadajú ťažko. Aplikácia preto beží celá v prehliadači, bez backendu, a dáta ukladá cez úložiskovú vrstvu pripravenú na Supabase.
Čo aplikácia rieši
- Ponuka: číslo, dátumy, platnosť, predmet, miesto, zodpovedná osoba a stav.
- Strany: dodávateľ a odberateľ s IČO, DIČ, IČ DPH, výpisom z OR a IBAN.
- Autofill: firma podľa IČO alebo názvu z RPO; pamäť firiem funguje aj offline.
- Kalkulácia: marža, DPH podľa sadzieb a zľava percentom alebo v eurách — všetko v centoch.
- Ukladanie: autosave po 900 ms a história po 3,5 s; export a import JSON.
- PDF: A4 s logom, podpisom, číslovaním strán a iba zákazníckymi údajmi.
- Pre nových ľudí: sprievodca ponukou a onboarding na 10 krokov.
- Mobil: polia 16 px a 44 px, sticky súčet a PDF dole.
Bezpečnostná hranica
Dáta pre zákazníka nie sú „to isté bez pár polí“. Je to samostatná
projekcia customerFacing s runtime guardom.
Testy overujú na reálne vygenerovanom PDF, že interné náklady, marže a zisk sa do dokumentu nedostanú — vrátane diakritiky a viacstranových ponúk.
Architektúra
Jednosmerná závislosť UI → Service → Repository →
úložisko. Komponent nikdy nepristupuje priamo
k localStorage, fetch ani k PDF enginu.
- Doména:
money.tss centovou aritmetikou a čisté funkcie pre marže, DPH a zľavy. - Repository pattern: localStorage a Supabase za jedným rozhraním, výber cez
VITE_STORAGE_DRIVER. - PDF: lazy chunk (~1,25 MB) sa sťahuje až pri prvom exporte, takže nezaťažuje štart.
- Registre: normalizátor pre RPO s heuristikou a testom na reálnej odpovedi API.
Testy
189 testov v 15 súboroch. Okrem kalkulácií a validácie IČO sa testuje reálne PDF s extrakciou textu, kontrast šablón a celý tok od výberu firmy po uloženie do histórie.
Dve tiché pasce @react-pdf/renderer (fixed element
s absolute a lineHeight na dynamickom uzle) strážia testy — bez
nich by obsah z dokumentu zmizol bez chyby v konzole.
Čo je otvorené
- Supabase repository je hotový proti PostgREST, ale bez credentials nie je v CI.
- Bez autentifikácie — pri prechode na Supabase treba prihlásenie a RLS politiky.
- Kvóta localStorage (~5 MB) pri veľkých logách alebo podpisoch.
- DIČ a IČ DPH nie sú vo verejných registroch; rieši to pamäť firiem a voliteľný doplnkový zdroj.