Jednotný výpočetní engine pro Next.js a Flutter: jak se vyhnout nesrovnalostem v číslech
Když existuje stejná stavební kalkulačka současně jako mobilní aplikace na Flutter a webová stránka na Next.js, i drobné rozdíly ve vzorcích mohou podkopat důvěru uživatelů. Reálný případ ukázal: pokud aplikace i web vrací různé objemy betonu pod sloup plotu, není to jen bug – je to systémový problém duplikace logiky. Řešení – jednotný zdroj pravdy na základě deklarativních JSON-spek a paritních testů.
Problém dvou nezávislých kódových základů
Původně byla logika výpočtů implementována dvakrát: v Dartu pro Flutter aplikaci a v TypeScriptu pro Next.js web. Oba projekty se vyvíjely paralelně, ale nezávisle. Koeficienty, výchozí hodnoty (např. průměr jámy pod sloup), pravidla zaokrouhlování a balení materiálů žily v kódu každého runtime zvlášť. Výsledek – nesrovnalosti ve výsledcích při stejných vstupních datech.
Taková architektura porušuje princip DRY (Don’t Repeat Yourself) a vytváří technický dluh, který se dříve či později projeví stížnostmi uživatelů. Zvláště to je kritické pro niszové nástroje, kde přesnost výpočtů přímo ovlivňuje důvěru k produktu.
Deklarační přístup: JSON jako zdroj pravdy
Místo duplikování business logiky byly všechny proměnné parametry vyneseny do strukturovaných JSON souborů – jeden na kalkulačku. Každá spec obsahuje:
- Výchozí hodnoty pro vstupní pole (např. průměr piloty – 150 mm)
- Pravidla zaokrouhlování (vždy směrem nahoru)
- Koeficienty ztrát v závislosti na režimu přesnosti
- Informace o balení materiálů (vaky po 25 kg, výdej 0,01 m³/vak)
- Minimální tloušťky vrstev a kroky kotvení
Tyto JSON soubory se staly jediným zdrojem pravdy. Nyní se jakákoli změna parametrů provádí jednou – v JSON – a automaticky se aplikuje v obou runtimích.
Kódová generace pro synchronizaci
Aby bylo zaručeno, že oba projekty používají stejná data, byl zaveden proces kódové generace:
- Při změně JSON-spek se spustí skript
npm run sync:specs - Skript přečte všechny speky a generuje Dart soubor s konstantní mapou (
const Map) - Vygenerovaný soubor se commituje do repozitáře Flutter aplikace
- CI/CD obou systémů kontroluje změny a nasazuje aktualizované verze
Vygenerovaný soubor je označen jako @generated a ruční úprava je zakázána linterem. To vylučuje lidské chyby a zaručuje shodnost dat.
Paritní testy: ochrana před nesrovnalostmi v logice
I při stejných datech mohou nastat rozdíly v chování kvůli specifikům jazyků: Math.ceil() v TypeScriptu a num.ceil() v Dartu se mohou chovat odlišně na hraničních hodnotách. Aby se tomu předešlo, byla zavedena soustava paritních testů:
- Vytvořen soubor fixture – desítky kombinací vstupních dat pro každou z 61 kalkulaček
- TypeScript engine se projede všemi fixturem, výsledky se uloží do referenčního souboru
- Stejný soubor se používá v Flutter repozitáři k porovnání s výsledky Dart enginu
- Jakýkoli rozdíl – i v poslední čárce po desetinné tečce – způsobí pád CI
Za půl roku tyto testy odhalily tři reálné případy nesrovnalostí, které by bez automatické kontroly zůstaly nepovšimnuty.
Tři režimy přesnosti místo „plus 10 %"
Tradiční kalkulačky často používají univerzální koeficient rezervy (např. +10 %). Toto zjednodušení přináší nepřesnosti: dlaždicím je skutečně potřebná rezerva na podřezávání, omítce na kompenzaci nerovností podkladu a lepidlu na savost povrchu.
Místo toho jsou realizovány tři režimy výpočtu:
- Základní – normativní výpočet bez rezerv, pouze podle GOST/SP
- Realistický (výchozí) – zohledňuje typické podmínky opravy v bytě
- Profesionální – maximální rezerva pro složité stavby a záruku proti nedostatku
Koeficienty pro každý režim jsou také uloženy v JSON-spekech, což umožňuje jejich změnu bez překompilování aplikací.
Důležité pravidlo: pro stejné vstupní data musí výsledky splňovat nerovnost: Základní ≤ Realistický ≤ Profesionální. Samostatný CI test kontroluje tuto podmínku pro všechny kalkulačky.
Validátory jako druhá úroveň ochrany
Kromě unit testů a paritních kontrol fungují v CI tři specializované validátory:
- Logický validátor: kontroluje, že množství k nákupu ≥ čistého množství, výsledky se neanulují při platných vstupech, popisky používají standardní jednotky míry („m²“, nikoli „m2“)
- Balicí validátor: ověřuje realistické balení materiálů (lepidlo – v dózách po 5/10/15 l, dlažba – v baleních, ne po kusech)
- Jednotkový validátor: zachytává smíchání metrických systémů (např. sčítání milimetrů s metry bez konverze)
Tyto skripty fungují jako „magnetická brána“ na vstupu do systému – nenahrazují unit testy, ale zabraňují hloupým, ale kritickým chybám na úrovni celé ekosystémy.
Co je důležité
- Jednotný zdroj pravdy v podobě JSON-spek eliminuje duplikaci parametrů mezi runtimy.
- Kódová generace zajišťuje synchronizaci dat bez manuálního zásahu.
- Paritní testy garantují shodnost výsledků v Dartu a TypeScriptu.
- Tři režimy přesnosti nahrazují zjednodušené „+10 %“ a dávají uživateli kontrolu nad úrovní rezervy.
- Specializovaní validátoři v CI chrání před systémovými chybami, které unit testy mohou přehlédnout.
— Editorial Team
Zatím žádné komentáře.