CVRN logoCVRN Docs
DocsArchitekturaPlanyChangelog
Sections
  • Zaklady
  • Architektura
  • Komunita
  • Legal
  • Plany
  • Changelog
Zaklady
  • O dokumentacii
  • Ako citat dokumentaciu
  • Struktura repozitara
Architektura
  • Ako aplikacia funguje
  • Diagramy
Komunita
  • Prehlad komunitnych pravidiel
  • CVRN desatoro
  • Onboarding a aktivacia clena
  • Prevadzkove pravidla (draft)
  • Treningovy mod (navrh)
  • WhiteBikes poznamky
  • Analyza Rekola
  • Analyza Slovnaft BAjk
Legal
  • Zasady ochrany osobnych udajov (navrh)
  • GDPR brief pre pravnika
  • RoPA template
  • Reklamacny a incidencny poriadok (draft)
Plany
  • Prehlad planov
  • Stavovy guard model
  • Nahlasene nepozicatelne biky
  • Email notifikacie (outbox)
  • Dynamicky kod a historia
  • Mapa a stanovista
  • Statistiky a historia jazd
  • Logo hover header
  • Backlog whitebikes inspired
Changelog
  • Sync a automatizacia
  • CVRN App Changelog

Email notifikacie (outbox)

PreviousNext

Plan transakcneho odosielania emailov cez spolahlivu outbox queue.

status: planned
type: plan
#plany
#email
#outbox

Migrovane z docs-old-cvrn/PLAN_EMAIL_NOTIFIKACIE.md.

0) Stav realizacie (aktualizovane 2026-02-11)

Toto je dokumentacny implementacny plan pre buducu funkcionalitu.

  • Feature este NIE JE implementovana v appke ani DB.
  • Ciel je mat decision-complete specifikaciu pred kodovanim.
  • Tento plan doplna plan reported bicyklov.

1) Ciel

Pridat transakcne e-mail notifikacie tak, aby:

  • appka posielala maily v mene app@cvrn.sk,
  • kriticke udalosti o reported bicykloch prisli automaticky adminom,
  • reporter dostal potvrdenie pri vytvoreni a uzavreti reportu,
  • odosielanie bolo spolahlive (retry, audit, bez blokovania core flow).

2) Scope

In scope (MVP)

  • provider Resend (API),
  • outbox model (email_outbox) + inline send attempt + cron retry,
  • konfiguracia recipientov v DB + admin UI,
  • zakladny admin log odosielania + retry akcia,
  • plain text SK e-mail sablony,
  • eventy:
    • reported_created_admin,
    • reported_created_reporter,
    • reported_resolved_admin,
    • reported_resolved_reporter,
    • reported_override_admin.

Out of scope (v tejto faze)

  • reminder maily po 24h/72h,
  • digesty (denne/tyzdenne),
  • notifikacie pre allowlist zmeny a ine ne-kriticke eventy,
  • SMS/push notifikacie,
  • HTML templating engine.

3) Produktove rozhodnutia (uzamknute)

  1. Provider: Resend.
  2. Sender: From=app@cvrn.sk, Reply-To=info@cvrn.sk.
  3. Delivery model: outbox queue + inline attempt + cron retry.
  4. Recipient config: DB + admin UI (nie len ENV).
  5. User notifikacie: ano pre report create aj report resolve.
  6. Format: plain text, slovencina.
  7. MVP bez reminderov.

4) Architektura (high level)

  1. Biznis event vznikne v report RPC (create/resolve/override).
  2. V tej istej DB transakcii sa vlozia riadky do email_outbox.
  3. Po uspesnom evente sa spusti inline send attempt pre nove pending riadky.
  4. Chyby idu do retry_scheduled s next_attempt_at.
  5. Cron endpoint periodicky spracuje retry queue.
  6. Admin ma read-only log + manual retry akciu.

5) Datovy model (decision-complete)

5.1 Nova tabulka public.notification_recipients

  • id bigint generated by default as identity primary key
  • email text not null
  • label text null
  • is_active boolean not null default true
  • created_at timestamptz not null default now()
  • updated_at timestamptz not null default now()
  • created_by uuid null references public.profiles(id) on delete set null

Constrainty a indexy:

  • unique index na lower(email)
  • index na (is_active, created_at desc)

5.2 Nova tabulka public.email_outbox

  • id bigint generated by default as identity primary key
  • event_type text not null
  • event_ref_type text not null (napr. bike_report)
  • event_ref_id bigint not null
  • to_email text not null
  • subject text not null
  • body_text text not null
  • status text not null default 'pending'
    • allowed: pending, sending, sent, failed, retry_scheduled, dead
  • attempt_count int not null default 0
  • next_attempt_at timestamptz null
  • last_error text null
  • provider_message_id text null
  • created_at timestamptz not null default now()
  • sent_at timestamptz null

Constrainty:

  • check (status in ('pending','sending','sent','failed','retry_scheduled','dead'))
  • dedupe unique key:
    • (event_type, event_ref_type, event_ref_id, lower(to_email))

Indexy:

  • (status, created_at asc)
  • (status, next_attempt_at asc)
  • (event_ref_type, event_ref_id)

6) API / RPC zmeny

6.1 Rozsirenie report RPC

  1. report_bike_unrentable(...)
    • enqueue reported_created_admin pre aktivnych recipientov,
    • enqueue reported_created_reporter pre usera, ktory report vytvoril.
  2. admin_resolve_bike_report(...)
    • enqueue reported_resolved_admin,
    • enqueue reported_resolved_reporter pre povodneho reportera.
  3. admin_override_rent_reported_bike(...)
    • enqueue reported_override_admin.

Poznamka:

  • enqueue sa deje v tej istej transakcii ako biznis event.
  • zlyhanie inline send attempt nesmie rollbacknut report/rental mutaciu.

6.2 Nove admin RPC

  1. admin_list_notification_recipients()
  2. admin_upsert_notification_recipient(email text, is_active boolean, label text default null)
  3. admin_delete_notification_recipient(recipient_id bigint)
  4. admin_list_email_outbox(limit_count int default 200, status_filter text default null)
  5. admin_retry_email_outbox_item(outbox_id bigint)

6.3 Helper funkcie

  • enqueue_reported_email_events(...) (DB helper alebo server helper)
  • email_compute_next_attempt(attempt_count int) pre backoff

7) Retry politika

  • Max pokusov: 5
  • Backoff:
    • pokus 1: +1 min
    • pokus 2: +5 min
    • pokus 3: +15 min
    • pokus 4: +60 min
    • pokus 5: +360 min
  • Po prekroceni limitu: dead

8) Frontend / Admin UX

8.1 /admin sekcia "Notifikacni prijemcovia"

  • pridanie prijemcu (email + volitelny label),
  • aktivacia/deaktivacia,
  • odstranenie.

8.2 /admin sekcia "E-mail outbox log"

  • filter podla stavu (pending/sent/failed/retry_scheduled/dead),
  • stlpce:
    • event,
    • to,
    • status,
    • attempts,
    • last_error,
    • created_at,
    • sent_at,
  • akcia Retry pre failed/dead.

9) Integracia s providerom (Resend)

Potrebne env premenne:

  • RESEND_API_KEY
  • EMAIL_FROM=app@cvrn.sk
  • EMAIL_REPLY_TO=info@cvrn.sk
  • EMAIL_CRON_SECRET

DNS onboarding (mimo kodu):

  • SPF, DKIM, DMARC pre cvrn.sk,
  • overenie sender domény v Resend.

10) Security a compliance

  • cron endpoint musi kontrolovat bearer secret (EMAIL_CRON_SECRET),
  • ziadne citlive udaje (secret_code) v tele e-mailov,
  • logovat len technicke detaily chyb bez zbytocnych PII,
  • RLS/admin guard pre recipient/outbox citanie a mutacie.

11) Test scenare

11.1 Funkcne

  1. Report create -> vzniknu outbox riadky pre admin + reportera.
  2. Report resolve -> vzniknu outbox riadky pre admin + reportera.
  3. Override rent -> admin alert mail event.
  4. Inline success -> sent + provider_message_id.
  5. Inline fail -> retry_scheduled + next_attempt_at.
  6. Cron retry -> uspesne dorucenie pending/retry mailu.
  7. Manual retry z admin UI funguje.

11.2 Security

  1. Cron endpoint bez valid secret vrati unauthorized.
  2. Bezny user nema pristup k recipient/outbox admin RPC.
  3. Dedupe key zabrani duplicitnym mailom pri race condition.

11.3 Regression

  1. Report/rent/return flow funguje aj pri vypadku provideru.
  2. Zlyhanie mailu nevracia report mutaciu naspat.

12) Dokumentacny dopad

Pri implementacii tejto funkcionality aktualizovat:

  • README.md (setup env + sekcia notifikacii),
  • CONTRIBUTING.md (kde sa plan nachadza + scope),
  • docs/checklist.md (feature-specific checks),
  • docs/CHANGELOG.md ([Unreleased]),
  • /docs/plany/nahlasene-nepozicatelne-biky (cross-reference).

13) Rollout plan

Faza A: Schema + provider adapter

  • DB tabulky, indexy, constraints,
  • env setup, Resend adapter, text template builder.

Faza B: Worker + cron

  • inline send attempt,
  • cron retry endpoint,
  • retry/backoff pravidla.

Faza C: Event napojenie

  • create/resolve/override event wiring z report flow.

Faza D: Admin observability

  • recipient management,
  • outbox log + manual retry.

14) Predpoklady a defaulty

  1. Hosting je Next.js + serverless kompatibilne cron volanie.
  2. reported flow je implementovany a sluzi ako event source.
  3. Provider default je Resend, ale adapter vrstva umozni vymenu neskor.
  4. Tento dokument je plan; runtime implementacia sa robi az v samostatnom kroku.
Nahlasene nepozicatelne bikyDynamicky kod a historia

On This Page

0) Stav realizacie (aktualizovane 2026-02-11)1) Ciel2) ScopeIn scope (MVP)Out of scope (v tejto faze)3) Produktove rozhodnutia (uzamknute)4) Architektura (high level)5) Datovy model (decision-complete)5.1 Nova tabulka public.notification_recipients5.2 Nova tabulka public.email_outbox6) API / RPC zmeny6.1 Rozsirenie report RPC6.2 Nove admin RPC6.3 Helper funkcie7) Retry politika8) Frontend / Admin UX8.1 /admin sekcia "Notifikacni prijemcovia"8.2 /admin sekcia "E-mail outbox log"9) Integracia s providerom (Resend)10) Security a compliance11) Test scenare11.1 Funkcne11.2 Security11.3 Regression12) Dokumentacny dopad13) Rollout planFaza A: Schema + provider adapterFaza B: Worker + cronFaza C: Event napojenieFaza D: Admin observability14) Predpoklady a defaulty
© CVRN dokumentacia