Reference

Vít HofmanOsobní značka20264 měsíce

Objednávka projde od košíku přes účetnictví až po spárovanou platbu, aniž by se jí kdokoliv dotkl

Můj vlastní web. Bezpečnost práce a požární ochrana jako živnost, ale postavená jako systém: e-shop, zákonná školení s certifikátem, evidenční moduly pro firmy a k tomu tři tisíce šest set stránek obsahu, ze kterého chodí poptávky.

RozsahWeb na míruE-shopAplikace na míruSpráva a rozvojSEO a obsah
  • 20

    kroků objednávky bez ručního zásahu

    Od udělení přístupu přes provize a licence až po fakturu a e-mail

    src/lib/order-completion.ts

  • 3

    systémy, které si povídají samy

    Platební brána, účetní systém a bankovní výpisy, bez přepisování mezi nimi

    Integrace ThePay, iDoklad a Fio banka

  • 3 625

    adres na jednom webu

    Články, videa, produkty, karty rizik, předpisy a stránky služeb

    Produkční sitemap.xml, 31. 7. 2026

  • 655

    lekcí v osmi kurzech

    S kvízy, checklisty a certifikátem na konci

    Rozcestník kurzů na produkci, 31. 7. 2026

  • 119 + 825

    blogových článků a videí

    Obsah, ze kterého chodí poptávky

    Produkční sitemap.xml, 31. 7. 2026

  • 303

    tabulek v jedné databázi

    E-shop, e-learning, blog, inzerce, rizika, dokumenty, úrazy

    prisma/schema.prisma, 159 migrací

Přehled funkcí
  • E-shop s okamžitým dodáním
  • Peníze projdou od košíku po zaúčtovanou fakturu samy
  • Zákonná školení s certifikátem, ne video ke stažení
  • Firemní účty se školicí maticí
  • Jeden účet pro všechny moje aplikace
  • Administrace, která nahradila tabulky
  • Obsah jako zdroj poptávek
  • Párování plateb, které počítá s realitou
  • Objednávka se neuzavře, dokud nedoběhne všech dvacet kroků
  • Platební brána, které se nevěří na slovo
  • Certifikát, který si kdokoliv ověří bez přihlášení
  • Fakturační údaje se vyplňují jednou pro všechno
  • Jedna aplikace obsluhuje tři domény
  • Statistiky se počítají z účetních dat, ne z měřicího skriptu
  • Provoz se hlídá sám
  • Databáze rizik zdarma jako vstupní brána
  • Sedm samostatných produktů s předplatným
  • Inzertní portál pro obor
  • Zákazník si postaví vlastní kurz

Celý přehled funkcí

Tohle není zakázka. Je to můj vlastní web a zároveň moje pracovní laboratoř. Patnáct let chodím po provozech jako bezpečnostní technik a tu agendu znám zevnitř: dokumentace, školení, hodnocení rizik, evidence úrazů. Věci, které firmy dělají v Excelu a v šanonech, protože jim nikdo nepostavil nástroj.

Původní weby běžely na WordPressu, e-shop na jeho nákupní nadstavbě. V dnešní databázi po tom zůstaly stopy, sloupce s původními identifikátory. Roky to stačilo, pak přestalo. Web byl pomalý, administrace nepříjemná na ovládání a s každým dalším doplňkem přibyla věc, kterou jsem musel hlídat a aktualizovat, aniž bych viděl dovnitř.

Pak mi jedním z těch doplňků e-shop napadli a udělali nepořádek v objednávkách. Data jsem nakonec narovnal, ale stálo to spoustu hodin, které nikdo nezaplatil, a po celou dobu jsem nemohl zákazníkům s jistotou říct, co se s jejich objednávkou stalo. Tohle je zkušenost, kvůli které dnes nestavím na cizích zásuvných modulech. Každý z nich je cesta dovnitř, kterou neovládám a za kterou nemůžu ručit.

K tomu provoz. Každá objednávka znamenala ruční vystavení faktury, ruční kontrolu výpisu z banky a ruční odeslání souborů. Školení se prodávalo jako soubor ke stažení, takže zákazník neměl doklad o proškolení, který by obstál před kontrolou.

Rozhodl jsem se to postavit znovu a od základu. Ne jako web s doplňky, ale jako jednu aplikaci nad jednou databází, kde vím o každém řádku kódu, proč tam je.

