Přeskočit na hlavní obsah

Monitoring cronů a doručování e-mailů

Stránka Monitoring (cesta /admin/monitoring) je přístupná jen pro role Owner a Admin organizace, případně pro platform admins. Běžným uživatelům není určena — pokud nejste správcem organizace, tato stránka pro vás není relevantní.

Monitoring vznikl v květnu 2026 (Sprint 96+97) jako reakce na otázku „Co když appka lehne uprostřed nějaké úlohy a něco se ztratí?". Aplikace má teď čtyři vrstvy ochrany pro plánované úlohy (crony) a doručování e-mailů.

K čemu monitoring slouží

Aplikace má 23 plánovaných úloh (crony) — od denních upomínek a týdenního přehledu, přes generování opakovaných faktur, po automatické posílání připomínek po splatnosti. K tomu přibyl systém pro spolehlivé doručování e-mailů, který automaticky opakuje neúspěšné odeslání.

Monitoring vám ukazuje:

  • Historii cronů — co kdy běželo, jestli se to povedlo, jak dlouho to trvalo, případně proč to selhalo.
  • E-maily čekající na opakování — pokud Resend (e-mailová služba) chvíli vypadne nebo vrátí chybu, e-mail se nezahodí, ale dostane se do fronty pro opakování.
  • Možnost ručního zásahu — můžete vybraný e-mail poslat znovu okamžitě nebo označit jako vyřešený.

Sekce: Historie cronů (CronRunsCard)

Sekce zobrazuje posledních 50 spuštění cronů s automatickým obnovením každých 30 sekund.

Filtry a výběr okna

FiltrPopis
StavVšechny / Úspěšné / Chyby / Přeskočeno / Běží / Spadl
Název úlohyFiltrace podle konkrétního cronu (např. weekly-digest, freelo-sync)
Časové oknoPosledních 1h / 6h / 24h / 7 dní

Stavy a co znamenají

Každý záznam má barevně označený stav:

