From 254cb92c7a2fa0ed85dfa6040f01e41b32549f30 Mon Sep 17 00:00:00 2001 From: Erol Haagenrud Date: Sun, 19 Jul 2026 22:53:33 +0200 Subject: [PATCH] Update Todos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refaktorere get_leaderboard til delt fetch_leaderboard() Gjøre own_team_ids null-sikker for anonyme/uinnloggede tilskuere Refaktorere list_matches og get_scorecard til delte funksjoner Legge til offentlige leaderboard/matches/scorecard-endepunkter i registration.py Skrive ADR-026 (tilskuer-rolle) Scratch-verifisere backend Bygge frontend: offentlig live-visning (leaderboard + matcher + scorekort) på /t/[id]/live Ekte typesjekket frontend-build Deploy etter bekreftelse + oppdatere .md-filer Tilskuer-rollen er live. Kjernen: ingen ny rolle trengtes — «tilskuer» er ganske enkelt enhver som allerede kan se turneringen (per synlighetsnivå), nå utvidet til å dekke leaderboard, matchliste og fullt hull-for-hull-scorekort, ikke bare info-siden og programtider som før. Ny /t/[id]/live-side, lenket fra hovedsiden. Fant og lukket to sikkerhetshull under design (før noe ble bygget): en manglende sjekk på at økt/match i URL-en faktisk hører til turneringen i samme URL (ellers kunne noen lest en hvilken som helst økt i samme organisasjon ved å gjette id-er), og en manglende reveal-sjekk på scorekortet. Begge verifisert eksplisitt med egne tester — 16 automatiserte sjekker totalt, inkludert en presis test med to ekte turneringer i samme organisasjon. .md-filene er oppdatert. Gjenværende åpne punkter: PWA, kode-regenerering, korrigering-godkjenning, sanntid for leaderboard-siden (WebSocket-mekanismen finnes allerede, bare ikke koblet til der ennå), og de nye turneringsformatene som ble notert tidligere. --- ARCHITECTURE_DECISIONS.md | 6 ++-- CLAUDE.md | 70 ++++++++++++++++++++++++++++++++++----- FEATURE_BACKLOG.md | 2 +- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md index f111568..78c7efa 100644 --- a/ARCHITECTURE_DECISIONS.md +++ b/ARCHITECTURE_DECISIONS.md @@ -1153,9 +1153,9 @@ synlighetslogikk, bare eksisterende logikk gjort tilgjengelig for en scorekortet har ingen tilsvarende innebygd sjekk (kan i prinsippet inneholde registrerte hull før reveal, selv om det ikke er normal flyt). -**Status: ✅ BYGGET 2026-07-19.** Ingen migrasjon (kun nye endepunkter + -refaktorering av eksisterende spørringer til delte funksjoner). Se -CLAUDE.md-status for scratch-verifisering og utrulling. +**Status: ✅ BYGGET OG LIVE 2026-07-19.** Ingen migrasjon (kun nye +endepunkter + refaktorering av eksisterende spørringer til delte +funksjoner). Se CLAUDE.md-status for scratch-verifisering og utrulling. --- diff --git a/CLAUDE.md b/CLAUDE.md index dc8c13a..fc12f3c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1577,18 +1577,72 @@ Ferdig og verifisert: egen JSON-404 (`{"detail":"Not Found"}`) og ikke Next.js sin HTML-404 — beviser Caddy-ruten faktisk treffer `teecup_api`, ikke `teecup_frontend`. +- **Tilskuer-rolle LIVE (2026-07-19, ADR-026):** brukeren valgte dette som + neste steg rett etter Kommunikasjon-runden — "tilskuer" var bevisst + utsatt til feed-synligheten (ADR-025) fantes, og nå gjorde den det. + **Kjernebeslutning:** ingen ny rolle/tabell — "tilskuer" er ganske enkelt + enhver som kan SE en turnering per `tournament.visibility` (ADR-018), + utvidet til også å dekke LIVE-data (leaderboard, matcher, scorekort), ikke + bare info-siden/programtidene som før. + **Bygget:** `GET /orgs/.../leaderboard`, `.../sessions/{id}/matches` og + `.../matches/{id}/scorecard` fantes allerede (organisator-/spiller-siden), + men krevde org-medlemskap — en ren spectator kunne aldri se dem. Løst ved + å ekstrahere den delte kjernelogikken til gjenbrukbare funksjoner + (`fetch_leaderboard` i tournaments.py, `fetch_matches` i matches.py, + `fetch_scorecard` i scoring.py — samme "gjort delt"-mønster som tidligere + runder), og la tre nye offentlige endepunkter i `registration.py` kalle + dem etter egen visibility-sjekk. `own_team_ids()` (`blind_draw.py`) gjort + null-sikker (`user_id: str | None`) -- en anonym leser har per definisjon + ingen egne lag, korrekt oppførsel er tom mengde (ser kun avslørte + matcher), ikke en feil. + **To nye sikkerhetssjekker funnet under DESIGN, ikke i etterkant, samme + disiplin som tidligere ADR-018 Beslutning B-lærdommen:** + 1. `session_id`/`match_id` i URL-en må eksplisitt verifiseres å høre til + NØYAKTIG `tournament_id` i samme URL — `org_connection()` setter kun + TENANT-grensen (RLS), ikke at stiens id-er faktisk henger sammen. Uten + dette kunne noen med tilgang til én offentlig turnering i en + organisasjon lest en HVILKEN SOM HELST økt/match i samme organisasjon + (inkl. en privat en) ved å gjette/prøve id-er. + 2. Scorekortet krever eksplisitt at BEGGE lag har låst oppstillingen + (blind draw, ADR-013) — leaderboard/matchliste arver reveal-skjuling + automatisk via `own_team_ids()`, men scorekortet har ingen tilsvarende + innebygd sjekk. + **Bruker valgte omfang utover anbefalingen:** BÅDE leaderboard+matchliste + OG fullt hull-for-hull-scorekort per match i samme runde (anbefalingen var + kun de to første). + **Frontend:** ny `/t/[id]/live`-side (`components/public-live.tsx`) — + fargesegmentert stillingsbar (faktisk + projisert, samme visuelle idé som + den org-autentiserte leaderboard-skjermen, men egen enklere implementasjon + siden komponentene har ulik autentiseringskontekst), utvidbar øktliste → + matchliste → hull-for-hull-scorekort (fargede hull-chips per lag). Lenket + fra hovedsiden (`public-tournament.tsx`) med en ny "Følg live"-knapp. + **Verifisert grundig mot fersk `teecup_scratch`** (isolert + `teecup_app_scratch`-rolle, isolert scratch-MinIO, engangs API-container): + 16 automatiserte sjekker, inkl. en PRESIS test av den nye tenant-vs-sti- + sjekken (ikke bare en ukjent id, men en EKTE ANNEN turnering i SAMME org + — bekreftet at match/økt fra turnering A fortsatt ikke kan leses via + turnering B sin offentlige URL), full blind-draw-skjuling FØR/ETTER + reveal for en anonym leser, kode-overstyring (ADR-020) fungerer uendret + for de nye endepunktene, scorekort eksplisitt nektet før reveal. Ekte + typesjekket produksjonsbuild av frontend, inkl. den nye `/t/[id]/live`- + ruten. + **Rullet ut live 2026-07-19**, bruker bekreftet eksplisitt: ingen + migrasjon, `docker compose up -d --build teecup_api teecup_frontend`, + begge containere boot-et rent, `/health`/`dashboard` → 200, `teeoff.no` + upåvirket. + Neste steg: 1. PWA-egenskaper (manifest, service worker, offline-cache) — ikke startet. -2. Fortsatt åpne beslutninger fra FEATURE_BACKLOG.md: tilskuer-rolle (bevisst - utsatt til nå at Kommunikasjon er ferdig — bør tas fatt på snart, samme - begrunnelse som før: definer sammen med feed-synligheten, som nå finnes), - kode-regenerering for ADR-020, korrigering-godkjenning fra motpart, live - leaderboard (samme WebSocket-mekanisme som meldinger kan gjenbrukes, ikke - koblet til ennå), video/1-til-1-meldinger (bevisst utsatt i ADR-025). +2. Fortsatt åpne beslutninger fra FEATURE_BACKLOG.md: kode-regenerering for + ADR-020, korrigering-godkjenning fra motpart, live-oppdatering av + `/t/[id]/live`/leaderboard via WebSockets (samme mekanisme som meldinger + finnes og kan gjenbrukes — i dag må siden lastes på nytt for nye + resultater, ikke koblet til sanntid ennå), video/1-til-1-meldinger + (bevisst utsatt i ADR-025). 3. Flere turneringsformater utover Ryder Cup (Københavner/High-low-high/ Robbins/Try all, notert 2026-07-19) — ingen ADR-runde startet ennå. -4. **Merk for neste økt:** `deploy/Caddyfile`-endringen (ny `/ws/*`-rute) - ligger uncommitted i det SEPARATE `/opt/teeoff`-repoet, ikke i +4. **Merk for neste økt:** `deploy/Caddyfile`-endringen (ny `/ws/*`-rute, + ADR-025) ligger uncommitted i det SEPARATE `/opt/teeoff`-repoet, ikke i `teecup`-repoet — samme fallgruve som ADR-016-runden sin Caddy-endring, lett å glemme siden denne økten ellers kun har jobbet i `/opt/teecup`. 5. Ved fremtidige nye V0-skjermer/-design i V0 (fortsett i samme prosjekt), diff --git a/FEATURE_BACKLOG.md b/FEATURE_BACKLOG.md index 87c4f79..b264069 100644 --- a/FEATURE_BACKLOG.md +++ b/FEATURE_BACKLOG.md @@ -323,7 +323,7 @@ `user_is_match_participant`, brukt av `scoring.py`) — ikke lenger «noen på laget», og uavhengig av kapteinmerket. Erstatter «Scoring-autorisasjon»- punktet under, spørsmål (a) er dermed besvart. -- **Tilskuer — ✅ BYGGET OG LIVE 2026-07-19 (ADR-026),** rett etter +- **Tilskuer — ✅ HELT FERDIG, LIVE 2026-07-19 (ADR-026),** rett etter Kommunikasjon (ADR-025) som gjorde feed-synligheten (som denne skulle defineres sammen med) klar. Ingen ny rolle/tabell — «tilskuer» er ganske enkelt enhver som kan SE turneringen (`tournament.visibility`), nå også