Architektura a flow
Aktualizováno: 2025-12-07
Přehled
- Next.js 14 (App Router) + TypeScript.
- Datová vrstva:
lib/persistenceje jediný vstup do databáze (lokální Postgres přesLOCAL_DATABASE_URLnebo Supabase; dev fallback in-memory). Supabase je používán jen pro auth a synchronizaci. - Synchronizace:
npm run sync:pushčte lokální DB (Pool) a upsertuje do Supabase pomocí service role. - Pull sync:
npm run sync:pullstáhne rooms/codes/room_messages ze Supabase (service role) a upsertne je do lokální DB – použij pro dorovnání nových zpráv z cloudu do lokální instance. - Ad-hoc pull zpráv: při načtení zpráv (
getMessagesByRoom) se při dostupné service role pokusíme stáhnout nové zprávy dané místnosti ze Supabase a upsertnout je do lokální DB, aby se příchozí cloudové zprávy propsaly i do lokálního úložiště. - Offline klient:
lib/offlineStore(IndexedDB) ukládá zprávy a pending frontu;lib/messagespři výpadku sítě ukládá zprávy lokálně a po návratu online volá/api/sync/pushk jejich uložení do persistence/Supabase. - Session: anonymní session v HTTP-only cookie (
setAnonymousSession); Supabase auth pro registrované uživatele. - Logging:
lib/loggerzapisuje do lokální DB (logs), při nedostupnosti do Supabase service-role nebo konzole. ÚroveňLOG_LEVEL=all|light|mini|off. - Rate limiting:
lib/rateLimiter(paměťový bucket) blokuje brute-force pro kódy/PIN (IP+device). Rozšiřitelné i na další endpoints.
Datový model (shrnutí)
- Viz
docs/DATAMODEL.mda SQL vsrc/db/localSQLcreate.sql/src/db/supabaseSQLcreate.sql. - Tabulky:
users,rooms,codes,room_messages,logs.
Hlavní flow
Zadání/ověření kódu
/api/codes/validate: ověřuje kód (persistence), větví na setup/pin/room; rate-limit IP+device; ukládá/čte anonymní session hash; logujevalidate_*./api/codes/setup: pro nepoužitý kód vytvoří pár, místnost, označí used; ukládá PIN hash nebo session hash; logujesetup./api/codes/enter: pro použitý kód zajistí linked code, případně založí room; označí used; logujeenter./api/codes/verify-pin: ověří PIN, nastaví session, logujeverify_pin_success; rate-limit./api/users/transfer-code: převede kód k přihlášenému uživateli, logujetransfer_to_user.
Místnosti a chat
/api/rooms/[roomId]: CRUD nad místností přes persistence (vč. vlastnictví přes kód.user_id); loguje get/update/delete./api/messages/[roomId]: čte a ukládá zprávy přes persistence, aktualizujerooms.date_last_message, loguje insert. Chat klient (components/chat/ChatRoom) používá tuto API a polling, bez přímého Supabase klienta.
Kódy a páry
lib/codes.createCodePairgeneruje dvojici a kontroluje unikátnost přes persistence (ne Supabase přímo).persistence.getCodeWithLinkedvrací primární + spárovaný kód;updateCodesRoomIdzapisuje room_id pro obě strany.
Synchronizace a prostředí
- Lokální DB:
LOCAL_DATABASE_URL; initnpm run db:local:init(vytvoří ilogs). - Supabase:
NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY(auth),SUPABASE_SERVICE_ROLE_KEYpro sync/log fallback. - Sync:
src/lib/syncLocalToSupabase.tsupsertuje rooms, codes, room_messages. - Pull:
src/lib/syncSupabaseToLocal.tsupsertuje rooms, codes, room_messages z cloudu do lokální DB; ad-hoc sync zpráv se volá zgetMessagesByRoom.
Logging a observabilita
- Úrovně:
all(včetně UA+data),light(bez UA),mini(bez UA+data),off. - Záznam: module, operation, data (JSON), error, ip, user_agent, lang, level.
- Tabulka
logsv obou SQL skriptech; RLS v Supabase dovoluje pouze service role.
Bezpečnost a limity
- Rate limiter pro kódy/PIN (3 pokusy/5 min/IP+device, 5min blok; po 3 blocích 24h). Doporučeno přidat i na login/register až budou implementované.
- Session hash: anonymní uživatelé dostávají dlouhou/krátkou expiraci dle PIN, uloženou v DB i cookie.
Frontend
- App Router stránky v
src/app; sdílené komponentysrc/components. - Chat běží přes API messages; UI layouty dle
doc/design(vizdocs/GITHUB_INSTRUCTIONS.md).