První rozhodnutí bylo nedělit to na tři nakoupené služby. Obvyklá cesta je web na jednom řešení, e-shop na druhém a e-learning jako pronajatá služba placená za uživatele. Tři účty, tři měsíční platby a zákazník existující třikrát, pokaždé trochu jinak. Chtěl jsem, aby objednávka, kurz a faktura mluvily o téže osobě.

Druhé rozhodnutí bylo, že peníze nesmí procházet rukama. Ne kvůli pohodlí, ale kvůli chybovosti. Ruční přepis částky a variabilního symbolu je místo, kde vzniká rozdíl mezi tím, co je v e-shopu, a tím, co je v účetnictví. Číslo objednávky proto vzniká jako čistě numerické a slouží rovnou jako variabilní symbol.

Třetí rozhodnutí se týkalo obsahu. Bezpečnost práce je obor, kde lidé hledají odpověď na konkrétní otázku, ne dodavatele. Encyklopedie rizik je proto zdarma, bez registrace a v plném rozsahu. Placený registr rizik z ní pak staví to samé pro konkrétní firmu, takže obsah zdarma a produkt sdílejí jedna data a neudržují se dvakrát.

Čtvrté rozhodnutí bylo o důvěře v cizí systémy. Platební bráně se nevěří na slovo, účetnímu systému se nedovolí zablokovat zákazníka a bankovní výpis se považuje za nespolehlivý zdroj, který může dorazit pozdě, dvakrát, nebo v částech.

Web běží na Next.js, obsah i obchodní data jsou v PostgreSQL a stránky se skládají na serveru. Jedna aplikace přitom obsluhuje tři domény: podle adresy se přepne režim a pustí se jen odpovídající část.

Přihlášení nepatří téhle aplikaci. Postavil jsem k němu samostatný server, který funguje jako jediná identita pro všechno, co provozuji: web, e-learning, evidenci úrazů i odborné fórum. Bezpečák je vůči němu jen klient, který se přihlašuje přes OAuth2 a OpenID Connect s PKCE. Session cookie je sdílená napříč doménami a platnost přihlášení se ověřuje proti databázi každých patnáct vteřin, takže odhlášení nebo změna hesla platí všude okamžitě. Zákazník tak má jeden účet a jedny fakturační údaje, i když nakupuje ve třech různých aplikacích.

Peněžní okruh. Platba kartou přes bránu vystaví ostrou fakturu v účetním systému. Platba převodem vystaví nejdřív zálohovou fakturu a po připsání peněz ji na ostrou konvertuje. Bankovní výpis se stahuje každých patnáct minut a páruje podle variabilního symbolu s tolerancí jednoho haléře, protože zaokrouhlení daně je legitimní rozdíl, zatímco tolerance jedné koruny už je náplast. Dvě částečné platby se sečtou, nedoplatek se eviduje a zákazník o něm ví.

Dokončení objednávky je fronta dvaceti kroků, každý s vlastním identifikátorem a pěti pokusy. Opakovací úloha běží každých pět minut. Objednávka se uzavře jen tehdy, když prošla faktura i všechny kritické kroky, takže stav dokončeno vždycky něco znamená.

Školení nejsou videa ke stažení. Průchod hlídá pořadí lekcí, minimální čas nad lekcí, povinné checklisty a složené kvízy. Otázky se v okamžiku pokusu zmrazí i s otiskem, takže je zpětně vidět, na co student odpovídal. Certifikát nese otisk SHA-256 a QR kód, přes který si pravost ověří kdokoliv bez přihlášení.

Provoz běží v Dockeru za Caddy, ven nevede žádný port. Nasazení má tři úrovně podle rizika, od kompletního s povinnou zálohou po rychlé za třicet vteřin. Skript odmítne poslat na produkci necommitnutý strom. Záloha databáze se ověřuje čtením zpátky a existuje skript na cvičnou obnovu.

Web dnes obsluhuje tři tisíce šest set dvacet pět adres v padesáti sekcích: sto devatenáct článků, osm set dvacet pět videí, sedm set devadesát jedna karet rizik, sto devadesát osm produktů, sto dvacet sedm stránek k předpisům a devadesát stránek služeb. Osm kurzů má dohromady šest set padesát pět lekcí.

Ruční kroky mezi e-shopem, účetnictvím a bankou: žádné. Faktura vzniká sama, platba se páruje sama, zákazník dostane soubor nebo přístup do kurzu okamžitě. Pod tím běží třicet osm automatických úloh a administrace o devadesáti osmi obrazovkách.

