Database CrAPP
Struttura del database Supabase (PostgreSQL) e ruolo di ogni tabella. Lo schema autoritativo
sono le migration in supabase/migrations/: una tabella nuova va documentata qui nella
stessa modifica che la crea. Le funzionalità future stanno in ROADMAP.md,
non in questo file.
Permessi di scrittura
Chi può scrivere cosa, dopo la migration m11_scritture_per_ruolo (DD-023). La lettura
resta aperta a tutti gli autenticati su ogni tabella di questo elenco; anon non arriva a
nessuna di esse da M4 (DD-011).
| Tabella |
Chi può scrivere |
eventi_app |
solo admin (nell'app li gestisce la rotta /eventi, già riservata) |
risposte_presenze, cacche_partita |
il giocatore sulla propria riga (giocatore_id), più gli admin |
pagelle_voti, mvp_voti, badge_social_voti |
il votante sui propri voti (votante_id), se votante e votato sono convocati all'evento (m13); solo per le pagelle anche pagelle_chiuse = false; gli admin senza questi vincoli |
turni_palloni, scout_sessioni, scout_live, scout_partite |
qualsiasi autenticato: nell'interfaccia non hanno gate |
profili_giocatore |
il giocatore sul proprio profilo, admin su tutti (DD-016, DD-017) |
giocatori_squadra |
admin; il giocatore può solo reclamare uno slot libero (DD-016) |
user_roles |
solo admin |
L'identità del giocatore è lo slot di giocatori_squadra con auth_user_id = auth.uid().
La tabella è verificata da test/integration/permessi.test.ts contro il database locale.
Anagrafica e utenti
| Tabella |
Scopo |
Note |
giocatori_squadra |
Anagrafica operativa della squadra, con ID testuali (g1…gN), dati gestiti dagli admin (nome, cognome, numero, ruolo), collegamento all'account (auth_user_id) ed email registrata (email). |
Introdotta dalla migration m1_giocatori_squadra, source of truth della rosa (DD-015): useRosa() e gli altri punti che elencano i giocatori la leggono tramite useGiocatoriSquadra() (client) o leggiGiocatoriSquadra() (server), filtrando attivo. src/lib/crapp-data.ts resta solo come seed storico e fallback (rosaFallback()) quando il database non risponde, e come sorgente della data di nascita (non ancora una colonna di questa tabella). Vedi DD-015 e DD-016. La colonna email (migration m5_email_giocatori_squadra, impostabile anche da /admin) è la chiave del collegamento automatico account↔giocatore al primo accesso (DD-018): NULL finché non nota, oggi impostata per tutta la rosa attiva. Le colonne numero_tessera/data_tessera (migration m8_tesseramento_csi) tracciano chi è già tesserato al CSI; come numero/ruolo le scrive solo un admin, il trigger di M1/M5 le include tra i campi bloccati per chi reclama il proprio slot. |
giocatori |
Anagrafica giocatori con UUID. |
Presente ma non usata dal codice attuale: la convergenza è rinviata (DD-012, DD-014). |
profili_giocatore |
Dati personali, metadati del documento d'identità, certificato medico e path dei file, in relazione 1:1 con giocatori_squadra. |
Creata dalla migration m2_profili_giocatore (DD-016). Letta da src/lib/profili.ts; le policy mostrano al giocatore solo il proprio profilo e all'admin tutti. I file non stanno qui: la tabella conserva i path nel bucket. |
user_roles |
Ruoli applicativi (es. amministratore, giocatore). |
Fonte dei permessi di amministrazione, letta da src/lib/ruoli.ts (DD-011). Il primo admin va inserito a mano; vedi PROJECT_STATE.md. |
giocatori_squadra / giocatori sono usate da: Squadra, Profili, Presenze, Scout, Badge, Pagelle.
Storage
| Bucket |
Scopo |
Note |
profili-giocatore |
Documento d'identità, certificato medico e foto tessera, in cartelle per giocatore (<giocatore_id>/<sezione>.<est>). |
Privato e destinato a restare tale: contiene documenti e dati sanitari, che non devono mai avere URL pubblici (DD-016 regola 4). Il giocatore gestisce solo la propria cartella, l'admin può scaricare tutto tramite signed URL a scadenza breve. Creato dalla migration m2_profili_giocatore. |
avatar-giocatori |
Foto profilo mostrate nel cerchio avatar (Squadra, Profilo), un file per giocatore (<giocatore_id>/avatar.jpg). |
Pubblico: foto informali, non documenti sensibili. Qualsiasi autenticato può caricare/sostituire/eliminare un file (nessun controllo per-proprietario, la maggior parte dei giocatori non ha ancora auth_user_id collegato, DD-018). Letto da src/lib/avatar-store.ts. Creato dalla migration m6_avatar_giocatori. |
Eventi e presenze
| Tabella |
Scopo |
Note |
eventi_app |
Eventi gestionali utilizzati dall'app. |
Modello in uso dal codice attuale. |
risposte_presenze |
Risposte dei giocatori agli eventi. |
Modello in uso dal codice attuale. risposto_il è l'istante della prima risposta (migration m9_risposte_presenze_risposto_il): confrontato con eventi_app.creato_il dà la serie "Conferme 24h". Un trigger lo rende immutabile, così un ripensamento non fa risultare rapida una risposta lenta — aggiornato_il resta l'ultima modifica. |
eventi |
Calendario generale: allenamenti, partite, eventi della squadra. |
Modello "nuovo" con autenticazione e vincoli, non ancora adottato (DD-014). |
presenze |
Presenze agli eventi. |
Come sopra (DD-014). |
Scout
| Tabella |
Scopo |
Note |
scout_sessioni |
Chi ha il controllo dello Scout Live per una partita (blocco condiviso), una riga per evento. |
Letta/scritta da src/lib/scout-live.ts. Prima viveva solo in localStorage: "Scout occupato da X" non funzionava mai tra dispositivi diversi (fix M7). |
scout_live |
Stato in corso (azioni non ancora concluse) di una sessione di Scout Live. |
Serve esclusivamente per statistiche di squadra, mai per classifiche individuali (DD-008). Letta/scritta da src/lib/scout-stato.ts. |
scout_partite |
Archivio delle partite scoutate concluse (risultato, parziali, azioni). |
Letta/scritta da src/lib/scout-store.ts. Prima il risultato finale finiva solo in localStorage: invisibile a chiunque non fosse il dispositivo di chi aveva chiuso la partita (fix M7). |
Votazioni
| Tabella |
Scopo |
Note |
mvp_voti |
Voti MVP assegnati a fine partita. |
Un voto per votante e partita; auto-voto rifiutato (mvp_no_autovoto, migration m12_niente_autovoto); votante e votato devono essere convocati all'evento (RLS, m13_convocati_e_pagelle_chiuse). |
pagelle_voti |
Voti anonimi assegnati ai giocatori. |
Usati per il voto medio. Voto 1-10 e auto-voto rifiutato dai vincoli della v1.0; votante/votato convocati e pagelle_chiuse = false richiesti dalla RLS di m13_convocati_e_pagelle_chiuse. |
badge_social_voti |
Voti social per i badge. |
Un voto per categoria, votante e partita; auto-voto rifiutato (badge_social_no_autovoto, m12_niente_autovoto); votante e votato devono essere convocati all'evento (RLS, m13_convocati_e_pagelle_chiuse). |
Turni e notifiche
| Tabella |
Scopo |
Note |
turni_palloni |
Gestione dei turni palloni. |
Solo turni confermati. Gli allenamenti non ricevono proposta automatica (vedi palloni.md); M10 azzera i turni salvati su allenamenti da oggi in poi. |
push_subscriptions |
Dispositivi registrati per le notifiche Push. |
|
promemoria_push |
Non più usata. |
Serviva da coda del testo quando la push partiva vuota; dal payload cifrato non la scrive né la legge nessuno. Tabella ancora presente, da eliminare con una migrazione. |
Funzioni speciali
| Tabella |
Scopo |
Note |
cacche_partita |
Sondaggio prepartita. |
Usato per statistiche e badge segreti. |
Badge
Non esiste una tabella dedicata: i badge vengono calcolati a runtime dall'applicazione a
partire dai dati esistenti (DD-007).