Zpět na domů

Jednotný engine výpočtů pro Next.js a Flutter

Článek o tom, jak autor synchronizoval logiku výpočtů mezi webovou stránkou na Next.js a mobilní aplikací na Flutter. Popsán přístup s použitím JSON specifikací jako jednotného zdroje pravdy, codegenu a paritních testů pro zajištění identických výsledků.

Jak jeden JSON soubor zachránil dva runtime před nesoulady
Advertisement 728x90

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.

Google AdInline article slot

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:

Google AdInline article slot
  • 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.

Google AdInline article slot

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

Advertisement 728x90

Číst dál