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

Ako aplikacia funguje

PreviousNext

Centralny technicky prehlad fungovania aplikacie CVRN.

status: reference
type: reference
#architektura
#system
#flow

Migrovane z docs-old-cvrn/guides/AKO_TO_FUNGUJE.md.

Tento dokument je centralny technicky prehlad aplikacie CVRN. Ciel: na jednom mieste popisat, co appka robi, ake ma flow, ake ma pravidla pristupu, a kde je logika v kode a databaze.

Stav dokumentu: aktualizovany podla kodu k 2026-02-12.

1) Co je CVRN

CVRN je minimalisticka komunitna web appka na poziciavanie bicyklov.

Aplikacia riesi:

  • prihlasenie cez Google (Supabase Auth),
  • allowlist pristup pre clenov komunity,
  • pravidlo "1 user = max 1 aktivne pozicany bicykel",
  • user dashboard (vyber bicykla alebo aktualna jazda),
  • admin cast (allowlist, stavy bicyklov, kody, poznamky, historia),
  • statistiky komunity na route /stats,
  • verejny changelog na route /changelog.

2) Role a pristup

RolaPristupTypicke moznosti
Neprihlaseny navstevnikVerejny landing (/landing, /log, /ciele, /amnestia, /krstiny, /onboarding, /adopcia, /pravidla, /desatoro, /contact) + public route (/login, /auth/callback, /changelog)Informacie o projekte + prihlasenie
Prihlaseny mimo allowlistuRedirect na /not-authorized (fallback view existuje aj na /)Poziadat o aktivaciu
Prihlaseny allowlisted userDashboard /, statistiky /statsPozicat/vratit bicykel, vidiet community stats
AdminVsetko ako allowlisted user + /adminSpravovat allowlist, bicykle, historiu

3) Route mapa (co je kde)

  • /login
    • Google OAuth login.
    • Informacia o pravidlach komunity a spracuvani osobnych udajov.
  • /auth/callback
    • OAuth callback, vymena code za session.
  • /
    • Hlavny dashboard.
    • Stav A: user nema bicykel -> zoznam bicyklov + rent dialog.
    • Stav B: user ma bicykel -> karta "Aktualna jazda" + kod zamku + return formular.
  • /stats
    • 3 komunitne grafy za vybrany mesiac + month switcher.
    • Pristup iba pre allowlisted usera.
  • /admin
    • Admin panel (allowlist, bicykle, historia jazd).
    • Pristup iba pre admina.
  • /not-authorized
    • Stranka pre usera mimo allowlistu.
  • /changelog
    • Verejna stranka citajuca docs/CHANGELOG.md.
  • /landing, /log, /ciele, /amnestia, /krstiny, /onboarding, /adopcia, /pravidla, /desatoro, /contact
    • Verejny obsah pre landing web.
    • Primarne obsluhovany na hoste cvrn.sk/www.cvrn.sk.

4) Hlavicka, paticka, globalne UI spravanie

  • Hlavicka (SiteHeader):
    • brand logo (SVG 32px, light/dark varianta) + text cvrn.sk (link na /, hover/focus reveal na desktope),
    • Toggle Mode (light/dark) + klavesa D,
    • ikona statistik (link /stats),
    • cervene tlacidlo Pomoc (mailto),
    • Admin tlacidlo iba pre admina,
    • Odhlasit.
  • Tlacidlo Pomoc ma dynamicky predmet:
    • ak ma user aktivny bicykel: Problem s bicyklom: <nazov>,
    • inak vseobecny predmet.
  • Paticka (SiteFooter):
    • zobrazi verziu appky vX.Y.Z,
    • verzia je link na /changelog.
  • Theme:
    • default podla localStorage / system preference,
    • prepina sa tlacidlom alebo klavesou D (mimo input/textarea/select).

5) User flow podrobne

5.1 Login flow

  1. User otvori /login.
  2. Klikne Prihlasit sa cez Google.
  3. OAuth redirect ide cez Supabase.
  4. /auth/callback dokonci session.
  5. Middleware pusti usera dalej podla stavu pristupu.

