Poctivě postavenou finanční aplikaci poznáme podle pravidel, která platí pro každou změnu: každý údaj má jedno místo, akce uživatele se zapíše buď celá, nebo vůbec, a každá změna projde ověřením úměrným tomu, na co sahá. Kontrolovat mohou i AI agenti, o nálezech ale rozhoduje a za výsledek odpovídá člověk.
Kdo vybírá software pro evidenci dluhopisů, vidí obrazovky, ceník a seznam funkcí. Nevidí ale to podstatné, tedy jestli aplikace po příští aktualizaci spočítá úrok stejně a jestli se platba nemůže zapsat jen napůl. U peněz investorů tohle rozhoduje víc než vzhled obrazovek. V článku projdu zásady, podle kterých vyvíjíme Bondie, a na konci z nich sestavím otázky, které jde položit kterémukoli dodavateli (ptáte se na principy, zdrojový kód k tomu vidět nepotřebujete).
Zásady vývoje software – proč u peněz nestačí „funguje to“
Zásady vývoje software jsou pravidla, která platí pro každou změnu aplikace bez ohledu na to, kdo ji píše a jak moc spěchá. U běžné aplikace se chyba projeví tak, že něco nejde. U finanční evidence je horší chyba ta, která nic nezastaví: výplata proběhne, jen s jinou částkou daně, nebo přehled ukáže jiný stav než detail objednávky. Takovou chybu nikdo hned nevidí a objeví se až u závěrky, při auditu nebo když se ozve investor.
Proto nestačí, že aplikace dnes funguje. Je potřeba mít pravidla, díky kterým bude fungovat stejně i po stovce dalších změn, a kontroly, které chybu zachytí dřív, než se dostane k zákazníkovi. Chyby se ve vývoji vyskytují vždycky a u každého dodavatele. Rozhoduje, jestli je dodavatel hledá pevným postupem, nebo na ně narazí náhodou.
Každá změna u nás jde stejnou cestou (od úkolu v plánu přes testy a kontroly až po verzi, viz schéma). Nález z pozdější kontroly se nevrací jen jako oprava, ale i jako test, který stejnou chybu příště zachytí dřív:
Každý údaj má jedno místo (jeden zdroj pravdy)
Stejný údaj nesmí žít na dvou místech. Kupón na jeden dluhopis proto počítá jedno místo a výplata, přehled i výpis pro investora ho jen přebírají, a sazbu daně počítá jedno pravidlo, které karta klienta jen zobrazí. Přehledy se z dat počítají, místo aby se opisovaly, a totéž platí pro stavy, oprávnění, nastavení i texty pro uživatele.
Logika navíc porovnává identifikátory z číselníků a názvy stavů do výpočtu nevstupují. Když někdo přejmenuje stav „Zaplaceno“ na „Uhrazeno“, výpočet to nesmí poznat. Proč tuhle zásadu považuji za nejdůležitější a jak ji hlídá test, rozebírám v článku Jeden zdroj pravdy.
Akce se zapíše celá, nebo vůbec
Každá akce uživatele (přijetí platby, úpis, výplata) je jedna služba v jedné databázové transakci. Buď se zapíšou všechny její kroky, nebo žádný. Představte si back office, který páruje platbu s objednávkou, a uprostřed zápisu spadne spojení. Bez transakce by platba zůstala spárovaná, ale objednávka nezaplacená a dluhopisy nevydané. S transakcí se nezapíše nic a akce jde zopakovat.
Když dva lidé pracují se stejnou objednávkou naráz, akce si záznamy zamkne, takže si navzájem nepřepíšou data. Zamyká se přitom vždy ve stejném pořadí, aby se dvě akce nezablokovaly navzájem tím, že každá čeká na záznam, který drží ta druhá. Chyba pro uživatele musí říct, co dělat dál (např. doplnit chybějící doklad), a technickou hlášku uživatel nevidí. U akcí s rizikem (např. změna účtu den před výplatou) je potřeba vědomé potvrzení. A v ostrém provozu aplikace odmítne cokoli, co maže data nebo nahrává ukázková data.
Změna databáze má vlastní skript
Každá změna struktury databáze je nový skript (migrace), který jde spustit opakovaně bez škody. Skript, který už někde běžel, se nikdy neupravuje a oprava je další skript. U zákazníka pak aktualizace znamená spustit skripty, které ještě nemá, a nic víc.
Aktualizaci zkoušíme na kopii databáze staré verze s daty: spustíme nové skripty a výsledek porovnáme s čistou instalací téže nové verze. Rozdíl bereme jako chybu aktualizace a opravujeme ho dalším skriptem.
Ověřování úměrné změně
Oprava textu na jedné obrazovce nepotřebuje stejné ověření jako změna výplat. Kdybychom u každé drobnosti pouštěli všechno, kontroly by trvaly hodiny a dřív nebo později by je někdo začal obcházet. Proto máme úrovně:
- po každé změně logiky testy dotčené oblasti s výsledkem do minuty,
- před každým commitem celá sada testů,
- na konci vlny práce (několik úkolů za sebou) stabilizace celku (průchod obrazovek pod všemi rolemi, přístupnost, bezpečnostní kontroly kódu, obnova ukázkových dat),
- po milníku průzkum celé aplikace z pohledu, který funkce nepsal.
Rozdíl je dobře vidět na dvou hypotetických změnách. Oprava překlepu v nápovědě projde po změně testy dokumentace během minuty a před commitem celou sadou, víc nepotřebuje. Změna zaokrouhlení srážkové daně spustí testy výplat i daně, ověření proti referenčním případům, a protože sahá na peníze, i kontrolu AI agentem v roli účetního a nezávislý přepočet. Obě změny přitom jdou stejnou cestou, liší se jen tím, kolik kontrol na ní potkají.
Výpočty úroků a daně mají navíc nezávislé ověření proti referenčním případům, tedy hodnotám, které nevznikly v aplikaci. Jak to celé běží a jak často, popisuji v článku Testování finančních výpočtů. Souhrnná čísla (počet testů, pokrytí kódu testy, počet kontrol) ukazuje stránka Vývoj v číslech.
Kontroluje někdo jiný než autor
Testy, které píše autor kódu, ověří, že kód dělá to, co si autor myslel. Neověří, co si nemyslel. Proto dokončenou funkci kontrolují AI agenti v rolích, které ji nepsaly, vybraných podle toho, na co změna sahá: účetní, právník, uživatel, útočník, revizor kódu a UX designér. Každý agent dostane jen vstupy své role (právník např. texty pro uživatele, kód nevidí) a každý nález dostane body podle pevné tabulky.
Body z tabulky připraví návrh pořadí, nález ale testem ověřuje a rozhoduje o něm člověk. Agent nesmí bez člověka změnit chování pro uživatele, práva, peníze ani nic nevratného. Podle mého názoru je to jediné rozumné rozdělení: agent toho projde víc, než by stihl jeden kontrolor, ale za výsledek neručí. Podrobně to popisuji v článku Oponentura v rolích.
Chyba se opravuje u příčiny i na podobných místech
Když se chyba najde, nejdřív vznikne test, který ji zopakuje. Pak hledáme příčinu ve zdroji (ve službě nebo v databázi). Oprava na obrazovce by totiž jen schovala příznak, a stejný výpočet ve vedlejším přehledu nebo v exportu by zůstal špatně.
Po opravě proto projdeme podobná místa: stejný výpočet v jiném přehledu, stejný stav v jiné akci, stejný text v nápovědě. Opravujeme jednou u zdroje a zapíšeme, proč chybu dosavadní kontroly nechytily. Bez nové kontroly by se stejná chyba mohla vrátit.
Změna chování jen vědomě a s cestou zpět
Když vývoj mění rozhraní, přehledy, nastavení nebo role, porovná je test s uloženým snímkem (kontraktem). Změna, která snímek posune, musí být vědomá a vysvětlená, a přestavba kódu beze změny chování ho posunout nesmí. Nová funkce dosavadní chování zachová: výchozí hodnota nového nastavení odpovídá dnešnímu chování, takže zákazník po aktualizaci pracuje stejně jako včera. Každá změna chování má vlastní commit, aby šla vrátit samostatně.
Funkce má místo dřív než kód
Než začneme psát kód, má funkce záznam v katalogu, patří do modulu a má úkol v plánu. Moduly jdou vypnout a celá sada testů běží i s každým volitelným modulem vypnutým zvlášť. Úkol má jednu hlavní funkci a každý commit se změnou aplikace nese úkol, funkci a vztah k verzi. Jak držíme nápady, úkoly, nálezy a otázky v jednom seznamu, popisuji v článku Řízení backlogu vývoje.
Stejné pravidlo platí pro texty. Průvodce, nápověda a vysvětlivky „Proč?“ čerpají z jednoho zdroje textů a právní citace jsou ověřené proti platnému znění s datem (viz snímek níže):