Proti běžné konkurenci v oboru je rozdíl hlavně v tom, co se neplatí a co se nepřepisuje. Obvyklá sestava je prezentace na hotovém řešení, e-shop jako nadstavba a e-learning pronajatý za uživatele a měsíc. Tady je to jedna aplikace: nejsou tu poplatky za studenta, nejsou tu tři administrace a zákazník existuje jednou. Zákonná školení navíc většina webů v oboru vůbec neprodává, protože samotný soubor ke stažení neobstojí jako doklad o proškolení. A není tu žádný cizí doplněk, který by někdo musel hlídat a přes který by se dalo dostat dovnitř.

V čem je web opravdu silný: v propojení obsahu s prodejem. Encyklopedie rizik a videa přivádějí lidi na konkrétní otázku, článek je propojený s produktem, který ji řeší, a nákup končí přístupem, ne příslibem. To je věc, kterou nakoupená sestava nástrojů neumí, protože každý z nich vidí jen svůj kousek.

Co se právě dělá: optimalizace rychlosti úvodní stránky a vlastní měření návštěvnosti bez cizích skriptů. Obchodní statistiky se už dnes počítají serverově přímo z účetních tabulek, takže odpovídají tomu, co je na faktuře.

Jádro zadání

7 funkcí

Co klient chtěl a bez čeho by web nefungoval

  • E-shop s okamžitým dodáním

    Sto devadesát osm produktů v katalogu: směrnice, pověření, formuláře, desetiminutovky, požární dokumentace. Zákazník platí kartou a soubor má hned, bez čekání na člověka.

    Technická poznámka

    Odkaz ke stažení má platnost rok, počítá stažení a vede log s IP adresou. Velké soubory se nikdy nepřenášejí přes aplikaci: server vrátí přesměrování na podepsanou adresu úložiště s platností pět minut.

  • Peníze projdou od košíku po zaúčtovanou fakturu samy

    Platba kartou vystaví ostrou fakturu. Platba převodem vystaví nejdřív zálohovou, a po připsání peněz se konvertuje na ostrou. Bankovní výpis se stahuje sám a páruje podle variabilního symbolu.

    Technická poznámka

    Číslo objednávky je záměrně čistě numerické (datum a pořadí), takže slouží přímo jako variabilní symbol. Tím odpadá překladová tabulka mezi e-shopem a bankou, což je místo, kde se párování obvykle rozbíjí.

  • Zákonná školení s certifikátem, ne video ke stažení

    Osm kurzů a šest set padesát pět lekcí s kvízy, checklisty a interaktivními cvičeními. Student neprojde dál, dokud nesplní povinné části, a na konci dostane certifikát.

    Technická poznámka

    Dokončení hlídá pět nezávislých podmínek: pořadí lekcí, minimální čas nad lekcí, povinný checklist, složené kvízy a teprve pak certifikát. Bez toho by doklad o proškolení neobstál před kontrolou.

  • Firemní účty se školicí maticí

    Firma si vede skupiny, podskupiny a oddělení, přiřazuje kurzy pozicím a vidí, komu školení propadá. Opakovaná školení se obnovují sama podle nastavené periody.

    Technická poznámka

    Povinné kurzy nevisí na jménech, ale na pracovních pozicích. Nový svářeč tak dostane správnou sadu školení tím, že se zařadí na pozici, ne tím, že si na něj někdo vzpomene.

  • Jeden účet pro všechny moje aplikace

    Web, e-learning, evidence úrazů i odborné fórum sdílejí jedno přihlášení. Stojí na přihlašovacím serveru, který jsem k tomu postavil, takže identita zákazníků nepatří žádné cizí službě.

    Technická poznámka

    OAuth2 a OpenID Connect s PKCE proti vlastnímu serveru account.safetyfrog.cz. Platnost přihlášení se ověřuje proti databázi každých patnáct vteřin, takže odhlášení nebo změna hesla platí ve všech aplikacích okamžitě, ne až vyprší token.

  • Administrace, která nahradila tabulky

    Devadesát osm obrazovek: produkty, objednávky, reklamace, kurzy, skupiny, blog, newsletter, prodejci, provize, audit log. Žádný plugin, žádná aktualizace zvenčí.

    Technická poznámka

    Devadesát osm obrazovek by se v cizím redakčním systému skládalo z pluginů od různých autorů. Tady je to jedna aplikace nad jedním schématem, takže objednávka, kurz a faktura mluví o téže osobě.

  • Obsah jako zdroj poptávek

    Sto devatenáct článků, osm set dvacet pět videí a sto dvacet sedm stránek k předpisům. Přes tři tisíce šest set adres, na které lidé chodí z vyhledávačů, a odtud do e-shopu.

    Technická poznámka

    Strukturovaná data jsou ve sto jedenácti souborech: články, otázky a odpovědi, návody, drobečková navigace, videa. K tomu tři sitemapy, z toho jedna zvlášť pro video.