5.2 User mimo allowlistu

  • Primarny flow: middleware redirectne usera na /not-authorized.
  • Fallback v dashboard kode: existuje aj cakaren karta "Ucet caka na aktivaciu" s CTA mailto.

5.3 Dashboard: user nema pozicany bicykel

Zobrazi sa zoznam bicyklov z RPC list_bikes_public().

  • Stavy bicykla:
    • available (dostupny),
    • rented (pozicany),
    • service (v servise),
    • issue_note zapina warning variant.
  • Klikatelny je iba available bike.
  • Klik otvori dialog "Pozicat bicykel".

Rent dialog obsahuje:

  • text: Chcete si pozicat bicykel <nazov>?,
  • obrazok bicykla,
  • warning panel s issue_note (ak existuje),
  • spodne iba tlacidlo Pozicat (zavretie je cez krizik vpravo hore).

Obrazok bicykla v dialogu:

  • nacitava sa zo statickeho suboru public/<nazov-bicykla>.png,
  • URL sa sklada z mena bicykla + .png (encodeURIComponent pre bezpecne znaky),
  • kontajner je stvorcovy (aspect-square) a obrazok sa oreze cez object-cover,
  • ak subor neexistuje, zobrazi sa fallback hlaska (nie rozbity image).

5.4 Pozicanie bicykla (mutacia)

  • Formular vola rentBikeAction.
  • Action vola RPC rent_bike(bike_id).
  • DB pravidla idu cez centralny transition guard model (bike_transition_guard + bike_transition_apply):
    • user musi byt prihlaseny,
    • user musi byt allowlisted,
    • user nesmie mat iny aktivny rental,
    • bike musi existovat a byt available.
  • Pri uspechu:
    • bicykel ide do rented,
    • naplni sa current_user_id,
    • vytvori sa zaznam v rentals,
    • action spravi revalidatePath("/") a revalidatePath("/stats").

5.5 Dashboard: user ma pozicany bicykel

Zobrazi sa karta "Aktualna jazda":

  • nazov bicykla,
  • kod zamku (secret_code),
  • pripomienka na ocistenie bicykla a reset kodu na 0000,
  • volitelna poznamka pre servis,
  • tlacidlo Vratit bicykel.

Dolezite:

  • v aktualnej jazde sa obrazok bicykla uz nezobrazuje,
  • v admin casti sa obrazok bicykla tiez nezobrazuje.

5.6 Vratenie bicykla (mutacia)

  • Formular vola returnBikeAction.
  • Action vola RPC return_bike(note_text).
  • DB update ide cez rovnake centralne transition guard jadro:
    • bike -> available,
    • current_user_id = null,
    • aktivny rental dostane returned_at = now(),
    • ak je poznamka, ulozi sa do rentals.return_note a tiez do bikes.issue_note.
  • Action revaliduje / aj /stats.

6) Statisticka stranka /stats

Route zobrazuje 3 grafy za vybrany mesiac (timezone Europe/Bratislava). Vpravo hore je month switcher (Select) a stav mesiaca je v URL:

  • /stats?month=YYYY-MM
  • ak month chyba alebo je neplatny, fallback je aktualny mesiac.

Select obsahuje:

  • aktualny mesiac (vzdy),
  • historicke mesiace od prveho mesiaca s datami.
  1. Vypozicky po dnoch
  • denny graf pre vybrany mesiac,
  • metrika Celkovo za vybrany mesiac,
  • tooltip Vypozicky: X.
  1. Vypozicky podla bicykla
  • horizontalne bary pre bicykle,
  • sumar vybraneho mesiaca + najviac vyuzivany bicykel.
  1. Najaktivnejsi cyklista
  • radial graf podielu top cyklistu,
  • pocet vypoziciek top cyklistu za vybrany mesiac,
  • zoznam dalsich cyklistov.

Data berie stranka cez RPC:

  • stats_get_monthly_daily_rentals(...),
  • stats_get_monthly_rentals_by_bike(...),
  • stats_get_monthly_rentals_by_cyclist(...).
  • stats_get_available_months(...).

Ak stats RPC chybi alebo zlyha, UI zobrazi error banner s hintom na patchy:

  • 003 a 004 (hlavne mesacne agregacie),
  • 008 (zoznam mesiacov pre switcher).

