Ogni salvataggio di CrAPP è un upsert con un onConflict scritto a mano nei hook
di src/lib/. Se quella chiave non corrisponde al vincolo UNIQUE della tabella
non arriva nessun errore: il database sovrascrive la riga sbagliata, e il difetto
si vede settimane dopo in una media che non torna. Nessuna delle sedici
scritture era mai stata eseguita da un test.
test/integration/scritture.test.ts ripete le stesse chiamate dei hook contro il
database locale e conta cosa resta nella tabella. Le due regole opposte che
nessuno verificava: le pagelle tengono un voto per ogni votato — se il conflitto
fosse su (match, votante) ogni voto cancellerebbe il precedente — mentre l'MVP
ne tiene uno solo per votante e partita. Più badge social per categoria, cacche,
turni palloni, risposte presenze (con l'istante che alimenta la serie di
conferme) e lo stato jsonb dello scout, che viene sostituito e non fuso. In più
i due CHECK su cui l'app conta: niente autovoto, voto fra 1 e 10.
Le righe usano il prefisso test-scritture e spariscono in un finally. La lettura
delle credenziali locali passa da test/helpers/locale.ts, ora che la usano due
file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le policy RLS scritte su auth.uid() e il trigger di DD-016 non erano coperti da
nessun test: schema-profili prova solo l'utente anonimo, e sul database di .env
non si può scrivere perché è quello di produzione.
Il nuovo test/integration/permessi.test.ts crea utenti veri sullo stack locale
(npx supabase start) e interroga il database come loro: un giocatore vede e
modifica solo il proprio profilo, non ne cancella, non cambia numero e ruolo
mentre reclama uno slot, non prende lo slot di un altro, non si assegna il ruolo
admin e non vede i ruoli altrui. Un controllo positivo sull'admin evita il falso
verde di un database completamente chiuso.
Prende URL e chiavi da `supabase status` invece che da .env e si ferma se l'URL
non è locale: un .env puntato alla produzione non deve poter trasformare un test
in una scrittura sul database vero. Senza stack locale si salta con il motivo,
quindi la suite resta verde su una macchina senza Docker. Ogni test ripristina
in un finally lo stato che tocca, così si rilancia senza db reset.
test/README.md documenta il flusso Docker e corregge la convenzione: non è più
«nessun test scrive sul database» ma «sul database di .env non scrive nessuno».
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
M3 esisteva solo come bozza archiviata in docs/archive/migrations/: il bucket
profili-giocatore è creato dalla migration M2 insieme alla tabella. Allinea
PROJECT_STATE.md (12 -> 18 migration), DATABASE.md, CHANGELOG.md, TODO.md,
DESIGN_DECISIONS.md, test/README.md e il test di integrazione dei profili.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Numero e data della tessera arrivano dal comitato dopo l'iscrizione, quindi
li scrive solo un admin (come numero/ruolo): estende il trigger di M1/M5,
aggiunge il pannello dedicato in /admin con badge e conteggio in dashboard.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copre le parti nuove e una trappola che sarebbe passata inosservata.
- unit: completamento del profilo (30/30/30/10), stato di scadenza dei
documenti, export CSV, conversione riga <-> modello, anagrafica di squadra.
- unit: risoluzione dei permessi admin, incluso il fatto che con una sessione
attiva decide il database e la lista di nomi non conta più.
- integration (schema-profili): verifica su un database vero le colonne che il
codice legge, il bucket privato e la chiusura verso l'utente anonimo.
- e2e: /admin entra nell'elenco delle schermate verificate.
schema-profili tenta scritture da anonimo per dimostrare che la RLS le respinge,
e poi rilegge la riga: su un UPDATE che tocca zero righe PostgREST risponde 2xx,
quindi fidarsi del codice di risposta darebbe un falso verde. Si salta da solo
dove M2/M3 non sono ancora applicate, indicandolo nel motivo.
Verificato: 8/8 contro lo stack locale (che ha M2/M3), 21/21 file con
npm run test:all contro il progetto cloud.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The project had no automated verification at all, so the "Test" step in
the AGENTS.md workflow rested entirely on clicking through the app.
The suite runs on bun with node:assert and adds no dependency: every file
is a script that exits non-zero when a check fails, and test/run.ts runs
each one in its own process. Unit tests cover the rules that decide what
players see (badges, streaks, ball duty rotation, ratings, MVP ties,
scouting totals, goals, notifications, CSI parsing); integration and
end-to-end tests drive the real dev server. Nothing writes to the
database, so both can be pointed at a live environment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>