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

Mapa a stanovista

PreviousNext

Plan mapoveho modulu, stanovist a alokacie bicyklov.

status: planned
type: plan
#plany
#mapa
#stanovista

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

1) Ciel

Pridat mapovy modul so stanovistami tak, aby:

  • appka vedela evidovat, kde sa bicykel fyzicky nachadza,
  • mapa zobrazovala stanovistia s poctom bicyklov,
  • servisne stanoviste bolo pre bezneho usera "return only",
  • admin mohol robit aj rent zo servisneho stanovista,
  • riesenie bolo bez platenej mapovej sluzby.

2) Scope

In scope

  • 2 bezne stanovistia + 1 servisne stanoviste,
  • geolokacia stanovist (lat, lng),
  • mapova stranka /map,
  • prepojenie rent/return flow na stanovistia,
  • agregacie poctov bicyklov pre marker ikony,
  • admin sprava stanovist.

Out of scope (v tejto etape)

  • live GPS tracking bicyklov,
  • geofencing,
  • route planning a navigacia.

3) Navrhovana architektura (high level)

  1. Datovy model sa rozsiri o tabulku stanovist.
  2. Bicykel bude mat aktualne stanoviste, ked nie je rented.
  3. Pri return sa vyberie cielove stanoviste.
  4. API vrstva (RPC) vrati:
    • zoznam stanovist,
    • map summary (pocty bicyklov na stanovisku),
    • station-aware rent/return.
  5. Frontend:
    • nova /map stranka s OpenStreetMap + Leaflet,
    • marker ikony podla poctov a typu stanovista.

4) Datovy model (decision-complete)

4.1 Nova tabulka public.stations

Stlpce:

  • id bigint generated by default as identity primary key
  • code text not null unique (napr. A, B, SERVIS)
  • name text not null
  • kind text not null (public, service)
  • lat numeric(9,6) not null
  • lng numeric(9,6) not null
  • is_active boolean not null default true
  • allow_user_rent boolean not null default true
  • allow_user_return boolean not null default true
  • created_at timestamptz not null default now()
  • updated_at timestamptz not null default now()

Constraint:

  • check (kind in ('public','service'))

Default business pravidla:

  • pre public: allow_user_rent=true, allow_user_return=true
  • pre service: allow_user_rent=false, allow_user_return=true

4.2 Uprava tabulky public.bikes

Pridat:

  • station_id bigint null references public.stations(id) on delete set null

Constraint (dolezite):

  • ak status='rented', tak station_id is null
  • ak status in ('available','service'), tak station_id is not null

Realizacia:

  • check constraint bikes_station_status_check.

4.3 Uprava tabulky public.rentals

Pridat:

  • start_station_id bigint null references public.stations(id) on delete set null
  • return_station_id bigint null references public.stations(id) on delete set null

Vyuzitie:

  • pri rent ulozit odkial bicykel odchadza,
  • pri return ulozit kam bol vrateny.

4.4 Nova audit tabulka public.bike_station_events (odporucane)

Stlpce:

  • id bigint generated by default as identity primary key
  • bike_id bigint not null references public.bikes(id) on delete cascade
  • event_type text not null (rent, return, admin_move)
  • from_station_id bigint null references public.stations(id) on delete set null
  • to_station_id bigint null references public.stations(id) on delete set null
  • rental_id bigint null references public.rentals(id) on delete set null
  • performed_by uuid not null references public.profiles(id)
  • created_at timestamptz not null default now()
  • note text null

5) API/RPC zmeny

