Jeden zdroj pravdy: každý údaj na jednom místě

Jan Zedníček · · Technici

Jeden zdroj pravdy znamená, že každý údaj, stav, pravidlo, nastavení a text má v aplikaci právě jedno místo. Ostatní obrazovky a výstupy ho čtou nebo z něj počítají, nikdy si ho neopisují. Kde to nejde zajistit samotným návrhem aplikace, hlídá shodu test.

Jeden zdroj pravdy (anglicky single source of truth) je zásada návrhu aplikace, podle které má každý údaj, pravidlo i text právě jedno místo. Ostatní obrazovky ho jen čtou nebo z něj počítají, takže dva přehledy nemohou ukázat dvě různá čísla. Ve finanční evidenci se porušení pozná nejhůř, protože obě obrazovky vypadají věrohodně (např. karta investora ukáže sazbu daně 15 % a výplata srazí 35 %). V článku se podíváme na to, jak duplicita vzniká a jak ji hlídat testem i revizí kódu.

Jeden zdroj pravdy – co všechno potřebuje jedno místo

Jeden zdroj pravdy se obvykle vysvětluje na datech: zákazník má jednu adresu a ta je uložená jen jednou. U aplikace s penězi je to širší. Jedno místo musí mít:

  • údaj, např. datum zaplacení patří k objednávce, ne napůl k objednávce a napůl do historie,
  • pravidlo (sazba daně, výpočet AÚV, kdo dostane výplatu k rozhodnému dni),
  • stav a číselník, kde logika porovnává identifikátor stavu, ne jeho název,
  • oprávnění a nastavení, tedy jeden seznam, ze kterého čte aplikace i dokumentace,
  • text pro uživatele (průvodce, nápověda a vysvětlivky z jednoho zdroje textů).

Všechno ostatní se z tohoto místa odvozuje, nebo se shoda hlídá testem. Je to první ze zásad, které shrnuje článek Zásady vývoje software.

Jak duplicita vzniká

Duplicitu, tedy stejný údaj nebo pravidlo na dvou místech, málokdo udělá úmyslně. V praxi obvykle vzniká jednou ze tří cest:

  1. Rychlá oprava. Obrazovka potřebuje údaj, který rozhraní zrovna nevrací, a tak si ho programátor dopočítá přímo na obrazovce. Dnes vyjde stejně.
  2. Druhá obrazovka. Nový přehled potřebuje stejné číslo jako detail, ale počítá ho vlastním dotazem s malou odchylkou (třeba bez stornovaných objednávek).
  3. Zjednodušení. Pravidlo má výjimky a na druhém místě se napíše jen jeho hlavní větev.

Ve všech třech případech vychází kopie v den vzniku stejně jako zdroj, aspoň u případů, které autor zkouší: druhá obrazovka sedí, dokud žádná objednávka není stornovaná, zjednodušené pravidlo sedí, dokud nepřijde výjimka. Testy autora proto rozdíl nezachytí. Problém přijde až s prvním případem mimo zkoušené nebo se změnou pravidla, kterou někdo udělá jen v jedné kopii.

Příklad: sazba srážkové daně na dvou místech

Vezměme hypotetický příklad se srážkovou daní. Výpočet výplaty má pro fyzické osoby pravidlo podle státu rezidence: českému rezidentovi a rezidentovi státu EU nebo EHP, případně státu se smlouvou o zamezení dvojímu zdanění nebo s dohodou o výměně informací, se srazí 15 %, ostatním 35 % (stav k 10. 10. 2026) [1]. Kdyby si karta klienta sazbu počítala zvlášť a zjednodušeně („fyzická osoba 15 %“), pro investora ze státu bez smlouvy i bez výměny informací by karta ukazovala 15 % a výplata by srazila 35 %. Žádná z obrazovek nespadne, jen si odporují. A při příští novele zákona se změní jedna z nich.

Pravidlo opsané na dvě místa Sazba daně kopie ve výplatě Sazba daně kopie na kartě klienta výplata srazí A karta ukáže B po změně jedné kopie si obrazovky odporují Jedno pravidlo, ostatní ho čtou Pravidlo sazby jediné místo výpočtu výplata karta klienta přehledy Test hlídá shodu karta = výpočet výplaty pro každý druh investora obrazovka hodnotu jen zobrazí, nepočítá ji znovu
Vlevo dvě kopie pravidla, které se časem rozejdou. Vpravo jedno pravidlo, obrazovky ho jen zobrazují a test hlídá shodu.

Oprava čísla na kartě by nepomohla. Karta nemá mít vlastní pravidlo vůbec. Sazbu a její zdroj (stát investora, doložené potvrzení o daňovém domicilu, výchozí sazba) jí vrátí rozhraní ze stejného pravidla, jaké používá výpočet výplaty. Obrazovka hodnotu jen zobrazí a připíše, odkud pochází.