Vychytávky

8 funkcí

Detaily, které nikdo nezadal a dělají rozdíl

  • Párování plateb, které počítá s realitou

    Tolerance je jeden haléř, ne jedna koruna. Dvě částečné platby se sečtou do jedné objednávky. Nedoplatek se eviduje a zákazník o něm ví, přeplatek se ohlásí.

    Technická poznámka

    Platba, která dorazí dřív než objednávka, se uloží jako nespárovaná a dopáruje se zpětně. U nespárovaných částek systém navrhne podobná čísla objednávek, aby šlo řešit překlep ve variabilním symbolu.

  • Objednávka se neuzavře, dokud nedoběhne všech dvacet kroků

    Přístup ke kurzu, provize, licence, faktura, e-mail. Každý krok má vlastní identifikátor a pět pokusů, opakovací úloha běží každých pět minut.

    Technická poznámka

    Přístup k obsahu se uděluje před fakturací, ne po ní. Výpadek účetního systému tak nikdy neblokuje zákazníka: objednávka zůstane ve stavu zaplaceno, faktura se dotáhne později a administrátor o tom ví.

  • Platební brána, které se nevěří na slovo

    Podpis notifikace se ověřuje v konstantním čase, každá notifikace jde do logu a duplicitu blokuje unikátní index v databázi. Skutečný stav platby si systém vždy dotáhne zpátky od brány.

    Technická poznámka

    Nezávisle na notifikacích běží každých deset minut srovnávací úloha, která dohání ztracené zprávy. Notifikace, která dorazí dřív než zápis objednávky, dostane odpověď 202 a brána ji zopakuje.

  • Certifikát, který si kdokoliv ověří bez přihlášení

    Na certifikátu je QR kód. Po jeho načtení stránka odpoví, jestli je doklad platný, propadlý, nebo jestli s ním někdo hnul.

    Technická poznámka

    Certifikát nese otisk SHA-256 spočítaný z údajů v okamžiku vydání. Zpětná změna jména nebo data se pozná, protože otisk přestane sedět. Každé ověření se loguje.

  • Fakturační údaje se vyplňují jednou pro všechno

    IČO, DIČ a adresa žijí u centrálního účtu, ne v každé aplikaci zvlášť. Zákazník je opraví na jednom místě a projeví se to všude, i na faktuře.

    Technická poznámka

    Přihlašovací server je vydává rovnou jako součást přihlášení, takže se nemusí nic dosynchronizovávat. Nákupy pořízené bez přihlášení se po pozdější registraci k účtu přiřadí podle e-mailu, aby o ně zákazník nepřišel.

  • Jedna aplikace obsluhuje tři domény

    Podle adresy, na kterou návštěvník přišel, se přepne režim webu a pustí jen odpovídající část. Šetří to provoz i údržbu.

    Technická poznámka

    Rozhodnutí padne v jednom souboru před vykreslením stránky. Tentýž soubor řeší i ochranu proti odeslání formuláře z cizí domény a oprávnění rolí, takže se pravidla nerozutečou po aplikaci.

  • Statistiky se počítají z účetních dat, ne z měřicího skriptu

    Tržby, průměrná objednávka, ziskovost produktů, platební mix, heatmapa objednávek podle dne a hodiny. Vše se srovnává s předchozím stejně dlouhým obdobím.

    Technická poznámka

    Čísla se čtou přímo z tabulek objednávek a plateb, takže odpovídají tomu, co je na faktuře. Měřicí skript v prohlížeči umí čísla ztratit blokovaným požadavkem, databáze ne.

  • Provoz se hlídá sám

    Třicet osm automatických úloh: párování plateb, upomínky, obnovy předplatných, opuštěné košíky, expirace licencí, doručování webhooků.

    Technická poznámka

    Záloha databáze běží denně, ověřuje se čtením zálohy zpátky a počítá kontrolní součet. Existuje i skript na cvičnou obnovu, protože záloha, kterou nikdo nikdy neobnovil, není záloha.

Bonusy nad rámec

4 funkce