Na snímku je oddíl Právní rámec z průvodce ukázkové aplikace. U každého předpisu vidíme datum znění, proti kterému jsme citace kontrolovali, a jednu větu, čeho se v aplikaci týká. Když vyjde novela, je hned vidět, které citace je potřeba projít znovu.
Verze, zálohy a aktualizace u zákazníka
Aplikace běží na serveru zákazníka (on-premise). Data zůstávají u emitenta, ale provoz musí být promyšlený už v prvních verzích: číslo verze a seznam změn srozumitelný pro uživatele, záloha s vyzkoušenou obnovou a aktualizace jen na vyšší vydanou verzi s ověřením, že balíček po cestě nikdo nezměnil.
Zálohu je potřeba zkoušet obnovou. Zálohu, ze které nikdo nikdy neobnovoval, nepovažuji za zálohu. Stejně tak aktualizace: když ji zákazník spouští sám u sebe, musí jít opakovat a musí jít poznat, na jaké verzi právě je. Skripty databáze se zpět nevracejí, takže cesta na předchozí verzi vede přes zálohu pořízenou těsně před aktualizací a předchozí balíček aplikace.
Úskalí: zásada, kterou nehlídá test
Zásady sepsat je snadné. Horší je, že zásada, kterou hlídá jen paměť vývojáře, dřív nebo později povolí (typicky ve spěchu před termínem nebo u „jen malé opravy“). Proto u každé zásady hledáme kontrolu, která ji vynutí: test shody, kontrolu při ukládání commitu, uložený snímek rozhraní, nebo aspoň bod v revizi kódu.
Druhé úskalí je opačné. Každá nová kontrola stojí čas a každé nové pravidlo komplikuje práci. Proto zásad nemá být co nejvíc, ale jen tolik, kolik jich jde uhlídat. Kontrola, kterou nikdo nespouští, je horší než žádná, protože vytváří dojem jistoty.
Otázky, které položit dodavateli finanční aplikace
Tyhle otázky se hodí na jakýkoli software, který počítá peníze, a dodavatel by na ně měl odpovědět i ukázkou:
- Kde žije každý údaj a co se stane, když ho změníte na jednom místě?
- Může se platba nebo výplata zapsat jen napůl?
- Jak ověřujete výpočet úroků a daně jinak než testy autora kódu?
- Co uděláte, když najdete chybu, a jak zjistíte, jestli stejná chyba není jinde?
- Jak vypadá aktualizace u nás a jak se vrátíme na předchozí verzi, když se nepovede?
- Kdy jste naposledy obnovovali ze zálohy?
- Kdo kontroluje změnu, kterou programátor napsal, a kdo o nálezech rozhoduje?
Dobrý dodavatel odpoví konkrétně a ukáže, kde to hlídá test. Odpověď „máme zkušené programátory“ nestačí.
Závěr
Poctivě postavenou finanční aplikaci poznáme podle pravidel, která platí pro každou změnu, a podle kontrol, které je vynucují. Jeden údaj má jedno místo, akce se zapíše celá, nebo vůbec, a výpočty peněz ověřuje i jiná cesta než testy autora. Kontrolovat mohou AI agenti, o nálezech ale rozhoduje a za výsledek odpovídá člověk. Do hloubky jdou články Jeden zdroj pravdy, Testování finančních výpočtů, Oponentura v rolích a Řízení backlogu vývoje.
Související články
- Modulární aplikace: jak vypnout modul a nepřijít o data
Malý emitent nepotřebuje provize ani párování výpisů, velký bez nich nevydrží. Jak rozdělit aplikaci na moduly, aby vypnutí nesmazalo data ani pravidla?
IT a vývoj · Technici · 15. 10. 2026 - Funkční mapa aplikace: funkce, pravidlo a test
Programátor opraví výpočet daně a za týden nesedí výpis pro investora. Jak katalog funkcí s pravidly a testy předem ukáže, čeho se změna týká.
IT a vývoj · Technici · 12. 10. 2026 - Testování finančních výpočtů: úroky, AÚV a daň
Programátor přečte pravidlo špatně a test napíše stejně špatně, takže oba projdou. Jak ověřit, že aplikace počítá úrok, AÚV a daň opravdu podle podmínek?
IT a vývoj · Technici · 10. 10. 2026