Architektura
Komunita
Legal
Plany
Changelog
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_statusosi (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:
- Jedno centralne guard jadro rozhodne, ci je transition povoleny.
- Konkretne RPC mutacie budu tenky wrapper:
- nacitaju actor context,
- zavolaju guard jadro,
- vykonaju side-effects (rentals, audit, poznamky).
- Frontend nebude vediet o internom modeli:
- stale bude volat semanticke RPC (
rent_bike,return_bike, ...), - ale vsetky budu pouzivat rovnake guard pravidla.
- stale bude volat semanticke RPC (
5) Stavovy model a osy
5.1 Operacna os bikes.status (teraz)
availablerentedservice
5.2 Rozsiritelnost (priprava)
- buduci stav:
reported(plan uz existuje), - guard model musi byt pripraveny doplnit
reportedbez 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)
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
- from:
user_return- from:
rented - to:
available - guard:
- actor je aktualny drzitel bike (
current_user_id), - existuje aktivny rental.
- actor je aktualny drzitel bike (
- reject:
no_active_bike,rental_not_found
- from:
6.2 Admin transitions (v tejto faze)
admin_set_service- from:
available - to:
service - guard:
- actor je admin,
- bike nie je rented.
- reject:
not_admin,bike_rented,bike_not_found
- from:
admin_set_available- from:
service - to:
available - guard:
- actor je admin,
- bike nie je rented.
- reject:
not_admin,bike_rented,bike_not_found
- from:
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
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):
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.
- vrati
bike_transition_apply(p_transition text, p_bike_id bigint, p_actor uuid, p_meta jsonb default '{}'::jsonb)- vola guard,
- pri
ok=falsevyhodi jednotnyerror_code, - pri
ok=truevykona 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_authenticatednot_allowednot_adminbike_not_foundbike_not_availablebike_rentedalready_has_bikeno_active_bikerental_not_foundinvalid_statusinvalid_codetransition_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 updatenabikesrow, - rental mutacie musia drzat lock konzistentne s
rentalsupdate, - 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_notedelegovat na guard jadro.
Faza C: App vrstva
- overit, ze
src/app/actions.tsmapuje 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)
- User rent:
- available bike + bez aktivneho rentalu => success
- rented/service bike => fail (
bike_not_available) - user s aktivnym rentalom => fail (
already_has_bike)
- User return:
- user je current holder => success
- user nema bike => fail (
no_active_bike)
- 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)
- Admin code/note:
- update code valid => success + audit
- clear note => success + audit
- non-admin => fail (
not_admin)
- Concurrency:
- paralelny rent rovnakeho bike => maximalne 1 success
- paralelny return/rent na rovnaky bike => konzistentny final state
12) Rizika a mitigacie
- Riziko: regresia v existujucich flow po refaktore.
- Mitigacia: zachovat API signatury + test matrix pred release.
- Riziko: nejednotne error texty po zmene kodov.
- Mitigacia: centralny error contract + explicit mapping v actions.
- Riziko: komplikacia pri buducich stavoch (
reported).
- Mitigacia: reserved transitions uz teraz v navrhu, bez implementacie.
13) Minimalny backlog (poradie)
- Navrhnut a pridat internej DB guard/apply funkcie.
- Refaktor
rent_bike+return_bikena guard jadro. - Refaktor admin bike mutacii na guard jadro.
- Zjednotit error codes a mapovanie v
actions.ts. - Dodat SQL + app regression testy.
- Rollout na staging, potom produkcia.
14) Vztah k ostatnym planom
PLAN_NAHLASENE_NEPOZICATELNE_BIKY.md: guard model ma byt pripraveny nareportedtransitions.PLAN_DYNAMICKY_KOD.md: oddelit operacnu osstatusod osicode_status.PLAN_MAPA_STANOVISTA.md: station-aware pravidla maju byt nadstavba nad centralnym guard modelom.
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