5.1 Nove RPC

  1. list_stations_public()
    • vrati aktivne stanovistia bez admin-only detailov.
  2. get_map_station_summary()
    • vrati pre kazde stanoviste:
      • station_id, code, name, kind, lat, lng,
      • total_count (bicykle fyzicky na stanovisti, nie rented),
      • rentable_count_user,
      • service_count,
      • note_count (available + issue_note).
  3. return_bike_to_station(return_station_id bigint, note_text text)
    • nahradi/rozsiri dnesny return_bike.
    • valida:
      • station existuje a je active,
      • pre bezneho usera allow_user_return=true.
    • update:
      • bike status='available', current_user_id=null, station_id=return_station_id,
      • rental returned_at, return_station_id.
    • optional:
      • zapis issue_note,
      • insert bike_station_events.
  4. rent_bike_from_station(bike_id bigint, station_id bigint)
    • valida:
      • bike je na danom stanovisti (bikes.station_id = station_id),
      • bike je available,
      • user ma pristup,
      • pre bezneho usera station musi mat allow_user_rent=true.
    • update:
      • bike status='rented', current_user_id=uid, station_id=null,
      • rental insert so start_station_id,
      • event insert.
  5. admin_list_stations() + admin_upsert_station(...)
    • CRUD pre admin spravu stanovist.

5.2 Zmeny existujucich RPC

  • list_bikes_public():
    • doplnit station_id, station_code, station_name.
  • get_my_bike():
    • doplnit posledne/start stanoviste podla potreby UI.
  • rent_bike():
    • bud deprecate, alebo nech interne vola station-aware variant.

6) UI/UX zmeny

6.1 Nova stranka /map

Technologia:

  • Leaflet + react-leaflet
  • mapove podklady: OpenStreetMap tile layer.

Marker vizualna logika:

Public stanoviste marker

  • farba zelena: rentable_count_user > 0
  • farba seda: total_count = 0
  • farba oranzova: total_count > 0 ale rentable_count_user = 0
  • badge text:
    • default rentable_count_user
    • sekundarny text total_count.

Priklad:

  • A ma 3 available -> zelena ikona s "3"
  • B ma 2 available -> zelena ikona s "2"
  • A ma 5 a B ma 0 -> A zelena "5", B seda "0"

Servisne stanoviste marker

  • farba modra/slate (vizualne odlisene),
  • ikona "service" + pocet bicyklov,
  • label "Servis (return only)" pre usera,
  • admin vidi "Servis (admin rent allowed)".

Popup obsah

Pre kazde stanoviste:

  • nazov + kod,
  • pocet bicyklov (total),
  • dostupne na rent pre usera (rentable_count_user),
  • link na zoznam bicyklov zo stanovista.

6.2 Dashboard /

Zoznam bicyklov:

  • pridat info "Stanoviste: A/B/SERVIS".
  • bicykel na servisnom stanovisti:
    • pre bezneho usera neklikatelny rent,
    • pre admina klikatelny.

Return flow:

  • formular pri vrateni obsahuje vyber cieloveho stanovista:
    • user: iba allow_user_return=true aktivne stanovistia,
    • admin: vsetky aktivne stanovistia.

6.3 Admin /admin

Pridat sekciu "Stanovistia":

  • create/edit station (name, kind, lat, lng, flags),
  • deactivate station,
  • prehlad occupancy (sumar).

7) RLS a bezpecnost

Stanovistia

  • bezny user:
    • select len active stations cez RPC/public view.
  • admin:
    • full CRUD.

Bicykle + station access

  • bezny user nemoze priamo update station.
  • vsetky presuny iba cez RPC (rent/return/admin_move).

Audit

  • kazdy move zapisat do bike_station_events.
  • dolezite pre riesenie "kde bike naposledy bol".

8) Migracny plan

Faza 1: Schema + read-only mapa

  1. SQL:
    • vytvor stations,
    • pridaj bikes.station_id,
    • dopln default stations A/B/SERVIS,
    • namapuj existujuce available/service bicykle na default station A.
  2. RPC:
    • list_stations_public, get_map_station_summary.
  3. UI:
    • /map read-only marker summary.

Outcome:

  • mapa je viditelna, data konzistentne, bez zmeny rent/return flow.

Faza 2: Station-aware rent/return

  1. SQL:
    • rentals.start_station_id, return_station_id,
    • bike_station_events.
  2. RPC:
    • rent_bike_from_station, return_bike_to_station.
  3. UI:
    • rent validacia podla station policy,
    • return vyber stanovista.

Outcome:

  • system realne riadi pohyb bicyklov medzi stanovistami.

Faza 3: Admin station management + polish

  1. Admin CRUD stanovist.
  2. Occupancy dashboard.
  3. Edge-case handling (deaktivacia station, fallback moves).

