From de78431090cb5771924429aae93027038efe1b9f Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 1 Oct 2026 15:03:04 +0200 Subject: [PATCH] Toglie la foto tessera dal profilo (DD-044) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il Profilo non chiede più la foto tessera e la scheda admin non la mostra. Il completamento diventa dati personali 34%, documento 33%, certificato 33%. La migration m29 elimina la colonna profili_giocatore.foto_path; le 4 foto già caricate sono state cancellate dal bucket profili-giocatore. Migration applicata in produzione. Test: pesi e sezioni di profili-core, rendering di CampiProfilo, colonna rimossa sul database locale. Documentati DD-044, modulo profilo-giocatore, DATABASE, ROADMAP e changelog. Co-Authored-By: Claude Sonnet 5.5 --- docs/CHANGELOG.md | 5 +++ docs/DATABASE.md | 8 ++-- docs/ROADMAP.md | 2 +- docs/decisions/DD-016.md | 2 +- docs/decisions/DD-017.md | 2 +- docs/decisions/DD-044.md | 38 +++++++++++++++++++ docs/decisions/README.md | 1 + docs/modules/allenatore.md | 6 +-- docs/modules/profilo-giocatore.md | 18 +++------ .../crapp/ProfiloAmministrativo.tsx | 19 +--------- src/integrations/supabase/types.ts | 3 -- src/lib/profili-core.ts | 14 ++----- src/lib/profili.ts | 2 +- src/routes/admin.tsx | 7 ---- .../20261001170000_m29_senza_foto_tessera.sql | 9 +++++ supabase/seed.sql | 10 ++--- test/README.md | 12 +++--- test/integration/foto-tessera-rimossa.test.ts | 37 ++++++++++++++++++ test/unit/profili-core.test.ts | 16 +++++--- test/unit/profili.test.ts | 4 +- test/unit/profilo-campi.test.ts | 28 ++++++++++++++ 21 files changed, 164 insertions(+), 79 deletions(-) create mode 100644 docs/decisions/DD-044.md create mode 100644 supabase/migrations/20261001170000_m29_senza_foto_tessera.sql create mode 100644 test/integration/foto-tessera-rimossa.test.ts create mode 100644 test/unit/profilo-campi.test.ts diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index bb9cba9..cadcb38 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -15,6 +15,11 @@ versioni `0.y.z` erano pre-release. ### Rimosso +- **Foto tessera del profilo** — il giocatore non la carica più e l'admin non la vede nella scheda; il + completamento del profilo si calcola su dati personali (34%), documento (33%) e certificato (33%). Migration + `m29_senza_foto_tessera` (elimina la colonna `foto_path`); i file già caricati sono stati cancellati dal + bucket `profili-giocatore` (DD-044). Applicata in produzione il 01/10/2026, con la cancellazione dei 4 file già caricati. + - **Promemoria evento a 24 e 3 ore** — non partono più per nessun evento (allenamenti, partite, extra-campo): niente notifica, push né email. Migration `m28_niente_promemoria_evento` (tolti i due job `pg_cron`; funzione, tipi e notifiche già generate restano). Applicata in produzione il 01/10/2026 (DD-043). diff --git a/docs/DATABASE.md b/docs/DATABASE.md index 0aa1b87..819063e 100644 --- a/docs/DATABASE.md +++ b/docs/DATABASE.md @@ -66,10 +66,10 @@ Colonne di `giocatori_squadra` che meritano una nota: ## Storage -| Bucket | Scopo | Note | -| ------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `profili-giocatore` | Documento d'identità, certificato medico e foto tessera, in cartelle per giocatore (`/.`). | **Privato e destinato a restare tale**: documenti e dati sanitari non devono mai avere URL pubblici (DD-016 regola 4). Il giocatore gestisce solo la propria cartella; l'admin scarica tutto con signed URL a scadenza breve. | -| `avatar-giocatori` | Foto profilo (`/avatar.jpg`). | **Pubblico**: foto informali. Qualsiasi autenticato può caricare, sostituire o eliminare un file (nessun controllo per proprietario: la maggior parte dei giocatori non ha ancora `auth_user_id`, DD-018). Letto da `src/lib/avatar-store.ts`. | +| Bucket | Scopo | Note | +| ------------------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `profili-giocatore` | Documento d'identità e certificato medico, in cartelle per giocatore (`/.`). | **Privato e destinato a restare tale**: documenti e dati sanitari non devono mai avere URL pubblici (DD-016 regola 4). Il giocatore gestisce solo la propria cartella; l'admin scarica tutto con signed URL a scadenza breve. | +| `avatar-giocatori` | Foto profilo (`/avatar.jpg`). | **Pubblico**: foto informali. Qualsiasi autenticato può caricare, sostituire o eliminare un file (nessun controllo per proprietario: la maggior parte dei giocatori non ha ancora `auth_user_id`, DD-018). Letto da `src/lib/avatar-store.ts`. | ## Eventi e presenze diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 1afcd3e..58e9318 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -27,7 +27,7 @@ Tutto quello che è rilasciato, fino alla versione 1.0.0 (vedi `CHANGELOG.md`). - [x] Dashboard amministratore - [x] Download CSV dati - [x] Profilo Giocatore — dati personali, documento d'identità, certificato medico - (caricamento, scadenza, stato, download) e foto tessera; lo storico dei certificati + (caricamento, scadenza, stato, download); la foto tessera è stata tolta (DD-044); lo storico dei certificati resta un'estensione futura - [x] Gestione tesseramenti CSI — raccolta dati, export CSV e tracciamento di chi è già tesserato (numero e data di tessera) diff --git a/docs/decisions/DD-016.md b/docs/decisions/DD-016.md index e01726c..66a09c0 100644 --- a/docs/decisions/DD-016.md +++ b/docs/decisions/DD-016.md @@ -16,7 +16,7 @@ Regole vincolanti: 1. **`giocatori_squadra` diventa progressivamente la source of truth** per l’anagrafica squadra. Durante la transizione, `crapp-data.ts` resta come **fallback** se il database non è disponibile o i dati non sono ancora migrati. 2. L’associazione **`auth_user_id` ↔ giocatore** è un’operazione **controllata e atomica** (es. al primo accesso da `/benvenuto`, con `UPDATE … WHERE auth_user_id IS NULL`). Il giocatore **non può modificare liberamente** `auth_user_id`; solo un admin può resettarlo in casi eccezionali. -3. I file (documento identità, certificato, foto tessera) vivono nel bucket Storage **`profili-giocatore`**, configurato come **privato**. +3. I file (documento identità, certificato; la foto tessera è stata tolta da DD-044) vivono nel bucket Storage **`profili-giocatore`**, configurato come **privato**. 4. Documenti personali e sanitari **non devono mai essere esposti tramite URL pubblici**. Accesso solo tramite client autenticato con policy RLS, o signed URL a scadenza breve per download admin. 5. Le **tabelle preesistenti non vengono modificate** (`eventi_app`, `risposte_presenze`, voti, palloni, scout, push, ecc.). Il profilo si aggancia agli ID `g1`…`g17` già in uso, senza migrare verso UUID per ora (coerente con DD-012). 6. La tabella `giocatori` (UUID) resta **invariata e non usata** dal modulo profilo. diff --git a/docs/decisions/DD-017.md b/docs/decisions/DD-017.md index 451bf9a..4ceee4f 100644 --- a/docs/decisions/DD-017.md +++ b/docs/decisions/DD-017.md @@ -15,7 +15,7 @@ Dalla dashboard amministratore, un admin può: Restano fuori, e non cambiano: -- i **file** (documento, certificato, foto): l'admin li scarica ma non li carica né li sostituisce. Un documento d'identità lo produce il suo titolare, e la catena di responsabilità deve restare leggibile; +- i **file** (documento, certificato; la foto tessera è stata tolta da DD-044): l'admin li scarica ma non li carica né li sostituisce. Un documento d'identità lo produce il suo titolare, e la catena di responsabilità deve restare leggibile; - il **giocatore**, che continua a non poter toccare i propri dati squadra. **Alternative scartate** diff --git a/docs/decisions/DD-044.md b/docs/decisions/DD-044.md new file mode 100644 index 0000000..a82236f --- /dev/null +++ b/docs/decisions/DD-044.md @@ -0,0 +1,38 @@ +# DD-044 — Via la foto tessera dal profilo + +**Data:** 1 ottobre 2026 +**Stato:** Accettata (migration `m29`, applicata in produzione il 1 ottobre 2026) + +**Contesto** +Il profilo amministrativo chiedeva al giocatore una foto formato tessera (DD-016), per il +tesseramento CSI. Non serve più: non viene richiesta nel tesseramento e resta un dato personale +da custodire. + +**Decisione** + +1. Il profilo **non ha più la foto tessera**: sparisce il campo di caricamento dal Profilo e la + voce «Foto» dalla scheda dell'admin. +2. **Completamento del profilo** su tre sezioni: dati personali 34%, documento 33%, certificato 33% + (prima 30/30/30/10). Il totale resta 100 e il widget «Completa il tuo profilo» sparisce con le + tre sezioni complete. +3. **Dati:** la migration `m29` elimina la colonna `profili_giocatore.foto_path`. I file + `/foto.*` del bucket privato `profili-giocatore` vanno cancellati con l'API + Storage (da SQL Storage lo vieta) prima della migration, perché dopo i path non sono più + leggibili. **Non toccati:** l'avatar (bucket `avatar-giocatori`), il documento e il certificato. +4. Ordine in produzione: **prima il rilascio del codice** (la versione precedente seleziona + `foto_path` e darebbe errore), poi cancellazione dei file, poi `m29`. + +**Alternative scartate** + +- Lasciare la colonna e nascondere solo l'interfaccia → scartata: resterebbe un dato personale + senza uso e senza un campo da cui aggiornarlo. +- Tenere i pesi 30/30/30 senza rinormalizzare → scartata: nessun profilo arriverebbe a 100%. + +**Conseguenze** + +- Cancellazione definitiva: le foto già caricate non si recuperano. +- Il 1 ottobre 2026 sono state cancellate in produzione le 4 foto caricate, poi la colonna. +- Le percentuali di completamento cambiano per tutti (chi aveva il 90% senza foto passa al 100%). + +**Riesame** +Se il comitato CSI dovesse richiedere di nuovo la foto, reintrodurla con una nuova decisione. diff --git a/docs/decisions/README.md b/docs/decisions/README.md index 09bb665..abe752a 100644 --- a/docs/decisions/README.md +++ b/docs/decisions/README.md @@ -86,6 +86,7 @@ Una decisione sostituita non si cancella: si cambia il suo **Stato** e si rimand | [DD-038](DD-038.md) | Tre canali per ogni notifica | | [DD-039](DD-039.md) | Niente promemoria all'allenatore | | [DD-040](DD-040.md) | Palloni e solleciti automatici | +| [DD-044](DD-044.md) | Via la foto tessera dal profilo | | [DD-043](DD-043.md) | Niente promemoria evento a 24 e 3 ore | | [DD-042](DD-042.md) | Turno palloni: un solo avviso a 3 ore | | [DD-041](DD-041.md) | Avviso certificati: giocatore a 30 giorni | diff --git a/docs/modules/allenatore.md b/docs/modules/allenatore.md index 91ea452..ee15632 100644 --- a/docs/modules/allenatore.md +++ b/docs/modules/allenatore.md @@ -55,8 +55,8 @@ Un link diretto a `/profilo?tab=stagione` o `?tab=badge` apre Documenti. | Telefono | `profili_giocatore.telefono` | | | Foto profilo | bucket `avatar-giocatori` | stesso cerchio avatar e stesso upload dei giocatori | -**Non** si mostrano: indirizzo di residenza, documento d'identità, certificato medico, foto -tessera, tesseramento CSI. +**Non** si mostrano: indirizzo di residenza, documento d'identità, certificato medico, +tesseramento CSI. ### Completamento profilo @@ -164,7 +164,7 @@ giocatore). | ------------------------------------------------------------------- | ---------- | ------------------ | ----------------------------------- | | Modificare nome e cognome | no | sì, i propri | tutti | | Dati personali e foto profilo | i propri | i propri (ridotti) | tutti (non i file) | -| Documento, certificato, foto tessera | i propri | — | lettura/download | +| Documento, certificato | i propri | — | lettura/download | | Avviso certificati in Home | il proprio | no | tutta la rosa | | Creare/modificare/eliminare eventi, convocati | no | sì | sì | | Sollecitare le presenze | no | sì | sì | diff --git a/docs/modules/profilo-giocatore.md b/docs/modules/profilo-giocatore.md index 0e00435..4dec796 100644 --- a/docs/modules/profilo-giocatore.md +++ b/docs/modules/profilo-giocatore.md @@ -44,7 +44,7 @@ Può: riga non viene eliminata, così presenze, voti, pagelle e badge della stagione restano agganciati al suo id -Non può caricare o sostituire i file altrui: documento, certificato e foto restano +Non può caricare o sostituire i file altrui: documento e certificato restano responsabilità del giocatore che li fornisce. ## Flusso utente @@ -73,7 +73,6 @@ Viene mostrata una barra di avanzamento (esempio: _Profilo completato — 85%_), - Dati personali - Documento di identità - Certificato medico -- Foto tessera Quando tutte le sezioni sono complete il widget scompare automaticamente. @@ -273,9 +272,8 @@ Lo storico non viene mantenuto nella prima versione. ### Foto tessera -Upload di una fotografia formato tessera. - -Utilizzata dagli amministratori per il tesseramento CSI. +**Rimossa** (DD-044, migration `m29`): il profilo non chiede più la foto tessera e la colonna +`foto_path` non esiste più. I file già caricati sono stati cancellati dal bucket. ### Statistiche @@ -328,7 +326,6 @@ Per ogni giocatore, nella tab Profili, vengono mostrati. - Stato del profilo - Certificato medico - Documento di identità -- Foto tessera - Stato tesseramento CSI (tesserato / da tesserare) Azioni disponibili. @@ -336,7 +333,6 @@ Azioni disponibili. - Visualizza profilo (la scheda si apre in linea nell'elenco: nessuna schermata separata) - Scarica certificato - Scarica documento -- Scarica foto tessera - Modifica dati squadra e dati personali del giocatore (DD-017) - Registra numero e data della tessera CSI, una volta arrivata dal comitato - Scollega account, per liberare uno slot assegnato per errore @@ -377,10 +373,9 @@ Ogni sezione contribuisce alla percentuale di completamento. | Sezione | Peso | | --------------------- | ---- | -| Dati personali | 30% | -| Documento di identità | 30% | -| Certificato medico | 30% | -| Foto tessera | 10% | +| Dati personali | 34% | +| Documento di identità | 33% | +| Certificato medico | 33% | Quando tutte le sezioni risultano complete il profilo raggiunge il 100%. @@ -402,7 +397,6 @@ nessun altro ne vede (vedi [Avviso certificati](#avviso-certificati)). - Gestione dati personali - Documento di identità - Certificato medico -- Foto tessera - Dashboard amministratore - Esportazione CSV CSI diff --git a/src/components/crapp/ProfiloAmministrativo.tsx b/src/components/crapp/ProfiloAmministrativo.tsx index a41c8ea..17cfdee 100644 --- a/src/components/crapp/ProfiloAmministrativo.tsx +++ b/src/components/crapp/ProfiloAmministrativo.tsx @@ -120,14 +120,12 @@ export function CampiProfilo({ sezioni, fileDocumento, fileCertificato, - fileFoto, }: { corrente: Profilo; aggiorna: (patch: Partial) => void; sezioni: Record; fileDocumento?: React.ReactNode; fileCertificato?: React.ReactNode; - fileFoto?: React.ReactNode; }) { return ( <> @@ -241,14 +239,13 @@ export function CampiProfilo({ /> {fileCertificato} - {fileFoto} ); } /** * I dati personali dell'allenatore (DD-034): gli stessi campi di `profili_giocatore`, meno - * indirizzo, documento, certificato e foto tessera. Condivisi tra Profilo e dashboard admin. + * indirizzo, documento e certificato. Condivisi tra Profilo e dashboard admin. */ export function CampiAllenatore({ corrente, @@ -469,18 +466,6 @@ export function ProfiloAmministrativo({ onCaricato={caricato("certificatoPath")} /> } - fileFoto={ - <> - - - - } />