diff --git a/.claude/settings.local.json b/.claude/settings.local.json index fd9203c..1b46332 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -342,7 +342,10 @@ "Bash(rm -f /opt/requirements.txt)", "Bash(python3 -m py_compile app/routers/*.py app/*.py)", "Bash(python3 -m py_compile app/routers/auth.py app/email.py)", - "Bash(sort -t_ -k1 -n)" + "Bash(sort -t_ -k1 -n)", + "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" https://teecup.teeoff.no/)", + "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" https://teecup.teeoff.no/account)", + "Bash(curl -s -o /dev/null -w \"%{http_code}\\\\n\" https://teeoff.no/)" ], "additionalDirectories": [ "/opt/teeoff/deploy", diff --git a/CLAUDE.md b/CLAUDE.md index 0df46c2..e8935d4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2206,13 +2206,66 @@ Ferdig og verifisert: (2026-07-21) ferdig bygget** (deltaker-tilgang, sekundær e-post del 1, HCP-historikk). +- **Obligatorisk profil-fullføring ved innlogging LIVE (2026-07-22):** + svar på det pauserte "dashbordets tom-tilstand"-spørsmålet over — + brukeren avklarte at det ALLER første en innlogget bruker med en + ufullstendig profil skal se, er en fokusert «Fullfør profilen din»- + visning, ikke dashbordet. Ny migrasjon `019_profile_country_bio.sql` + (`app_user.country`, `app_user.bio` — samme nullable-kolonne-mønster + som resten av profilen, "obligatorisk" håndheves i app-laget). + `/auth/me` fikk et nytt beregnet felt `profile_complete` (sant når + fornavn/etternavn/fødselsdato/kjønn/HCP/hjemmeklubb/land ALLE er + utfylt — bilde og beskrivelse er bevisst unntatt, valgfrie). + **HCP-grensetilfelle avklart med bruker FØR bygging** (nybegynnere har + sjelden en offisiell HCP ennå): WHS-maksimum 54 brukes som + forhåndsutfylt standardverdi i skjemaet (ikke en DB-default), og + `ProfileUpdate.handicap_index` fikk en hard `le=54`-grense (kan aldri + registreres høyere) — løser grensetilfellet uten en egen "har ikke + HCP ennå"-avkrysning. + `AccountSettings` (`/account`) grener nå: er profilen ufullstendig, + vises KUN et nytt, fokusert `ProfileOnboarding`-skjema (de obligatoriske + feltene + valgfri beskrivelse, «Logg ut» tilgjengelig, INGEN tilgang + til resten av kontosidene) — er den komplett, vises den vanlige + innstillingssiden som før (nå med land+beskrivelse lagt til i det + vanlige profilskjemaet, for redigering i etterkant). `app/page.tsx` + (rot-siden) og `Dashboard`-komponenten sender en innlogget bruker til + `/account` i stedet for `/dashboard` når profilen er ufullstendig — + dekker alle innloggingsveier (magic-link/passord/2FA lander alle på + `/dashboard`, som selv gjør sjekken ved mount). + **Bevisst avgrenset:** gaten håndheves kun ved disse to naturlige + inngangspunktene, ikke ved dypere direktelenker til andre autentiserte + sider — samme skope-disiplin som tidligere runder. + **Scratch-verifisert, 16 backend-sjekker** (isolert scratch-rolle+ + MinIO+engangs API-container): fersk konto starter `profile_complete: + false`, delvis utfylling forblir ufullstendig, HCP>54 avvist (422), + full utfylling gir `true`, beskrivelse er reelt valgfri, å nullstille + et obligatorisk felt i etterkant slår `profile_complete` tilbake til + `false`, full isolasjon mellom to kontoer. `test_isolation.sql` 12/12 + uendret. Ekte typesjekket produksjonsbuild + et ekte HTTP-nivå-bevis + mot en kjørende produksjonscontainer (anonym mot `/` → 200 innloggings- + skjema, en ekte innlogget-men-ufullstendig sesjonscookie mot `/` → + `307 → /account`). + **Rullet ut live 2026-07-22**, bruker bekreftet eksplisitt: migrasjon + 019 kjørt mot ekte `teecup_db` (kolonner bekreftet, `test_isolation.sql` + fortsatt 12/12), deretter `docker compose up -d --build teecup_api + teecup_frontend`. Begge containere boot-et rent, `/health`/`/dashboard`/ + `/account`/`/` (anonym) → 200, `teeoff.no` upåvirket. **Merk:** BEGGE + brukerens egne kontoer (`erol.haagenrud@envide.no` — eier av «Tjøme + Gents» — og `hei@erol.no`) mangler i dag alle disse feltene og vil + derfor begge se profil-fullførings-skjemaet ved neste innlogging — + bekreftet tilsiktet, ikke en bug. + Neste steg: 1. **Pauset, venter på retning:** dashbordets tom-tilstand ved første innlogging. Brukeren ba om å justere det opprinnelige 2026-07-20- forslaget i lys av et dypere spørsmål — bør organisasjon fortsatt være "det som meldes først"? Min vurdering (se FEATURE_BACKLOG.md): nei, - bør bli ett likestilt valg blant flere. Bygging avhenger delvis av - punktet under (hvilken tredje kortform tom-skjermen skal ha). + bør bli ett likestilt valg blant flere. **Delvis besvart 2026-07-22:** + den ALLER første tingen en ny/ufullstendig bruker nå ser er den + obligatoriske profil-fullføringen (se status over), ikke selve + dashbordet — men spørsmålet om HVA dashbordets tom-tilstand skal vise + for en bruker som HAR fullført profilen, men ennå ikke har noen + organisasjon/turnering, står fortsatt åpent. 3. **Nytt, stort, IKKE designet:** frittstående rundeføring + detaljert statistikk (putter/chip/bunkerslag/straffeslag/førsteputt-lengde) UTEN turnering/organisasjon, reist 2026-07-21. Utfordrer tenant-invarianten diff --git a/FEATURE_BACKLOG.md b/FEATURE_BACKLOG.md index 21db04d..c761bab 100644 --- a/FEATURE_BACKLOG.md +++ b/FEATURE_BACKLOG.md @@ -1261,6 +1261,59 @@ ADR), og konto-sammenslåing (del 2 av multi-e-post). --- +## Obligatorisk profil-fullføring ved innlogging — ✅ BYGGET OG LIVE 2026-07-22 + +Bygget som direkte svar på "hva skal møte en fersk bruker aller først"- +spørsmålet reist i tom-tilstand-diskusjonen under. Brukeren observerte selv +at en fersk konto (`hei@erol.no`, opprettet bevisst for å se førstegangs- +innloggingen) kun viste et tomt skall + opprett-organisasjon-skjermet, og +avklarte at riktig oppførsel er: **kontoinnstillinger/personlig profil skal +være det aller første som vises, og alt der (utenom bilde) skal være +obligatorisk**, før noe annet i appen (inkl. dashbordet) er tilgjengelig. + +**Design:** +- Ny migrasjon `019_profile_country_bio.sql`: `app_user.country` + + `app_user.bio` (samme nullable-kolonne-mønster som resten av + ADR-031-profilen — "obligatorisk" håndheves i app-laget via et beregnet + `profile_complete`-felt på `/auth/me`, ikke som en DB `NOT NULL`). +- Obligatoriske felt: fornavn, etternavn, fødselsdato, kjønn, HCP, + hjemmeklubb, land. Valgfrie: beskrivelse, profilbilde. +- **HCP-grensetilfellet avklart eksplisitt med bruker før bygging** (via + AskUserQuestion): en fersk golfspiller har sjelden en offisiell HCP + ennå. Løsning: WHS-maksimum 54 er forhåndsutfylt i skjemaet som + utgangspunkt, og `handicap_index` har en hard `le=54`-validering i + `ProfileUpdate` (kan aldri registreres høyere) — ingen egen "har ikke + HCP ennå"-avkrysning trengtes. +- `/account` grener på `profile_complete`: ufullstendig → et nytt, + fokusert `ProfileOnboarding`-skjema (kun de obligatoriske feltene + + valgfri beskrivelse, «Logg ut» tilgjengelig, INGEN annen navigasjon) — + komplett → den vanlige innstillingssiden (nå med land+beskrivelse lagt + til i det ordinære profilskjemaet for redigering i etterkant, per + brukerens eget ønske: "Når dette er på plass kan informasjonen heller + kunne redigeres i 'Konto'-visningen"). +- `app/page.tsx` (rot) og `Dashboard`-komponenten sender en innlogget + bruker til `/account` i stedet for `/dashboard` når profilen er + ufullstendig — dekker alle innloggingsveier (magic-link/passord/2FA + lander alle på `/dashboard` uansett hvilken flyt som ble brukt, som selv + gjør sjekken ved mount, så ingen av de tre separate login-komponentene + måtte endres). +- **Bevisst avgrenset:** gaten håndheves kun ved disse to inngangspunktene, + ikke ved dypere direktelenker til andre autentiserte sider (f.eks. en + bokmerket turnering-URL) — samme skope-disiplin som tidligere runder. + +**Verifisert:** se full detalj i CLAUDE.md-status 2026-07-22 — 16/16 +scratch-backend-sjekker, `test_isolation.sql` 12/12, ekte typesjekket +produksjonsbuild, og et ekte HTTP-nivå-bevis mot en kjørende +produksjonscontainer (anonym → 200 innloggingsskjema, ekte innlogget-men- +ufullstendig sesjonscookie → `307 → /account`). Rullet ut mot ekte +`teecup_db`/containere, bruker bekreftet eksplisitt. + +**Kjent, tilsiktet konsekvens:** brukerens BEGGE egne kontoer +(`erol.haagenrud@envide.no` og `hei@erol.no`) manglet alle disse feltene +og vil derfor begge se profil-fullførings-skjemaet ved neste innlogging. + +--- + ## Dashboard: tom-tilstand ved første innlogging — 📋 UNDER REVURDERING (2026-07-21), IKKE bygget Brukeren påpekte 2026-07-20 at dagens tomme-tilstand ("Du har ingen @@ -1283,6 +1336,17 @@ likestilt valg blant flere fremtidige "første ting du kan gjøre" arrangere/opprette organisasjon) — ikke lenger den ENESTE synlige veien inn. +**2026-07-22 — delvis besvart, ikke fullt løst:** brukeren avklarte at +det ALLER første en innlogget bruker med en ufullstendig personlig profil +skal se, er en obligatorisk «Fullfør profilen din»-visning (fornavn/ +etternavn/fødselsdato/kjønn/HCP/hjemmeklubb/land — alt utenom bilde og +beskrivelse) — se CLAUDE.md-status, ✅ BYGGET OG LIVE. Dette svarer på +"hva møter en fersk bruker aller først", men IKKE på det opprinnelige +spørsmålet i denne seksjonen: hva skal dashbordets tom-tilstand vise for +en bruker som HAR fullført profilen, men ennå ikke har noen organisasjon/ +turnering å vise? Den vurderingen (organisasjon bør slutte å være +default/første-handling) står fortsatt ved lag og er fortsatt IKKE bygget. + **Konsekvens for byggerekkefølgen:** selve tom-skjerm-redesignet er satt PÅ VENT til frittstående runder (under) er avklart nok til å vite hvilken tredje kortform den skal ha på tom-skjermen — å bygge en to-valgs versjon