Rilettura completa della documentazione confrontata con il codice. Dove la doc diceva il falso l'ho corretta; dove aveva ragione lei ho corretto il codice. Autovoto (la doc aveva ragione) - migration m12_niente_autovoto: vincoli mvp_no_autovoto e badge_social_no_autovoto, gli stessi che pagelle_voti ha dalla v1.0. Le righe che li violano vengono cancellate prima dell'ALTER, altrimenti fallisce; in locale non ce n'erano. M11 garantisce solo che il voto sia firmato con il proprio votante_id, non che il votato sia un altro: eleggersi MVP restava a un POST di distanza. - VotazioneMvp non mostra più il votante nell'elenco, come già faceva VotoSocial. Test che guardavano la colonna sbagliata - scritture.test.ts verificava che aggiornato_il si muovesse, chiamandolo "quello che alimenta la serie di conferme". È l'opposto: la serie usa risposto_il, che il trigger di M9 deve tenere fermo. Ora il test prova a riscriverlo e controlla che il database abbia tenuto la prima risposta; prima passava anche senza trigger. - destinatariSollecito() esce dalla route sollecita-presenze e diventa una funzione pura in presenze.ts, con i suoi test — stesso trattamento di avvisiPalloniEvento. Tre riletture in meno - giocatori-squadra, scout-store e avatar-store usavano invalidateQueries dove il dato scritto era già noto: ora setQueryData, come il resto dell'app. Resta scout-live, dove il lock può averlo vinto un altro dispositivo. Documentazione riallineata - presenze.md, badge.md, mvp.md: i limiti su RLS aperta e route non autenticata erano superati da M11 e DD-024; - serie-presenze.md: il filtro è e.data < oggi, non <=, e l'evento di oggi non conta (conterebbe come assenza per tutti); aggiunta la tabella risposto_il/aggiornato_il; - ARCHITECTURE.md ed EFFICIENZA_CLOUD.md: una sola eccezione a setQueryData; - DATABASE.md: i vincoli delle tre tabelle di voto; - PROJECT_STATE.md: fermo a M9, ora arriva a M12. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.2 KiB
2.2 KiB
Efficienza cloud
Regola di progetto: CrAPP gira su un piano cloud minimo (Supabase + Vercel) per ~17 utenti. Query, traffico e invocazioni vanno tenuti al minimo per costruzione, non ottimizzati dopo.
Regole da rispettare
- Niente polling: mai
refetchIntervalverso il database. Per sincronizzare più schede aperte si usanoBroadcastChannelo gli eventi distorage. - Cache lunga e passiva: i default del
QueryClientstanno insrc/router.tsx(staleTime5 min,gcTime30 min,refetchOnWindowFocus/Mount/Reconnectdisattivati,retry: 1). Non alzare la frequenza di refetch modulo per modulo. - Dopo una mutazione si aggiorna la cache con
setQueryData, non coninvalidateQueries: invalidare costa una rilettura. Unica eccezione:src/lib/scout-live.ts, dove il lock di sessione può essere stato preso da un altro dispositivo e la riga scritta non basta a sapere chi ha vinto. - Scout Live: scrive solo chi sta segnando; gli altri leggono dati già salvati.
- Write once, read many: statistiche, badge e classifiche si calcolano una volta e non
si ricalcolano a ogni apertura di pagina. I badge restano calcolati a runtime dai dati già
in cache, senza query aggiuntive (DD-007):
src/lib/rosa.tsaggrega ciò che è già stato letto. - Push solo per eventi importanti: convocazioni, promemoria allenamento/partita, turno palloni, esito finale.
- Niente funzionalità pesanti: foto, video, chat.
- Indici sui campi usati per filtri e relazioni in ogni nuova migration.
Obiettivi non ancora attuati
Questi punti sono stati definiti come direzione, ma non sono implementati: non descrivono il comportamento attuale.
- Dati CSI: sincronizzazione periodica server-side salvata su una tabella locale, con
l'app che legge solo dal database interno. Oggi la lettura è live dal portale a ogni
richiesta, tramite
/api/public/csi(vedi modules/collegamento-csi.md). - Aggregati persistiti: uno schema con
statistiche_aggregateeclassifica_csiè stato ipotizzato ma non esiste; nessuna di quelle tabelle è insupabase/migrations/. Va valutato con una decisione dedicata, perché tocca DD-007 (badge e statistiche calcolati a runtime).