7) Admin flow /admin

Admin panel ma 3 casti:

  1. Allowlist
  • pridanie e-mailu,
  • odobratie e-mailu.
  1. Bicykle
  • prehlad stavu a poznamok,
  • edit secret_code,
  • prepnutie service <-> available (nie pri rented),
  • vymazanie issue_note.
  1. Historia jazd
  • poslednych 200 zaznamov,
  • user, bike, rented_at, returned_at, return_note.
  1. Admin zasahy (audit trail)
  • poslednych 200 admin operacii,
  • akcie: zmena kodu, zmena stavu, vymazanie poznamky,
  • doplnene akcie pre PUK flow:
    • uspesne zobrazenie historie kodov,
    • neuspesne overenie PUK.
  1. Historia kodov bicykla (PUK)
  • pri zmene kodu sa predchadzajuci kod ulozi do historie pre dany bicykel,
  • v audite pri "Zmena kodu" je tlacidlo Historia kodov,
  • po kliknuti sa otvori centrovany modal so 6-policovym PUK inputom,
  • po uspesnom overeni PUK sa zobrazi cely historicky zoznam starych kodov pre dany bicykel (cas, admin, kod).

Admin akcie idu cez server actions a bike mutacie pouzivaju jednotny DB transition guard:

  • adminAddAllowedEmailAction,
  • adminRemoveAllowedEmailAction,
  • adminUpdateBikeCodeAction,
  • adminSetBikeStatusAction,
  • adminClearBikeNoteAction.

8) Datovy model (Supabase)

Tabulky:

  • profiles - profil usera (is_admin, email),
  • bikes - aktualny stav bicykla (status, secret_code, current_user_id, issue_note),
  • rentals - historia vypoziciek,
  • allowed_emails - allowlist.
  • admin_operations - audit admin operacii.
  • bike_code_history - historia starych kodov po zmene kodu bicykla.
  • admin_puk_config - hash PUK kodu pre overenie zobrazenia historie.

Hard pravidla v DB (indexy/constraints):

  • bikes_status_check: iba available|rented|service,
  • max 1 aktivny rental na usera (rentals_one_active_per_user),
  • max 1 aktivny rental na bicykel (rentals_one_active_per_bike),
  • bikes.current_user_id je unikatny pre aktivne priradenie (bikes_one_user_one_bike).

Automaticke zalozenie profilu:

  • trigger handle_new_user() vytvori profil po prvom prihlase,
  • prvy user v systeme sa stane adminom,
  • prvy user sa automaticky prida do allowed_emails.

9) RPC katalog (biznis logika)

Auth/role helpery:

  • is_admin()
  • is_allowed()

User-safe read RPC:

  • list_bikes_public()
  • get_my_bike()

Mutacne RPC:

  • rent_bike(bike_id)
  • return_bike(note_text)

Admin RPC:

  • admin_list_rentals(limit_count)
  • admin_list_operations(limit_count)
  • admin_update_bike_code(bike_id, new_secret_code, reason_text)
  • admin_set_bike_status(bike_id, next_status, reason_text)
  • admin_clear_bike_note(bike_id, reason_text)
  • admin_reveal_bike_code_history(p_bike_id, p_puk_code)

Stats RPC:

  • stats_get_monthly_daily_rentals(month_start, tz)
  • stats_get_monthly_rentals_by_bike(month_start, tz)
  • stats_get_monthly_rentals_by_cyclist(month_start, tz)
  • stats_get_available_months(tz)

10) Bezpecnostny model

Klucove pravidlo: bezny user nesmie vidiet kody zamkov vsetkych bicyklov.

Ako je to spravene:

  • RLS povoluje direct SELECT/UPDATE na citlive tabulky iba adminovi,
  • bezny user cita iba cez security-definer RPC,
  • list_bikes_public() vracia verejne data bez secret_code,
  • get_my_bike() vracia secret_code iba pre bike, ktory ma aktualny user pozicany,
  • mutacie idu cez server action -> RPC, nie priamo z klienta.

11) Middleware pravidla

