Proč stavíme ModularPlatform jako stabilní základ, ne jako PoC
Většina produktů začíná jako proof of concept, který se pak roky dohání. My stavíme modulární základ navržený od začátku na spolehlivost, rozšiřitelnost a bez vendor lock-inu. Co to konkrétně znamená a proč to klientovi šetří čas a peníze.
Většina produktů, na kterých jsem v životě dělal, začala jako proof of concept. Někdo potřeboval rychle ukázat, že nápad funguje, tak vznikla malá appka, která to udělala. A pak se nevyhodila. Pustila se do produkce, přibyl první zákazník, druhý, a najednou se ten PoC roky dohání. Technický dluh, výpadky, vendor lock-in, který nikdo nepodepsal vědomě.
Tohle vzniklo z toho, co jsem viděl selhávat. ModularPlatform stavíme opačně: nejdřív čistý, produkce-ready základ, pak na něj funkcionalita. Je to interní projekt SolutionBoxu a je stále v průběhu — píšu „stavíme", ne „máme hotové". Ale chci popsat, proč to děláme takhle, protože ten důvod je ze zkušenosti, ne z marketingu.
Co se mi opakovaně rozbíjelo pod rukama
Začnu příběhem, protože ten dává zbytek smysl.
V TrafinOilu jsem dělal e-fakturaci na KSeF — polský státní systém pro elektronické faktury. Je asynchronní, rate-limited, občas nedostupný a má vlastní stav. Když ho integrujete naivně, vznikne fire-and-forget pipeline: pošlu fakturu, doufám, že dorazila, a jedu dál. To přesně tam předtím bylo. Forenzně jsme pak obnovovali 15 141 dokumentů, které ta tichá pipeline ztratila. Nikdo o tom nevěděl, protože nic nehlásilo chybu — prostě se to nikam neuložilo.
Přepsal jsem to na dlouhoběžící stavový workflow: idempotentní submit, retry s exponenciálním backoffem, rate limiting, reconciliation, UPO potvrzení, audit log. Dnes je to ověřené v produkci na víc než 40 000 dokumentech, 100 % doručeno. Rozdíl mezi těmi dvěma verzemi není v tom, že druhá je „lépe napsaná". Rozdíl je v tom, že durabilita, idempotence a observabilita tam byly od začátku, ne dolepené po incidentu.
Stejnou věc jsem viděl jinde z jiného úhlu. Atlas Copco mělo SAP datovou pipeline, kde jeden SQL skript narostl na 15 000 řádků a runtime se protáhl na několik dnů. Refactor na event-driven přístup na Azure Functions to zkrátil na ~4 hodiny z EU a stáhl ten SQL na 3 000 řádků, tedy o 80 % méně. Zase: bottleneck nebyl v jazyce ani frameworku, ale v tom, že se základ stavěl ad hoc a nikdo ho nenavrhl na to, co přijde.
To je pointa, kterou ModularPlatform řeší. Když firma začíná každý produkt od nuly, opakovaně staví tutéž infrastrukturu: multitenancy, platby, messaging, observabilitu. A pokaždé ji staví ve spěchu, protože zákazník chce vidět feature, ne outbox pattern. Takže pokaždé vznikne ten stejný křehký start.
Co konkrétně znamená „stabilní základ"
Stabilní základ není adjektivum, je to seznam rozhodnutí, která se dělají dřív, než se napíše první business feature. Tady je, co do ModularPlatform stavíme a proč.
Čisté závislosti, vynucené mechanicky. Modulární monolit má smysl jen tehdy, když moduly opravdu nesahají jeden druhému do střev. Většina „modulárních" kódů to slíbí v dokumentaci a pak to nikdo nehlídá — za půl roku je z toho propletenec. My to vynucujeme ArchUnitNET testy: když někdo zavede zakázanou závislost mezi moduly, spadne build, ne až produkce za rok. Hranice, kterou hlídá test, vydrží. Hranice, kterou hlídá dobrá vůle, ne.
Durable messaging od začátku. Komunikace mezi moduly i s vnějškem jede přes Wolverine — outbox, inbox, sagy. To je přesně ta mašinérie, kterou jsem v KSeF musel dostavovat ručně po incidentu. Když ji máte od prvního dne, žádná zpráva se tiše neztratí mezi „uložil jsem do DB" a „poslal jsem dál". Tyhle dvě operace buď proběhnou obě, nebo žádná.
Multitenancy a izolace dat. Tenant izolace přes Postgres row-level security. To znamená, že oddělení dat zákazníků nehlídá aplikační kód, který může mít bug, ale databáze sama. Když se programátor splete a zapomene ve dotazu na filtr podle tenanta, RLS ho i tak nepustí k cizím datům. Tohle je přesně typ věci, který se v PoC odkládá na „později to vyřešíme" a později se z toho stane bezpečnostní incident.
Security a GDPR by default. Crypto-shred mazání pro GDPR — když má zákazník právo být zapomenut, smažeme klíč a data se stanou nečitelná, místo abychom honili kopie po backupech. Audit log a izolace jdou s tím ruku v ruce. Tohle se nedá věrohodně dolepit; buď to v základu je, nebo není.
Platby. Stripe integrace v základu, protože placený produkt potřebuje účtovat a většina týmů to objevuje až ve chvíli, kdy už má zákazníka a žádný billing.
Self-healing a běh přes víc strojů. Základ je navržený tak, aby běžel multi-machine a aby se po výpadku jednoho uzlu zotavil sám, ne aby ho někdo o třetí ráno restartoval ručně.
Observability od začátku, ne po prvním výpadku. Strukturované eventy na přechodech stavů, ať je vidět, co se kde děje. Tohle je lekce z KSeF napsaná do základu: tichý LogWarning bez alertu je dluh, ne monitoring. Pipeline, která ztratila 15 141 dokumentů, je drahá hlavně proto, že to nikdo neviděl včas.
Frontend jede na Next.js 15 a React 19, backend je .NET modulární monolit. Monolit schválně — pro read-heavy aplikace je čistý modulární monolit s vynucenými hranicemi obvykle rozumnější než mikroservisy, které přidají provozní složitost, kterou většina produktů nepotřebuje.
Proč to šetří čas a peníze klientovi
Tohle není akademické cvičení v čistotě kódu. Má to tři konkrétní důsledky pro toho, kdo si nás najme.
Rychlejší time-to-market. Nový produkt nezačíná stavbou multitenancy, plateb, messagingu a observability. To už existuje a je odzkoušené. Začíná se rovnou tím, co je na produktu unikátní. To je týdny až měsíce, které se nemusí utratit za infrastrukturu, kterou stejně potřebuje každý.
Žádný vendor lock-in. Zdrojový kód zůstává klientovi. ModularPlatform není SaaS, do kterého se klient zamkne a platí navždy. Je to základ, na kterém se postaví jeho produkt, a ten produkt je jeho. Pokud se rozhodne pokračovat sám nebo s jiným týmem, má v ruce normální .NET kód, ne černou skříňku.
Nižší cena dohánění. Tohle je ta nejméně vidět položka a nejdražší. Když produkt vyletí z PoC do produkce bez základů, neplatí se za to hned. Platí se za to za rok, v podobě výpadků, datových ztrát, bezpečnostních incidentů a refactorů, které jdou napříč celou aplikací. Já jsem ten účet platil v cizích projektech dost často na to, abych ho chtěl klientům ušetřit.
Nechci to přehánět. ModularPlatform je interní a in progress — pořád na něm pracujeme a některé části jsou dál než jiné. Není to hotový produkt s klikacím demem. Ale filozofie za ním je odzkoušená v reálných projektech, kde jsem viděl, co se stane, když chybí: ztracené dokumenty, několikadenní runtime, security odložená na „později".
Většina týmů vypustí PoC bez základů a rok ho dohání. My jdeme opačně. Nejdřív základ, na kterém se dá stavět, pak to ostatní. Ne proto, že je to elegantnější, ale protože jsem viděl dost krát, kolik stojí ten druhý přístup.