Architektura
Komunita
Legal
Plany
Changelog
Migrovane z
docs-old-cvrn/plans/PLAN_NAHLASENE_NEPOZICATELNE_BIKY.md.
0) Stav realizacie (aktualizovane 2026-02-11)
Toto je dokumentacny implementacny plan.
- Feature este NIE JE implementovana v appke ani DB.
- Ciel je mat decision-complete specifikaciu pred kodovanim.
- Existujuci flow
issue_noteostava v prevadzke bez zmeny.
1) Ciel
Pridat user flow pre nahlasenie zjavne nepojazdneho/problemoveho bicykla este pred pozicanim tak, aby:
- user vedel nahlasit problem bez spustenia rent flow,
- bicykel bol po nahlaseni nepozicatelny pre beznych userov,
- v systeme vznikol admin audit/report zaznam,
- admin vedel report uzavriet po fyzickej kontrole,
- existoval admin override rent pre servisny test.
2) Scope
In scope
- novy stav bicykla
reported, - samostatna tabulka reportov
bike_reports, - user akcny flow "Nahlasit" pred pozicanim,
- povinna report poznamka,
- UI formular cez bottom Drawer,
- admin sekcia pre open/resolved reporty,
- admin akcia
resolve+ adminoverride rent, - pravidla proti duplicitnym otvorenym reportom.
Out of scope (v tejto faze)
- auto-expiracia reportov (timeout),
- verejne zobrazenie textu reportu beznym userom,
- notifikacie SMS/Push,
- automaticka detekcia poruch bez user reportu.
Poznamka:
- e-mail notifikacie su riesene v samostatnom plane
docs/PLAN_EMAIL_NOTIFIKACIE.md.
3) Produktove rozhodnutia (uzamknute)
- Model stavu: pouzit novy
bikes.status='reported'. - Data model reportov: samostatna tabulka (bez refaktoru existujuceho
issue_note). - User input: poznamka je povinna.
- User UI: report formular sa otvara cez bottom Drawer.
- User viditelnost: bezny user vidi iba kratky status
Nahlasene, nie detail textu. - Duplicity: ak bike ma otvoreny report, dalsie user reporty sa blokuju.
- Recovery: standard je
admin fix + potvrdit. - Admin override: admin moze pozicat
reportedbike aj bez uzavretia reportu.
4) Vychodiskovy stav (teraz)
bikes.statuspodporuje ibaavailable|rented|service.issue_noteje warning flag, ale bike zostava rentovatelny.- report flow pred rentom neexistuje.
- admin nema samostatnu sekciu pre "otvorene nahlasene problemove bicykle".
5) Cielovy behavior (po implementacii)
5.1 User bez aktivnej jazdy
- User klikne na
availablebike. - V rent dialogu vidi akcie:
Pozicat,Nahlasit.
- Po kliknuti
Nahlasitsa otvori bottom Drawer:- nazov bicykla,
- kratke upozornenie, ze bike bude zablokovany pre ostatnych,
- povinna
textarea, - CTA
Nahlasit bicykel.
- Po submit:
- vytvori sa report,
- bike prejde do
reported, - user dostane success banner.
5.2 Zobrazenie reported bicykla v user zozname
- stavova bodka + badge su fialove,
- text stavu:
Nahlasene, - bike nie je klikatelny pre bezneho usera,
- dovod reportu (volny text) sa beznemu userovi nezobrazuje.
5.3 Admin flow
- admin vidi list otvorenych reportov (bike, cas, nahlasil, poznamka),
- admin moze report uzavriet po fyzickej kontrole:
- povinna
resolution_note, - cielovy stav bicykla:
availablealeboservice, - report prejde do
resolved.
- povinna
- admin ma samostatnu akciu
override rentprereportedbike.
5.4 Integracia s return flow
- existujuci
return_bike(note_text)ostava zachovany, - ak ma bike otvoreny report, return nesmie prepisat stav na
available, - bike po returne ostava
reportedaz do admin resolve.
6) Datovy model (decision-complete)
6.1 Uprava public.bikes
- rozsirit
statuscheck oreported:check (status in ('available','rented','service','reported'))
Poznamka:
reportedreprezentuje nepozicatelny bike pre beznych userov.servicezostava interny servisny rezim.
6.2 Nova tabulka public.bike_reports
Navrh stlpcov:
id bigint generated by default as identity primary keybike_id bigint not null references public.bikes(id) on delete cascadereported_by uuid not null references public.profiles(id)report_note text not nullstatus text not null default 'open'(open,resolved)reported_at timestamptz not null default now()resolved_at timestamptz nullresolved_by uuid null references public.profiles(id)resolution_note text nullresolved_to_status text null(available,service)override_used boolean not null default falseoverride_used_at timestamptz nulloverride_used_by uuid null references public.profiles(id)override_note text null
Constrainty:
check (status in ('open','resolved'))check (resolved_to_status in ('available','service') or resolved_to_status is null)- partial unique index: max 1 otvoreny report na bike:
unique (bike_id) where status='open'
Indexy:
(status, reported_at desc)(bike_id, reported_at desc)(reported_by, reported_at desc)
7) API / RPC kontrakty (dokumentovane, nie implementovane)
7.1 Nove RPC
report_bike_unrentable(bike_id bigint, report_note text)- auth + allowlist required,
- bike musi byt
available, report_notenesmie byt prazdny,- ak existuje otvoreny report -> reject (
report_already_open), - insert do
bike_reports, - update
bikes.status='reported'.
admin_list_bike_reports(include_resolved boolean default false, limit_count int default 200)- admin only,
- vrati report feed (open + optional resolved).
admin_resolve_bike_report(report_id bigint, resolution_note text, target_status text default 'available')- admin only,
- report musi byt
open, resolution_notepovinna,target_status in ('available','service'),- ak bike je
rented-> reject (bike_currently_rented), - report ->
resolved, - bike status ->
target_status.
admin_override_rent_reported_bike(bike_id bigint, override_note text default null)- admin only,
- umozni admin rent aj ked bike je
reported, - zaznamena override metadata na otvorenom reporte (
override_used*).
7.2 Zmeny existujucich RPC
rent_bike(bike_id bigint)- pre bezneho usera blokovat
reportedrovnako akoservice(bike_not_available). - admin standardny
rent_bikemoze ostat strict; override ide cez samostatne RPC.
- pre bezneho usera blokovat
return_bike(note_text text)- ak bike ma otvoreny report:
- po returne ostava
status='reported', - nesmie sa vratit na
availablekym admin report neuzavrie.
- po returne ostava
- ak bike ma otvoreny report:
list_bikes_public()- vracia
statusvratanereported. - text reportu sa user endpointom neposkytuje.
- vracia
7.3 Frontend typy (plan-only)
- TS status union rozsirena o
reported:status: "available" | "rented" | "service" | "reported"
8) UI/UX navrh
8.1 User dashboard (/)
- v bike karte:
reportedma fialovy dot + badgeNahlasene,- karta je neklikatelna (pre bezneho usera).
- v rent dialogu pre
availablebike:- CTA
Pozicat, - sekundarna akcia
Nahlasit.
- CTA
Nahlasitotvori Drawer (nie druhy modal stack).
8.2 Drawer obsah
- title:
Nahlasit bicykel, - podtitle: kratke vysvetlenie nasledku (bike sa docasne zablokuje),
- povinna textarea:
- placeholder napriklad
Napr. zamok je zniceny, bike ma defekt, chyba sedlo...,
- placeholder napriklad
- validacia:
- trim,
- prazdny text -> inline chyba,
- submit button:
Nahlasit bicykel.
8.3 Admin (/admin)
Nova sekcia "Nahlasene bicykle":
- tab
Open:- bike, nahlasil, cas, report note, override flag.
- tab
Resolved(optional filter). - akcie:
Uzavriet ako dostupny,Uzavriet ako servis,Admin override rent.
9) RLS a bezpecnost
- bezny user nema direct SELECT na
bike_reports, - report text je dostupny iba adminovi cez admin RPC,
- user moze vytvorit report iba cez
report_bike_unrentable, - admin action RPC maju explicitny
is_admin()gate.
Privacy:
- report note neobsahuje osobne udaje; UI upozorni usera, aby ich nepisal.
10) Edge cases a failure modes
- Dva paralelne report requesty:
- partial unique index + transaction lock => maximalne jeden open report.
- Race report vs rent:
- report aj rent musia lockovat bike row
for update.
- report aj rent musia lockovat bike row
- Admin sa pokusi uzavriet report pocas aktivneho rentalu:
- reject, nutny najprv return.
- Admin override bez open reportu:
- reject (
no_open_report), aby audit ostal konzistentny.
- reject (
- Bike uz je
servicealeborented:- user report pred rentom zamietnuty (
bike_not_reportable_now).
- user report pred rentom zamietnuty (
11) Test plan
11.1 Funkcne
- User nahlasi
availablebike s validnou poznamkou. - Bike prejde na
reporteda user ho nemoze pozicat. - User bez textu report odoslat nevie.
- Druhy user nemoze vytvorit duplikatny open report na rovnaky bike.
- Admin vidi detail reportu a vie ho uzavriet.
- Po admin resolve na
availableje bike znova rentovatelny. - Admin override rent
reportedbike funguje a audituje sa.
11.2 Security
- Bezny user neprecita
bike_reportsdetail. - Bezny user nevie zavolat admin RPC.
- Report endpoint neprijima prazdny text.
11.3 Regression
- Existujuci
issue_notewarning flow ostava funkcny. serviceflow ostava funkcny.- Standard rent/return flow pre bike bez reportu ostava bez zmeny.
12) Rollout plan
Faza A: Schema + RPC
- pridat
reportedstatus abike_reports, - nasadit nove RPC + upravy rent/return guardov.
Faza B: User UI
- doplnit
Nahlasitflow s Drawer komponentou, - pridat fialovy status rendering.
Faza C: Admin UI
- report feed, resolve flow, override flow.
Faza D: Hardening
- regression test checklist,
- doplnit docs/checklist + changelog.
13) Naviazanie na ostatne plany
PLAN_MAPA_STANOVISTA.md: station-aware pravidla musia ratat aj sreported.PLAN_DYNAMICKY_KOD.md:code_statusareportedsu odlisne osi stavu.PLAN_STATISTIKY.md: optional KPI "pocet reported bicyklov".docs/PLAN_EMAIL_NOTIFIKACIE.md: transakcne notifikacie pre create/resolve/override eventy.
14) Predpoklady a defaulty
- Ziadna runtime implementacia v tejto faze.
- Ziadny DB release patch sa este nespusta.
- Ziadny SemVer bump ani tag.
- Zmeny su cisto dokumentacne.
On This Page
0) Stav realizacie (aktualizovane 2026-02-11)1) Ciel2) ScopeIn scopeOut of scope (v tejto faze)3) Produktove rozhodnutia (uzamknute)4) Vychodiskovy stav (teraz)5) Cielovy behavior (po implementacii)5.1 User bez aktivnej jazdy5.2 Zobrazenie reported bicykla v user zozname5.3 Admin flow5.4 Integracia s return flow6) Datovy model (decision-complete)6.1 Uprava public.bikes6.2 Nova tabulka public.bike_reports7) API / RPC kontrakty (dokumentovane, nie implementovane)7.1 Nove RPC7.2 Zmeny existujucich RPC7.3 Frontend typy (plan-only)8) UI/UX navrh8.1 User dashboard (/)8.2 Drawer obsah8.3 Admin (/admin)9) RLS a bezpecnost10) Edge cases a failure modes11) Test plan11.1 Funkcne11.2 Security11.3 Regression12) Rollout planFaza A: Schema + RPCFaza B: User UIFaza C: Admin UIFaza D: Hardening13) Naviazanie na ostatne plany14) Predpoklady a defaulty