middleware.ts kontroluje:

  • host-based flow:
    • cvrn.sk a www.cvrn.sk -> landing (root / sa rewrite na /landing),
    • app route na apex hoste sa redirectuju na app.cvrn.sk.
  • na app hoste (app.cvrn.sk) standardne auth pravidla:
    • session (neprihlaseny -> /login),
    • allowlist (is_allowed),
    • admin route (/admin len pre admina),
    • public route ostavaju dostupne bez auth.

12) Kde je co v kode

Hlavne stranky:

  • src/app/page.tsx
  • src/app/login/page.tsx
  • src/app/stats/page.tsx
  • src/app/admin/page.tsx
  • src/app/not-authorized/page.tsx
  • src/app/changelog/page.tsx
  • src/app/landing/page.tsx
  • src/app/log/page.tsx
  • src/app/ciele/page.tsx
  • src/app/amnestia/page.tsx
  • src/app/krstiny/page.tsx
  • src/app/onboarding/page.tsx
  • src/app/adopcia/page.tsx
  • src/app/pravidla/page.tsx
  • src/app/desatoro/page.tsx
  • src/app/contact/page.tsx

Klucove komponenty:

  • src/app/_components/bike-list.tsx (zoznam + rent dialog + obrazok)
  • src/components/site-header.tsx
  • src/components/site-footer.tsx
  • src/components/theme-toggle.tsx

Server a auth vrstva:

  • src/app/actions.ts (server actions)
  • src/lib/supabase/server.ts
  • src/lib/supabase/browser.ts
  • src/lib/supabase/middleware.ts
  • middleware.ts

DB a patchy:

  • supabase/schema.sql
  • supabase/seed.sql
  • supabase/patches/001_fix_rent_bike.sql
  • supabase/patches/002_fix_rent_bike_ambiguous_id.sql
  • supabase/patches/003_add_stats_rpc.sql
  • supabase/patches/004_add_monthly_cyclist_stats.sql
  • supabase/patches/005_add_admin_operations_rpc.sql
  • supabase/patches/006_add_puk_code_history.sql
  • supabase/patches/007_add_bike_transition_guard_model.sql

13) Staticke assety pre bicykle (obrazky)

Miesto:

  • public/

Pravidlo nazvu:

  • presne public/<nazov-bicykla-z-db>.png

Priklad:

  • ak je v DB nazov bicykla Vendelin, subor je public/Vendelin.png;
  • ak je v DB nazov bicykla Vendelín, subor je public/Vendelín.png.

Odporucanie:

  • drzat presnu zhodu nazvu s hodnotou bikes.name (vratane diakritiky),
  • ak sa bike premenuje v DB, premenuj aj subor v public/.

14) Prevadzkove poznamky

  • Potrebne env premenne:
    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY
  • Pre plne stats je nutne mat patchy 003 a 004.
  • Pre centralny bike transition guard model je nutne mat patch 007 (ak nebezis fresh install zo schema.sql).
  • Changelog release informacie su v docs/CHANGELOG.md.
  • Release pravidla (SemVer) su v docs/VERSIONING.md.

15) Mental model na zapamatanie

Jedna veta:

"Next.js riesi UI a flow; Supabase riesi identitu, data a tvrde pravidla."

Ak menis funkcionalitu, vzdy si rozdel zmenu na 3 vrstvy:

  • UI/UX (React komponenty),
  • orchestrace (server actions + redirect/revalidate),
  • data pravidla (RPC + RLS + indexy/constraints).
Struktura repozitaraDiagramy

On This Page

1) Co je CVRN2) Role a pristup3) Route mapa (co je kde)4) Hlavicka, paticka, globalne UI spravanie5) User flow podrobne5.1 Login flow5.2 User mimo allowlistu5.3 Dashboard: user nema pozicany bicykel5.4 Pozicanie bicykla (mutacia)5.5 Dashboard: user ma pozicany bicykel5.6 Vratenie bicykla (mutacia)6) Statisticka stranka /stats7) Admin flow /admin8) Datovy model (Supabase)9) RPC katalog (biznis logika)10) Bezpecnostny model11) Middleware pravidla12) Kde je co v kode13) Staticke assety pre bicykle (obrazky)14) Prevadzkove poznamky15) Mental model na zapamatanie
© CVRN dokumentacia