BarvaStavVýznam
ZelenáÚspěchÚloha proběhla bez chyby.
ČervenáChybaÚloha selhala — kliknutím na řádek rozbalíte error message a metadata.
OranžováPřeskočenoDruhá replika kontejneru byla rychlejší a získala Redis lock. Druhá replika se přeskočila — to je správné chování pro multi-replica safety.
ModráBěžíÚloha právě běží (nebo nebyla správně dokončena — viz „Spadl" níže).
FialováSpadlAplikace se restartovala uprostřed běhu úlohy. Po restartu boot recovery automaticky označí orphan záznamy starší než 15 minut jako spadlé, aby nezasekávaly další pokusy.
Catch-up scan při bootu

Pokud aplikace byla offline a propásla nějaké plánované spuštění (například denní cron v 7:00 a aplikace nabíhala v 7:15), při startu proběhne catch-up scan — vrátí se 24 hodin zpět, zjistí které úlohy měly proběhnout, a doplní je. Idempotency tabulka zajistí, že se úloha nespustí dvakrát ani v multi-replica nasazení.

Rozbalení detailu

Kliknutím na řádek se rozbalí:

  • Error message — pokud úloha selhala, plný text chyby (stack trace pokud je k dispozici)
  • Metadata — runId (UUID), durationMs (jak dlouho běžela), případně další JSON metadata
  • Časové údaje — kdy začala, kdy skončila

Sekce: Fronta e-mailů (FailedEmailsCard)

Sekce ukazuje e-maily, které se nepodařilo odeslat napoprvé a čekají na opakování (nebo už dosáhly limitu).

Stavy ve frontě

StavPopis
PendingE-mail čeká na další pokus (cron email-retry běží každých 5 minut).
ClaimedCron právě e-mail zpracovává.
SucceededE-mail byl úspěšně doručen po dřívějším selhání. Záznam se v rámci úklidu maže po 30 dnech.
Dead letterPo 5 neúspěšných pokusech se e-mail označí jako dead letter, vyžaduje manuální zásah. Admin organizace dostane upozornění. Záznam se uchovává 90 dní pro audit.

Mechanika opakování

Pokud Resend vrátí chybu, e-mail se zařadí do fronty s plánovanou další repeticí podle exponenciálního schématu:

PokusČekání před dalším pokusem
1. (původní)
2.5 minut
3.30 minut
4.1 hodina
5.6 hodin
(pokud i pak selže)dead letter
Throughput

Cron email-retry zpracovává max 10 e-mailů per spuštění s paralelním limitem 5. To znamená horní hranici cca 120 e-mailů za hodinu při retry storm — chrání to Resend i naši DB před přetížením.

Akce dostupné na řádku

Pro stavy pending a dead letter můžete:

  • „Retry now" — okamžitě naplánovat další pokus (resetuje next_retry_at na teď). Použijte když víte, že příčina selhání pominula (Resend opět funguje, klient si potvrdil, že má SPF/DMARC v pořádku).
  • „Mark resolved" — ručně označit e-mail jako vyřešený (například pokud jste klientovi stejnou informaci napsal ručně přes Outlook). Nezahájí žádný další pokus.

Co se NEopakuje (skipRetry)

Pět typů e-mailů automatickou frontu vědomě obchází, protože automatické opakování by zhoršilo UX nebo nedávalo smysl:

E-mailDůvod přeskočení
Reset heslaToken v odkazu má TTL 1 hodinu — opakování po 30 minutách by uživateli poslalo odkaz, který už expiroval. Pokud reset nedorazil, klikněte v aplikaci na „Zaslat znovu".
Ověření e-mailuStejný důvod — ověřovací token má krátkou TTL.
Custom verificationStejný důvod jako výše.
Faktura jako PDF přílohaPříloha se přikládá při generování e-mailu, retry layer příloh zatím neumí (Sprint 97+ F2 backlog). Pokud klient fakturu nedostal, pošlete ji znovu z detailu faktury.
Klientský report jako PDF přílohaStejný důvod — příloha se neukládá ve frontě. Pošlete report znovu z modulu Klientské reporty.

Pro zbylých 23 typů e-mailů (notifikace o schválení výkazů, týdenní přehled, denní připomínky, upomínky po splatnosti, member welcome atd.) je opakování zapnuté ve výchozím stavu.

Typický scénář: Resend výpadek

  1. Resend (e-mailová služba) má 30minutový výpadek odpoledne.
  2. Během výpadku aplikace zkusí poslat 8 e-mailů — všechny selžou.
  3. Všech 8 e-mailů se zařadí do fronty pending s plánovaným opakováním za 5 minut.
  4. Cron email-retry v 5min intervalu zkusí znovu — pokud Resend stále nefunguje, e-maily se přeplánují za 30 minut.
  5. Resend obnoven po 30 minutách → další tikne cron → všech 8 e-mailů projde, status se změní na succeeded.
  6. Žádný uživatel si ničeho nevšiml — krom zpoždění o ~30 minut.

V monitoringu po výpadku vidíte 8 zelených „succeeded" záznamů s počtem pokusů (např. 3/5).

Typický scénář: Klient blokuje SPF

  1. Aplikace pošle týdenní přehled klientovi.
  2. Klientův mailserver odmítá kvůli SPF konfiguraci.
  3. Po 5 pokusech se e-mail označí jako dead letter.
  4. Admin organizace dostane upozornění (e-mail).
  5. Admin se podívá na /admin/monitoring, vidí dead letter záznam, klikne na detail, zjistí adresu klienta a chybovou hlášku.
  6. Buď klienta kontaktuje s žádostí o opravu SPF, nebo klikne „Mark resolved" a informaci klientovi pošle jinou cestou.

Co monitoring NEukazuje

Pro úplnost — monitoring se týká interní infrastruktury (cronové úlohy + e-mailová fronta). Nezobrazuje:

  • Audit log uživatelských akcí (ten je v sekci níž — AdminAuditLogSection)
  • Historii Stripe webhooků (samostatná tabulka processed_stripe_events)
  • Aplikační logy Sentry (Sentry dashboard)

Časté otázky

Můžu monitoring vypnout?

Ne — monitoring je jen pro čtení a žádné akce nedělá automaticky bez vašeho souhlasu (kromě cronu email-retry, který běží automaticky a je core funkcí). Tracking cronů a fronta e-mailů jsou součástí infrastruktury aplikace.

Co se stane, když je dead letter příliš mnoho?

Pokud vidíte mnoho dead letter záznamů, něco systémového nefunguje — typicky problém s konfigurací domény odesílatele, problém s SPF/DKIM klienta, nebo blokace IP. Kontaktujte podporu (info@mujvykaz.cz).

Můžu zvýšit počet pokusů z 5 na víc?

Ne, to je pevně nastavené. Pět pokusů za 24 hodin pokrývá většinu reálných výpadků. Větší počet by jen prodlužoval „neutrální" stav e-mailu, ale neopravil by skutečné problémy (jako blokace SPF).

Proč mé faktury nejsou ve frontě e-mailů?

Faktury (a klientské reporty) se posílají s PDF přílohou. Aktuální verze fronty neumí přílohy znovu vygenerovat při opakování (Sprint 97+ F2 v backlogu). Proto je u nich opakování záměrně vypnuté. Pokud klientovi fakturu nedorazila, pošlete ji znovu z detailu faktury (/invoicing/[id] → tlačítko „Odeslat klientovi").

Můžu vidět tělo e-mailu, který se nepodařilo poslat?

V monitoringu vidíte metadata (příjemce, předmět, počet pokusů, stav, příští pokus), ale tělo e-mailu se v seznamu nezobrazuje kvůli ochraně soukromí a velikosti. Pro rozbalení detailu klikněte na řádek — pak uvidíte i obsah.


Související: