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

Stavovy guard model

PreviousNext

Single source of truth pre bike status transitions.

status: implemented
type: plan
#plany
#stavovy-model
#bike-flow

Migrovane z docs-old-cvrn/plans/PLAN_STAVOVY_GUARD_MODEL.md.

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

Toto je dokumentacny implementacny plan.

  • Core guard model JE implementovany v DB vrstve (bike_transition_guard + bike_transition_apply).
  • Existujuce bike mutacie (rent_bike, return_bike, admin bike RPC) deleguju transition guardy do tohto jadra.
  • Dokument ostava referencny pre dalsie rozsirenia (reported, override flows) a test matrix.

1) Ciel

Zaviest centralny stavovy guard model pre bike flow tak, aby:

  • existovala jedna pravda pre vsetky bike status transitions,
  • vsetky mutacie pouzivali rovnake guard pravidla,
  • error kody boli konzistentne bez ohladu na route/UI,
  • bolo jednoduche doplnat dalsie stavy (napr. reported) bez duplikacie logiky,
  • audit bol konzistentny pre admin operacie aj user flow.

2) Scope

In scope

  • centralizacia pravidiel pre prechody stavu bicykla,
  • jednotne guardy pre user/admin mutacie,
  • jednotny error contract pre transition zamietnutia,
  • refaktor existujucich bike mutacii na spolocny guard jadro,
  • test matrix pre povolene/zakazane transitions,
  • priprava hookov pre buduci stav reported.

Out of scope (v tejto faze)

  • redesign celej domény rentals,
  • notifikacie (email/SMS),
  • zmena UX flow na dashboarde mimo nutnych error mapping uprav,
  • zmena modelu code_status osi (riesi sa samostatne v dynamic-code plane).

3) Problem dnes

Aktualne pravidla su funkcne, ale su rozdelene medzi viac miest:

  • cast guardov je v RPC rent_bike / return_bike,
  • cast guardov je v admin RPC mutaciach,
  • cast validacie/error mapping je v src/app/actions.ts.

Dopad:

  • rastie riziko nekonzistentnych pravidiel pri novych features,
  • pre nove stavy (reported) treba prechadzat viac suborov,
  • regressions sa tazsie hladaju, lebo neexistuje centralny transition kontrakt.

4) Navrhovany cielovy model

Zaviest "state transition engine" na DB vrstve:

  1. Jedno centralne guard jadro rozhodne, ci je transition povoleny.
  2. Konkretne RPC mutacie budu tenky wrapper:
    • nacitaju actor context,
    • zavolaju guard jadro,
    • vykonaju side-effects (rentals, audit, poznamky).
  3. Frontend nebude vediet o internom modeli:
    • stale bude volat semanticke RPC (rent_bike, return_bike, ...),
    • ale vsetky budu pouzivat rovnake guard pravidla.

5) Stavovy model a osy

5.1 Operacna os bikes.status (teraz)

  • available
  • rented
  • service

5.2 Rozsiritelnost (priprava)

  • buduci stav: reported (plan uz existuje),
  • guard model musi byt pripraveny doplnit reported bez prepisu celej logiky.

5.3 Dolezite pravidlo osi

  • status = operacna pozicatelnost bicykla,
  • code_status (ak je pouzite) = doveryhodnost kodu zamku,
  • tieto osi sa nesmu implicitne miesat.

6) Transition katalog (decision-complete)

6.1 User transitions (v tejto faze)

  1. user_rent
    • from: available
    • to: rented
    • guard:
      • actor je allowlisted user,
      • actor nema aktivny rental,
      • bike existuje.
    • reject:
      • not_allowed, already_has_bike, bike_not_available, bike_not_found
  2. user_return
    • from: rented
    • to: available
    • guard:
      • actor je aktualny drzitel bike (current_user_id),
      • existuje aktivny rental.
    • reject:
      • no_active_bike, rental_not_found

6.2 Admin transitions (v tejto faze)

  1. admin_set_service
    • from: available
    • to: service
    • guard:
      • actor je admin,
      • bike nie je rented.
    • reject:
      • not_admin, bike_rented, bike_not_found
  2. admin_set_available
    • from: service
    • to: available
    • guard:
      • actor je admin,
      • bike nie je rented.
    • reject:
      • not_admin, bike_rented, bike_not_found
  3. admin_update_code
    • status transition: none (stav sa nemeni)
    • guard:
      • actor je admin,
      • bike existuje,
      • novy kod je validny.
    • reject:
      • not_admin, bike_not_found, invalid_code
  4. admin_clear_note
    • status transition: none
    • guard:
      • actor je admin,
      • bike existuje.
    • reject:
      • not_admin, bike_not_found

6.3 Reserved transitions (future-ready)

  • user_report_bike (available -> reported)
  • admin_resolve_report_to_available (reported -> available)
  • admin_resolve_report_to_service (reported -> service)
  • admin_override_rent_reported (reported -> rented, admin-only)

7) Technicky navrh (DB/RPC)

7.1 Centralne guard jadro

Navrhovane interne funkcie (DB):

  1. bike_transition_guard(p_transition text, p_bike_id bigint, p_actor uuid, p_meta jsonb default '{}'::jsonb)
    • vrati ok boolean, error_code text, resolved_bike_id bigint, current_status text, target_status text.
  2. bike_transition_apply(p_transition text, p_bike_id bigint, p_actor uuid, p_meta jsonb default '{}'::jsonb)
    • vola guard,
    • pri ok=false vyhodi jednotny error_code,
    • pri ok=true vykona status update + potrebne side-effects.

Poznamka:

  • tieto funkcie budu interne (nie priamo volane klientom),
  • verejne RPC ostanu semanticke (rent_bike, return_bike, admin mutacie).

7.2 Verejne RPC po refaktore

  • rent_bike => deleguje do transition jadra (user_rent)
  • return_bike => deleguje do transition jadra (user_return)
  • admin_set_bike_status => deleguje do transition jadra (admin_set_service / admin_set_available)
  • admin_update_bike_code => guard + side-effects (bez zmeny statusu)
  • admin_clear_bike_note => guard + side-effects (bez zmeny statusu)

8) Error contract (jednotny)

Pri transition guard zamietnuti sa vracaju standardizovane kody:

  • not_authenticated
  • not_allowed
  • not_admin
  • bike_not_found
  • bike_not_available
  • bike_rented
  • already_has_bike
  • no_active_bike
  • rental_not_found
  • invalid_status
  • invalid_code
  • transition_not_allowed

Frontend mapovanie hlasky ostava v actions.ts, ale kody budu centralne.

9) Datova integrita a locking

  • vsetky transition mutacie musia pouzit select ... for update na bikes row,
  • rental mutacie musia drzat lock konzistentne s rentals update,
  • side-effects sa vykonavaju v jednej transaction scope.

10) Implementacny plan (fazy)

Faza A: Spec + SQL zaklad

  • doplnit internej DB funkcie pre guard/apply,
  • pridat/zosuladit jednotny error kod set,
  • zachovat existujuce API signatury.

Faza B: Refaktor existujucich RPC

  • rent_bike, return_bike, admin_set_bike_status, admin_update_bike_code, admin_clear_bike_note delegovat na guard jadro.

Faza C: App vrstva

  • overit, ze src/app/actions.ts mapuje jednotne error kody,
  • odstranit redundantne lokalne guardy, ktore sa duplikuju s DB guardom.

Faza D: Testy a rollout

  • SQL test matrix pre povolene/zakazane transitions,
  • regression test user/admin flow,
  • rollout najprv na staging/proxy DB, potom produkcia.

11) Test matrix (minimum)

  1. User rent:
  • available bike + bez aktivneho rentalu => success
  • rented/service bike => fail (bike_not_available)
  • user s aktivnym rentalom => fail (already_has_bike)
  1. User return:
  • user je current holder => success
  • user nema bike => fail (no_active_bike)
  1. Admin status:
  • admin set service na available => success
  • admin set available na service => success
  • admin set status na rented bike => fail (bike_rented)
  • non-admin admin RPC => fail (not_admin)
  1. Admin code/note:
  • update code valid => success + audit
  • clear note => success + audit
  • non-admin => fail (not_admin)
  1. Concurrency:
  • paralelny rent rovnakeho bike => maximalne 1 success
  • paralelny return/rent na rovnaky bike => konzistentny final state

12) Rizika a mitigacie

  1. Riziko: regresia v existujucich flow po refaktore.
  • Mitigacia: zachovat API signatury + test matrix pred release.
  1. Riziko: nejednotne error texty po zmene kodov.
  • Mitigacia: centralny error contract + explicit mapping v actions.
  1. Riziko: komplikacia pri buducich stavoch (reported).
  • Mitigacia: reserved transitions uz teraz v navrhu, bez implementacie.

13) Minimalny backlog (poradie)

  1. Navrhnut a pridat internej DB guard/apply funkcie.
  2. Refaktor rent_bike + return_bike na guard jadro.
  3. Refaktor admin bike mutacii na guard jadro.
  4. Zjednotit error codes a mapovanie v actions.ts.
  5. Dodat SQL + app regression testy.
  6. Rollout na staging, potom produkcia.

14) Vztah k ostatnym planom

  • PLAN_NAHLASENE_NEPOZICATELNE_BIKY.md: guard model ma byt pripraveny na reported transitions.
  • PLAN_DYNAMICKY_KOD.md: oddelit operacnu os status od osi code_status.
  • PLAN_MAPA_STANOVISTA.md: station-aware pravidla maju byt nadstavba nad centralnym guard modelom.
Prehlad planovNahlasene nepozicatelne biky

On This Page

0) Stav realizacie (aktualizovane 2026-02-16)1) Ciel2) ScopeIn scopeOut of scope (v tejto faze)3) Problem dnes4) Navrhovany cielovy model5) Stavovy model a osy5.1 Operacna os bikes.status (teraz)5.2 Rozsiritelnost (priprava)5.3 Dolezite pravidlo osi6) Transition katalog (decision-complete)6.1 User transitions (v tejto faze)6.2 Admin transitions (v tejto faze)6.3 Reserved transitions (future-ready)7) Technicky navrh (DB/RPC)7.1 Centralne guard jadro7.2 Verejne RPC po refaktore8) Error contract (jednotny)9) Datova integrita a locking10) Implementacny plan (fazy)Faza A: Spec + SQL zakladFaza B: Refaktor existujucich RPCFaza C: App vrstvaFaza D: Testy a rollout11) Test matrix (minimum)12) Rizika a mitigacie13) Minimalny backlog (poradie)14) Vztah k ostatnym planom
© CVRN dokumentacia