Stejně to platí pro přehledy. Přehled se počítá z dat, neopisuje se. V Bondie jsou přehledy pohledy v databázi a rozhraní je jen čte, takže seznam objednávek, detail i export ukazují stejné číslo z jednoho výpočtu.

Kde má žít údaj, který chybí

Občas zjistíme, že nějaký údaj v datech chybí (např. kdy přesně se objednávka posunula do dalšího stavu). Lákavé je vyčíst ho z historie změn. Jenže pak má půlka údajů o průběhu objednávky jeden zdroj a půlka jiný.

Je potřeba doplnit údaj tam, kde žijí jeho sourodé údaje: nový sloupec u objednávky, zápis ve službě, která stav mění, vymazání při vrácení akce a skript, který doplní stará data. Historie změn přitom zůstává jediným místem pro otázku, kdo a kdy co změnil. Zapisuje se automaticky při každé změně v databázi a ostatní obrazovky z ní jen čtou.

Jak jeden zdroj pravdy hlídat testem

Zásadu, kterou nikdo nekontroluje, dřív nebo později někdo poruší, i když ji zná. Proto ji opíráme o kontroly:

  • Test shody. U pravidla, které se zobrazuje na víc místech, test porovná výsledek obrazovky s výpočtem pro každý druh případu (u sazby daně rezident fyzická osoba, právnická osoba, nerezident bez uvedeného státu, s potvrzením a s propadlým potvrzením). Propadlé potvrzení sazbu samo nemění, důkazní břemeno ale nese emitent jako plátce a bez doložení mu hrozí doměření až do 35 %, proto ho obrazovka i výplata musí hlásit stejně. Když se pravidlo změní jen na jednom místě, test spadne.
  • Test na texty místo identifikátorů. U vybraných číselníků kontrola projde kód a hledá porovnání se slovním názvem stavu; ostatní místa hlídá revize kódu.
  • Seznam proti dokumentaci. Každé nastavení v registru aplikace musí mít řádek v dokumentaci nastavení a obráceně.
  • Snímek rozhraní a přehledů. Test porovná sloupce přehledů a cesty rozhraní s uloženým seznamem, takže změnu, o které nikdo nerozhodl, ohlásí.
  • Invarianty nad daty. Např. výplata se rovná úroku plus jistině minus dani. Kdyby dva výpočty daně šly různými cestami, invariant to často ukáže dřív než uživatel.

Testy doplňuje revize kódu, kterou dělá AI agent v roli revizora, který změnu nepsal. Pravidlo spočítané podruhé je jedna z věcí, které revizor hledá nejdřív, protože testy autora ji neodhalí (autor svou kopii považuje za správnou). O opravě, kterou revizor navrhne, rozhoduje člověk. Jak revize a další role fungují, popisuji v článku Oponentura v rolích.

Když se duplicita najde, postup je pevný: test, který rozdíl zopakuje, oprava u zdroje a kontrola podobných míst, jestli není stejné pravidlo opsané ještě jinde.

Kdy výsledek uložit: výkon a hodnoty k datu

Jeden zdroj nicméně neznamená, že se všechno musí počítat pokaždé znovu. Dvě výjimky jsou v pořádku, pokud se vědomě pojmenují.

Předpočítaná hodnota kvůli výkonu je odvozený údaj a druhým zdrojem se nestává. Musí mít jasné místo, kde vzniká, a test, že se shoduje s výpočtem.

Hodnota uložená k události je fakt, který se k pravidlu už nevrací. Sazba, kterou výplata skutečně srazila, patří k výplatě i poté, co se zákon změní. Tady by naopak chybou bylo dopočítávat ji znovu podle dnešního pravidla.

Závěr

Údaj, pravidlo, stav, nastavení i text mají v aplikaci jedno místo a obrazovka hodnotu jen zobrazí i se zdrojem, místo aby ji počítala po svém. Nejzrádnější je duplicita z rychlé opravy a z druhé obrazovky, protože v den vzniku vychází stejně jako zdroj, a proto ji hlídají testy shody a revize kódu, kterou dělá AI agent, který změnu nepsal. Výjimkou je hodnota uložená k události, např. sazba, kterou výplata skutečně srazila: ta se k pravidlu už nevrací a znovu se nepočítá. Jak se ověřuje samotný výpočet daně a úroků, popisuje článek Testování finančních výpočtů.

Reference

  1. Zákon č. 586/1992 Sb., o daních z příjmů, § 36 [on-line]. [cit. 2026-10-10]. Dostupné z WWW: https://www.zakonyprolidi.cz/cs/1992-586

Související články