Práce navíc, která se nepočítala

  • Databáze rizik zdarma jako vstupní brána

    Sedm set devadesát jedna pracovních nebezpečí ve veřejné encyklopedii, každé na vlastní adrese. Zdarma, bez registrace, a je to jeden z nejsilnějších zdrojů návštěvnosti.

    Technická poznámka

    Ke katalogu patří skoro pět tisíc předpřipravených opatření a sto čtyřicet pět profesí s vazbami na rizika. Placená verze z toho staví registr rizik pro konkrétní firmu, takže obsah zdarma a produkt sdílejí jedna data.

  • Sedm samostatných produktů s předplatným

    Registr rizik, kniha návštěv, kniha úrazů, kalkulačky hluku a vibrací, generátor promptů, digitální dokumenty, inzertní portál. Každý se prodává sám a má vlastní obnovu.

    Technická poznámka

    Opakované platby mají u každého modulu stejný návrh: mandát, pokusy o stržení s upomínkami a doklad souhlasu včetně IP adresy, času a znění podmínek. Bez toho se souhlas se strháváním neobhájí.

  • Inzertní portál pro obor

    Pět typů inzerátů: firma poptává, firma nabírá, odborník nabízí kapacitu, odborník hledá práci, dodavatel hledá zákazníky. S moderací před zveřejněním.

    Technická poznámka

    Odborník má pět reakcí měsíčně zdarma. Bezplatná úroveň není ukázka, ale funkční nástroj, protože prázdný inzertní portál nemá cenu pro nikoho.

  • Zákazník si postaví vlastní kurz

    Firma může v editoru vytvořit vlastní školení nad vlastním obsahem a rozdat ho svým lidem. Platí se za rozsah, ne za každého uživatele zvlášť.

    Technická poznámka

    Rozsah se skládá z kreditů, slotů na kurzy a slotů na lekce. Firma tak platí za to, co opravdu potřebuje, místo aby přeskočila o celý tarif výš kvůli jedné lekci navíc.

  • Next.js

    Stránky se skládají na serveru, takže prohlížeč dostane hotové HTML. U webu, který stojí na vyhledávačích a má přes tři tisíce adres, to není volba stylu.

  • React

    Interaktivní části (přehrávač kurzu, košík, editor dokumentů) potřebují stav v prohlížeči. Zbytek webu zůstává serverový.

  • TypeScript

    Čtyři sta tisíc řádků se bez typů neudrží. Sestavení padá na typové chybě, takže se rozbitá varianta na produkci neobjeví.

  • Tailwind CSS

    Barvy, rádiusy a časování mají jediné místo pravdy v bloku @theme. Světlý i tmavý režim se pak přepíná přepsáním tokenů, ne druhou sadou komponent.

  • Prisma

    Tři sta modelů a sto padesát devět migrací se spravuje z jednoho schématu. Migrace jsou verzované v gitu, takže je vidět, kdy a proč se datový model změnil.

  • PostgreSQL

    Peníze potřebují transakce a unikátní indexy. Deduplikaci plateb tady řeší částečný unikátní index v databázi, ne podmínka v aplikaci, kterou by souběh obešel.

  • Docker a Caddy

    Aplikace, databáze a migrátor běží jako tři služby v uzavřené síti. Ven nevede žádný port, veškerý provoz jde přes Caddy.

  • Caddy

    Certifikáty se obnovují samy a hlavičky (HSTS, potlačení otisku serveru) jsou v jednom souboru. Při výpadku aplikace vrací vlastní stránku místo chyby brány.

  • S3 úložiště

    Zakoupené soubory a fotodokumentace úrazů leží mimo aplikaci. Stahují se přes podepsanou adresu s krátkou platností, takže nasazení nikdy nepřepíše data zákazníků.

  • bezpecak.safetyfrog.cz
    Homepage bezpecak.safetyfrog.cz
Od zadání ke spuštění
4 měsíce
Co se dodalo
Web na míru, E-shop, Aplikace na míru, Správa a rozvoj, SEO a obsah
Web běží od
2026
  • 20kroků objednávky bez ručního zásahu
  • 3systémy, které si povídají samy
  • 3 625adres na jednom webu
  • 655lekcí v osmi kurzech
  • 119 + 825blogových článků a videí
  • 303tabulek v jedné databázi

Potřebujete něco podobného

Napište nám, co řešíte. Ozveme se do jednoho pracovního dne a řekneme rovnou, jestli to umíme a co to bude stát.