teecup/015_user_profile.sql

38 lines
1.7 KiB
MySQL
Raw Normal View History

Update Todos Migrasjon 015: app_user-profilfelt + player_organizations_for_user()-bro Backend: utvid Me + PATCH /auth/profile + avatar-opplasting/sletting Backend: 'mine runder'-data + check_visibility-utvidelse for deltakere Frontend: profil-seksjon i /account Frontend: 'Mine runder'-seksjon + betinget tom-tilstand i dashboard.tsx Scratch-verifisere alt (15 sjekker bestått) Typesjekket frontend-build ADR-031 + .md-oppdatering Bygget og scratch-verifisert (15 automatiserte sjekker). Oppsummering: Personlig profil — nye felt på selve kontoen (ikke på org-ens spillerdata, det er bevisst holdt atskilt siden en person kan ha ulike spiller-rader i ulike klubber): profilbilde, fornavn, etternavn, fødselsdato, kjønn, HCP, hjemmeklubb. Redigeres i en ny seksjon på /account. Sletting av enkeltfelt fungerer (send tomt/null), profilbilde kan lastes opp og fjernes. "Mine runder" — ny seksjon øverst på dashbordet, viser turneringer du er rostret i på tvers av alle organisasjoner, uavhengig av om du er medlem noe sted. Et reelt sikkerhetshull jeg fant underveis, ikke antatt på forhånd: da jeg testet "Mine runder" mot en faktisk ren spiller (ingen organisasjonsmedlemskap), oppdaget jeg at synlighetsregelen kun ga deltakere tilgang for det strengeste synlighetsnivået — ikke for standard-nivået («org»), som er det ALLE nye turneringer får automatisk. En ren spiller ville altså vært låst ute av sin egen, helt normale turnering. Fikset og verifisert grundig at det er en ren utvidelse: en fremmed innlogget bruker og en anonym leser blir fortsatt korrekt avvist som før. Bevisst utenfor omfang, tydelig flagget: "Mine runder" lenker til den offentlige turnering-siden, ikke til lagets private chat eller scorekortet ennå — de krever fortsatt ekte organisasjonsmedlemskap, en strengere sperre brukt bredt i hele appen som jeg ikke ville endre uten en egen, forsiktig runde. Notert som naturlig neste steg. Ingen kode for punkt 2 (midlertidige spillere) i denne runden, som avtalt.
2026-07-20 10:41:30 +02:00
-- =====================================================================
-- TeeCup — personlig profil på app_user + tverr-org spiller-oppslag
-- (migrasjon 015)
-- =====================================================================
-- ADR-031: personlig landingsside for enhver registrert bruker. Ett
-- canonical profil-sett PER KONTO (ikke per org-scopet `player`-rad --
-- se ADR-031 for hvorfor de to bevisst holdes atskilt). Alt additivt/
-- nullable -- trygt mot eksisterende kontoer.
-- =====================================================================
\set ON_ERROR_STOP on
ALTER TABLE app_user ADD COLUMN first_name text;
ALTER TABLE app_user ADD COLUMN last_name text;
ALTER TABLE app_user ADD COLUMN birth_date date;
ALTER TABLE app_user ADD COLUMN gender text CHECK (gender IN ('m', 'f', 'x'));
ALTER TABLE app_user ADD COLUMN handicap_index numeric(4,1);
ALTER TABLE app_user ADD COLUMN home_club text;
ALTER TABLE app_user ADD COLUMN avatar_key text;
-- Samme "smale SECURITY DEFINER-bro"-mønster som public_tournament_org()
-- (007) / link_player_by_email() (008) / public_org_by_slug() (009) /
-- public_tournament_by_code() (011): `player` er RLS-beskyttet per org, så
-- et tverr-org-oppslag ("hvilke organisasjoner har jeg en spiller-rad i")
-- kan ikke gjøres med en vanlig org-scopet tilkobling. Eksponerer KUN
-- uuid-listen, ingenting annet fra player-raden.
CREATE FUNCTION player_organizations_for_user(p_user_id uuid)
RETURNS TABLE(organization_id uuid)
LANGUAGE sql
SECURITY DEFINER
SET search_path = public
STABLE
AS $$
SELECT DISTINCT organization_id FROM player WHERE user_id = p_user_id;
$$;
GRANT EXECUTE ON FUNCTION player_organizations_for_user(uuid) TO teecup_app;