Commit Graph
28 Commits
Author SHA1 Message Date
davideandClaude Sonnet 5.5 986098d933 DD-050: «Presenza modificata» anche agli allenatori (m33)
Fine della fase di prova: la funzione avvisa admin e allenatori attivi. Test
aggiornato (l'allenatore ora è tra i destinatari), DD-050, notifiche, allenatore,
DATABASE, CHANGELOG, ROADMAP e PROJECT_STATE allineati. m33 non ancora applicata
in produzione.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 11:06:46 +02:00
davideandClaude Sonnet 5.5 274fed93c5 Implementa DD-050: avviso «Presenza modificata», in prova solo per gli admin
Migration m32: tipo presenza_modificata, funzione e trigger su risposte_presenze
che avvisano gli admin attivi se una risposta cambia a 0-6 ore da una partita o
un allenamento (push, email e centro notifiche). Gli allenatori non la ricevono
finché dura la prova. Applicata in produzione il 09/10/2026.
Test di integrazione e unitario; DD-050, notifiche, DATABASE, CHANGELOG,
ROADMAP e PROJECT_STATE aggiornati (slot g18 ora giocatore).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 10:54:47 +02:00
davideandClaude Sonnet 5.5 519f9aaff4 Avvisi in Home: componente condiviso, più leggibili; turno palloni ridisegnato
Certificati e turno palloni usano lo stesso componente Avviso: icona propria per
ogni caso (il colore non è l'unico segnale), testo più grande, elenchi di persone
in righe con dettaglio a destra e conteggio, freccia sulle card cliccabili,
comparsa graduale. Il turno palloni ha la pillola «Oggi»/«In arrivo» e i
messaggi in riquadri. Solo aspetto: testi e regole di comparsa invariati.
Test del componente, CHANGELOG, ARCHITECTURE e test/README aggiornati.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 11:44:58 +02:00
davideandClaude Sonnet 5.5 e7ae2c1884 Toglie numero e data tessera dalla dashboard (DD-048); docs allineate
Spariscono dalla scheda del giocatore in /admin il blocco «Tesseramento CSI» e il
salvataggio, il badge «Tesserato/Da tesserare» e il riquadro «Tesserati» della
tab Squadra. L'export CSV non cambia. Le colonne numero_tessera e data_tessera
restano a database, non più usate; nessuna migration.

Aggiornati PROJECT_STATE, CHANGELOG, ARCHITECTURE, DATABASE, ROADMAP, i moduli
profilo-giocatore, squadra e obiettivi-squadra, test/README e l'indice delle
decisioni.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 11:39:11 +02:00
davideandClaude Sonnet 5.5 985fc2fcc1 Notifica di compleanno: auguri al festeggiato, avviso agli altri (DD-047)
Ogni giorno, dalle 8:00 (Europe/Rome), un job pg_cron orario manda a chi compie
gli anni «Buon compleanno, <Nome>! 🎂» e a tutti gli altri membri attivi,
allenatori compresi, «Oggi è il compleanno di <Nome>» (con più compleanni lo
stesso giorno un solo messaggio a testa, nomi in ordine alfabetico). Solo
titolo, senza corpo né età. Canali: push, centro notifiche ed email.

- migration m31: tipi `compleanno` e `compleanno_auguri`, registro
  `compleanni_notificati` (una sola volta per destinatario e giorno, anche se la
  notifica viene eliminata), funzione `genera_avvisi_compleanno()` e job
  `avvisi-compleanno`, trigger push esteso ai nuovi tipi. Non ancora applicata
  in produzione.
- 29 febbraio non gestito: chi è nato quel giorno è avvisato solo negli anni
  bisestili (limite noto, documentato).
- test: integrazione `notifiche-compleanno` (ora e ora legale, destinatari,
  più compleanni, registro, coda push/email, 29 febbraio, job pianificato);
  unit sui nuovi tipi e sul corpo vuoto del service worker.
- documentazione: DD-047, catalogo e testi delle notifiche, DATABASE, CHANGELOG,
  ROADMAP, PROJECT_STATE.

Chiude la issue #11.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 10:18:22 +02:00
davideandClaude Sonnet 5.5 f19f0bbf8d Sollecito presenze: un solo avviso automatico, 24 ore prima (DD-045)
La migration m30 riduce il job automatico alla sola fascia delle 24 ore:
il sollecito arriva una volta a chi non ha risposto o ha risposto «forse»,
anche per un evento creato a meno di 24 ore dall'inizio. Il pulsante
manuale «Sollecita» non cambia. I tipi sollecita_presenze_12h e _6h restano
ammessi per le notifiche già generate. Migration applicata in produzione.

Test di integrazione aggiornati; documentati DD-045, moduli notifiche,
presenze e allenatore, DATABASE, ROADMAP e changelog.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 15:39:24 +02:00
davideandClaude Sonnet 5.5 de78431090 Toglie la foto tessera dal profilo (DD-044)
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 <noreply@anthropic.com>
2026-10-01 15:03:04 +02:00
davideandClaude Sonnet 5.5 cdf8b144e2 Turno palloni: un solo avviso, 3 ore prima dell'evento (DD-042)
La migration m27 riduce il job automatico alla sola fascia delle 3 ore:
l'avviso arriva una volta a chi deve portare i palloni e a chi li deve
prendere. I tipi turno_palloni_12h e _6h restano ammessi per le notifiche
già generate e per la revoca. Migration applicata in produzione.

Test di integrazione aggiornati (nessun avviso a 4,5 e 9 ore); documentati
DD-042, moduli, DATABASE, ROADMAP, glossario e changelog.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 14:33:38 +02:00
davideandClaude Sonnet 5.5 71b2d97fae Documenta l'implementazione delle notifiche automatiche (DD-040)
DD-040 passa a implementata in locale; catalogo e testi aggiornati; nuova
tabella delle funzioni SQL e dei job in DATABASE.md; note su palloni, presenze,
allenatore e worker; CHANGELOG, ROADMAP, PROJECT_STATE e README dei test.
Corretto lo stato delle migration in produzione (applicate fino a m25).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 14:03:50 +02:00
davideandClaude Sonnet 5.5 4760e8650c L'allenatore non riceve i promemoria degli eventi; test dei destinatari per ruolo (DD-039)
m25: giocatori_destinatari_evento() include solo i giocatori attivi, quindi
l'allenatore non riceve più i promemoria a 24 e 3 ore, per nessun tipo di
evento (fino alla m24 li riceveva sempre, DD-034). Riceve ancora i messaggi
dello staff.

Test: nuovo destinatari-notifiche.test.ts (14 controlli sulle route vere con un
servizio push finto: promemoria, messaggio dello staff, sondaggio, sollecito,
turno palloni, permessi di allenatore e giocatore) e aggiornato
permessi-allenatore. Documentazione: DD-039, tabella delle notifiche
dell'allenatore, catalogo e tabella dei test che lo verificano.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 14:48:30 +02:00
davideandClaude Sonnet 5.5 e9013b703b Promemoria senza ritorni e tre canali per ogni notifica (DD-037, DD-038)
m23: un registro (promemoria_eventi_generati) ricorda i promemoria a 24 e 3 ore
già generati, così eliminare la notifica non li fa rigenerare dal cron né
riaccodare la mail a ogni giro.

m24: la push dei promemoria, che nascono nel database, la manda il worker
mailer/ con lo stesso modulo dell'app (coda notifiche_push_coda, esiti, backoff,
iscrizioni scadute eliminate, push scartate oltre 3 ore). Il sondaggio
pre-partita scrive anche notifiche_utente (tipo sondaggio_cacche): compare
in-app e arriva per email. L'immagine del worker si costruisce dalla radice
del repository per includere src/lib/webpush.server.ts.

Test: 9 di integrazione per m23, 17 per la coda push, 6 per la route del
sondaggio, nuovi casi unitari sul worker; prova end-to-end con un servizio
push finto. Documentazione e catalogo delle notifiche aggiornati.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 14:19:54 +02:00
davideandClaude Sonnet 5.5 b7d3fde225 Implementa le notifiche email via Gmail da un worker Docker (DD-036)
Migration m22: coda notifiche_email_coda, preferenze_utente, trigger che
accoda ogni notifica di notifiche_utente e tre funzioni RPC riservate
alla service role. Worker in mailer/ (bun + nodemailer, solo polling in
uscita) con backoff, tetto giornaliero e healthcheck. Interruttore
«Email» in Profilo → Opzioni, acceso di default. Test unit e di
integrazione; documentazione aggiornata (DD-036 accettata).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 11:07:24 +02:00
davideandClaude Opus 5.5 c6437a605c Aggiunge il controllo dei tipi e copre con un test lo script di backup
- npm run typecheck (tsc --noEmit) entra nella checklist di fine lavoro:
  bun esegue i test senza controllare i tipi, ed è così che si erano
  accumulati errori di tipo con la suite verde.
- La logica pura del download dello storage passa in storage-core.ts,
  testata con dati finti (nessuna lettura del .env reale).
- Il download dello storage esce con errore se anche un solo file non
  si scarica, così backup.sh non dichiara completo un backup parziale.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 12:25:35 +02:00
davideandClaude Sonnet 5 cdd433cb15 Copre con un test il backfill di M19 (nascita dei profili preesistenti
M19 era stato applicato in produzione senza copertura automatica, solo
verificato a mano. Il test simula un profilo compilato prima di M18 ed
esegue lo stesso SQL del backfill via psql, perché PostgREST non espone
un update multi-tabella come RPC.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 13:22:19 +02:00
davideandClaude Sonnet 5 bef5542ce3 Rende testabile la bonifica di M15 come funzione RPC (M16)
M15 ha ripulito una tantum le righe orfane con un blocco di DELETE
verificato solo a mano, senza lasciare nessuna rete di sicurezza
automatica per il futuro. Questa migration rende lo stesso corpo la
funzione bonifica_dati_evento_orfani(), riservata al service role, così
resta richiamabile se il trigger di M14 smettesse mai di funzionare.

Aggiunge test/integration/bonifica-evento.test.ts: inserisce una riga
orfana e una storica su id Scout/CSI, richiama la funzione via RPC e
verifica che tocchi solo la prima. Documenta l'aggiornamento in
DESIGN_DECISIONS.md (DD-029), DATABASE.md, test/README.md e CHANGELOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 10:32:16 +02:00
davideandClaude Sonnet 5 c7cd527045 Pulisce a cascata i dati collegati quando un evento viene cancellato (DD-029)
Un audit del modulo Obiettivi ha verificato che gli obiettivi non hanno
bisogno di pulizia: sono ricalcolati a runtime sull'elenco eventi
corrente. Il problema reale era un livello sotto: cancellare un evento
lasciava orfane le righe collegate in 8 tabelle (risposte_presenze,
cacche_partita, mvp_voti, pagelle_voti, badge_social_voti,
turni_palloni, scout_sessioni, scout_live, scout_partite), nessuna con
una foreign key verso eventi_app.

Aggiunge un trigger AFTER DELETE su eventi_app (migration
m14_pulizia_dati_evento_cancellato) invece di una FK con CASCADE, non
applicabile per dati storici disallineati (match_id che a volte punta
a id Scout/CSI). Verificato con un nuovo test di integrazione contro
il database locale; documentato in DESIGN_DECISIONS.md, DATABASE.md,
obiettivi-squadra.md, test/README.md e CHANGELOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 10:16:29 +02:00
davideandClaude Sonnet 5 8a692bfe2f Documenta il salto automatico dei test CSI quando il portale non risponde
Aggiunto un punto ai Limiti noti di collegamento-csi.md: il portale può essere
del tutto irraggiungibile (non solo cambiare formato, già coperto dal punto 5),
con l'episodio dell'8 settembre 2026 come esempio verificato. Spiega perché
api.test.ts salta quei 5 test invece di farli fallire, e che tornano a girare da
soli quando il CSI risponde di nuovo. Aggiunta la stessa nota, più breve, in
test/README.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 14:48:33 +02:00
davideandClaude Opus 5 7c1f08d943 Copre la cache delle presenze, le tabelle aperte e le letture server.
Chiude i tre buchi di copertura rimasti dalla rilettura della documentazione:
comportamenti che la doc descrive come regole ma che nessun test verificava.

- conRisposta() esce da useSalvaPresenza e diventa una funzione pura in presenze.ts.
  La mutation non rilegge dopo la scrittura, quindi la cache deve imitare il database:
  l'istante si scrive solo se manca (??=) e il ritiro della risposta lo cancella. Erano
  due dettagli che serie-presenze.md chiede di preservare e che un refactor poteva
  perdere in silenzio, falsando la serie "Conferme 24h" fino al refresh successivo.
- permessi.test.ts copre ora anche il terzo gruppo di DD-023, le tabelle lasciate
  aperte di proposito: scout_sessioni, scout_live, scout_partite e push_subscriptions.
  Non dicono che sono sicure, dicono che sono aperte per scelta: se una prende un gate
  nell'interfaccia, le policy devono seguirlo e questi casi vanno cambiati con loro.
- lettori-server.test.ts esegue leggiEventi() e leggiGiocatoriSquadra() sul database
  locale, mettendo le credenziali in process.env prima della prima chiamata perché
  supabaseAdmin nasce pigramente. Nessuna delle due controlla l'errore di PostgREST:
  una colonna rinominata darebbe zero righe, zero destinatari e nessuna push, senza
  che niente segnali il problema. Scrivendolo è emerso che eventi_app.note è NOT NULL,
  mentre RigaEvento lo dichiara nullable.

PROJECT_STATE: m12_niente_autovoto è applicata in produzione dal 06/09/2026,
verificata con `npx supabase migration list` (23 migration, local = remote).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 19:46:52 +02:00
davideandClaude Opus 5 752b300474 Copre presenze, calendario e guardia admin con nuovi test.
Confrontando le funzioni esportate di src/lib/ con i riferimenti in test/,
le uniche funzioni pure ancora scoperte erano i conteggi presenze, tre
funzioni del calendario, i titoli MVP e i rifiuti della guardia notifiche.

- unit: contaPresenzeGiocatore e totaliEventiGiocatore, compleanniEventi,
  convocatiEvento, eventoVuoto, mvpVintiPerGiocatore, e il nuovo
  auth-route.test.ts sui 401 di richiediAdmin (DD-024);
- integration/permessi: badge_social_voti, che mancava tra le tabelle di M11,
  e le deroghe "Gli admin gestiscono tutti/e ...", mai verificate finora.

Due modifiche al codice servivano per poter scrivere i test:

- presenze.ts: i conteggi leggevano la data da dataOggi() e non erano
  verificabili; ora accettano oggi come parametro opzionale, come già
  facevano serieConsecutiva e serieConferme. Toglie anche la dipendenza
  dall'orologio che avrebbe cambiato i risultati dei test delle serie dal
  10 settembre in poi;
- auth-route.server.ts: "Bearer .." passava il pre-check con tre segmenti
  vuoti e arrivava fino alla chiamata di rete; ora i segmenti devono essere
  non vuoti.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 19:03:18 +02:00
davideandClaude Opus 5 d8f334007b Fa arrivare le push ad app chiusa e rende diagnosticabile quando non arrivano.
Il testo della notifica viaggia ora cifrato dentro la push (aes128gcm, RFC
8188/8291) invece di essere recuperato dal service worker con una fetch al
risveglio. Era quella fetch a non chiudersi in tempo: ad app chiusa il browser
tiene vivo il worker pochi secondi, showNotification non veniva mai chiamata e
non compariva niente, mentre ad app aperta con la rete calda sembrava tutto a
posto. La POST porta anche Urgency: high, che chiede la consegna immediata
invece di far accumulare i messaggi fino al risveglio del dispositivo.

Cadono i pezzi che esistevano solo per rimediare al payload vuoto: la route
push-messaggio, la coda promemoria_push con la sua scadenza a 12 ore,
messaggioPalloniOggi() e il timeout nel worker. Tutti e tre i mittenti avevano
gia il testo pronto prima di inviare.

Il worker si aggiorna da solo all'avvio e a ogni ritorno in primo piano
(mantieniWorkerPushAggiornato): nella webapp installata quello vecchio puo
sopravvivere a lungo, e senza questo un dispositivo resterebbe fermo alla
versione che va a cercare il testo in rete.

Profilo -> Opzioni ha "Mandami una notifica di prova", visibile solo a notifiche
attive: manda una push a questo dispositivo e riporta stato HTTP, corpo della
risposta e se l'endpoint risulta davvero in push_subscriptions. Senza, "non
arriva" era cieco: ogni prova richiedeva un admin, un evento nello stato giusto
e una seconda persona, e la risposta del servizio push veniva buttata via.
inviaPush torna { stato, corpo } e logga il corpo sui rifiuti.

Dalle prove sul campo: a parita di server, iPhone installato da Home riceve ad
app chiusa. Su Android installato come webapp resta da verificare: il WebAPK e
un'app Android a se, con permesso notifiche (Android 13+) e voce batteria
distinti da quelli di Chrome. Annotato nei limiti noti.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 14:24:07 +02:00
davideandClaude Opus 5 847972b582 Chiede le credenziali alle route che avvisano tutta la squadra (DD-024).
Le route in src/routes/api/public/ girano con la service role e saltano la RLS,
quindi DD-023 non le copre. Nessuna faceva un controllo di accesso: cercando
"authorization" in quella cartella l'unico header era lo User-Agent con cui
csi.ts chiama il portale CSI. Chiunque conoscesse l'URL poteva far suonare i
telefoni della squadra, e promemoria-palloni accetta perfino una POST con il
corpo vuoto.

La difesa apparente delle altre due — serve un id evento valido — non è una
difesa: l'id è "e" più il timestamp in base 36, compare negli URL che la squadra
si scambia ed è elencabile da qualsiasi utente loggato.

auth-route.server.ts porta i due controlli, diversi perché i chiamanti sono
diversi. apri-sondaggio e sollecita-presenze usano richiediAdmin: token della
sessione verificato con auth.getUser, poi ruolo admin da user_roles, la stessa
fonte di ruoli.ts. Il controllo precede la validazione dell'input, così la
risposta non rivela nemmeno se un evento esiste. promemoria-palloni usa
richiediSegreto, perché la chiama un cron che una sessione non ce l'ha: se
CRON_SEGRETO non è configurata la route resta chiusa con 503, perché una porta
che si riapre da sola quando manca una variabile non se ne accorge nessuno.

csi, push-config, push-subscribe e push-messaggio restano aperte: le chiamano il
browser prima del login e il service worker, dove qualsiasi segreto finirebbe
nel bundle.

Lato client i due pulsanti admin mandano il token con intestazioniAutenticate(),
letto al momento della chiamata e non da uno stato React.

permessi-route.test.ts copre il giro intero — nessun token, giocatore, admin —
avviando il server di sviluppo puntato al database locale, perché servono utenti
veri. Il controllo positivo è il 404: l'admin supera l'accesso e arriva alla
validazione. In api.test.ts restano i rifiuti che non richiedono un utente e
sparisce la verifica della validazione di sollecita-presenze, che ora sta dietro
all'accesso.

I limiti noti di palloni.md sono aggiornati: il secret che il piano originale
prevedeva ora c'è. Resta vero che nessun cron chiama la route, quindi il
promemoria quotidiano non parte da solo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 12:05:39 +02:00
davideandClaude Opus 5 fe0c938358 Verifica che gli upsert dell'app scrivano sulla riga giusta.
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>
2026-09-06 11:41:26 +02:00
davideandClaude Opus 5 94673090f1 Verifica i permessi per ruolo contro il database Supabase locale.
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>
2026-09-06 11:22:45 +02:00
davideandClaude Sonnet 5 9c173df753 Corregge riferimenti alla migration M3, mai applicata
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>
2026-09-03 11:00:27 +02:00
davideandClaude Sonnet 5 ff45b2379c Aggiunge unit test per i moduli lib rimasti scoperti
Copre la logica pura isolabile di avatar-store, error-capture, error-page,
lovable-error-reporting, profili (validazione upload), push-client (guardie
senza DOM), scout-stato e webpush.server (firma JWT VAPID con chiavi P-256
generate al volo, fetch intercettato). Alza i file di src/lib coperti da 19
a 28 su 37, senza introdurre nuove dipendenze.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 11:34:09 +02:00
davideandClaude Sonnet 5 85223baa9d Formatta la documentazione con prettier
Solo whitespace: tabelle allineate, enfasi normalizzata (* -> _), a capo
coerenti. Nessuna modifica di contenuto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 13:38:56 +02:00
davideandClaude Opus 5 255afde48e Test per profili, ruoli e permessi sul database
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>
2026-08-30 17:58:12 +02:00
davideandClaude Opus 5 c06b33e83b Document how to run the tests.
test/README.md covers the commands, what each folder verifies, whether it
needs the network, and the one real limit: the app renders after
hydration, so the end-to-end tests check HTTP responses and the data
behind the pages, not the rendered interface.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 13:07:59 +02:00