Outcome:

  • plna operacna kontrola bez SQL zasahu.

9) Konkretny dopad na existujuce subory

Backend/DB:

  • supabase/schema.sql
  • nove migration patch subory v supabase/patches/

Frontend:

  • src/app/page.tsx (station info, return station select)
  • src/app/actions.ts (nove action pre station-aware RPC)
  • src/app/admin/page.tsx (stanovistia CRUD)
  • nova src/app/map/page.tsx
  • nove komponenty:
    • src/app/_components/station-map.tsx
    • src/app/_components/return-station-select.tsx

Routing/middleware:

  • middleware.ts bez velkej zmeny (auth/allowlist ostava).

10) Test plan

Funkcne testy

  1. User vidi mapu s 2 public + 1 service station.
  2. Marker count sedí s DB stavom.
  3. User rent z A/B funguje.
  4. User rent zo service je blokovany.
  5. Admin rent zo service funguje.
  6. User return na service funguje.
  7. Po return sa marker count aktualizuje.
  8. Rental historia obsahuje start/return station.

Edge cases

  1. Pokus return na neaktivne stanoviste -> reject.
  2. Dva paralelne rent requesty na rovnaky bike -> jeden uspeje.
  3. Station delete/deactivate s bike-mi -> blokovat alebo vyzadovat presun.

11) Performance a free map limity

Default:

  • OpenStreetMap tiles (bezplatne) + rozumna frekvencia requestov.
  • pre malu komunitu je to v poriadku.

Odporucanie:

  • nepreloadovat zbytocne tile zoomy,
  • drzat mapu len na 1 stranke,
  • pri raste navstevnosti zvazit vlastny tile cache.

12) Default rozhodnutia (uzamknute)

  1. Pri starte budeme mat 3 stanovistia:
    • A (public),
    • B (public),
    • SERVIS (service, return-only pre usera).
  2. User moze vratit bike aj na SERVIS.
  3. User nemoze rentovat bike zo SERVIS.
  4. Admin moze rentovat zo SERVIS.
  5. Marker bude primarne zobrazovat rentable_count_user.

13) Implementacne poradie (kratky backlog)

  1. DB schema migracie pre stations + station_id.
  2. Map summary RPC + read-only /map.
  3. Rent/return station-aware RPC + actions.
  4. Return UI s vyberom stanovista.
  5. Admin station management.
  6. Testy + rollout na malej skupine.

14) Kompatibilita s planom reported bicykla

Pri implementacii planu PLAN_NAHLASENE_NEPOZICATELNE_BIKY.md je potrebne rozsirit mapovy status model:

  • constraints a valida pravidla musia ratat aj so stavom reported,
  • station-aware rent pre bezneho usera musi reported blokovat,
  • map summary ma vediet vratit aj pocet reported bicyklov na stanovisti,
  • UI marker/popup logika musi rozlisit "nedostupny pre report" vs "service".
Dynamicky kod a historiaStatistiky a historia jazd

On This Page

1) Ciel2) ScopeIn scopeOut of scope (v tejto etape)3) Navrhovana architektura (high level)4) Datovy model (decision-complete)4.1 Nova tabulka public.stations4.2 Uprava tabulky public.bikes4.3 Uprava tabulky public.rentals4.4 Nova audit tabulka public.bike_station_events (odporucane)5) API/RPC zmeny5.1 Nove RPC5.2 Zmeny existujucich RPC6) UI/UX zmeny6.1 Nova stranka /mapPublic stanoviste markerServisne stanoviste markerPopup obsah6.2 Dashboard /6.3 Admin /admin7) RLS a bezpecnostStanovistiaBicykle + station accessAudit8) Migracny planFaza 1: Schema + read-only mapaFaza 2: Station-aware rent/returnFaza 3: Admin station management + polish9) Konkretny dopad na existujuce subory10) Test planFunkcne testyEdge cases11) Performance a free map limity12) Default rozhodnutia (uzamknute)13) Implementacne poradie (kratky backlog)14) Kompatibilita s planom reported bicykla
© CVRN dokumentacia