Un ex sorvegliante puo' guidare un gruppo nuovo: si riattiva la sua
utenza. Il sorvegliante di un gruppo attivo non si cestina ne' si
anonimizza; anonimizzando un ex sorvegliante si anonimizza anche
l'utenza. Nel registro delle attivita' nome ed email dell'utenza del
sorvegliante diventano "proclamatore #id". La voce "Il mio gruppo"
dipende dal ruolo: l'amministratore passa ogni @can.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Migrazione: tolte le colonne email e telefono dei proclamatori (vuote
in produzione). Tolti da form, scheda, elenco, XML (un file vecchio si
importa ignorandoli).
- Invio del link: solo "Copia link" e "Condividi…" (menu di condivisione
del telefono, navigator.share): il destinatario lo sceglie chi usa
l'app. Via WhatsApp diretto, canale email, notifica LinkTerritorio,
componente x-whatsapp.
- Elenco assegnati: "Condividi" al posto di WhatsApp; a condivisione
fatta il link risulta inviato.
- Informativa privacy, README, HANDOFF e test aggiornati.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Gli elenchi tengono ricerca, filtri e ordinamento nell'indirizzo
(#[Url]); la pagina c'era già.
- I link verso schede e operazioni (data-ritorno) portano ?da= con la
pagina di partenza, o il da già ricevuto: si risale all'origine
(elenco -> scheda -> Rientra -> elenco filtrato).
- Ritorno::valida accetta solo percorsi interni: niente rimandi esterni.
- Trait RicordaRitorno: redirect dopo il salvataggio, Annulla e
"Torna indietro" usano la pagina di partenza. Senza da, tutto come prima.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Server di posta in Impostazioni (password cifrata, email di prova): se
compilato prende il posto del .env; non si esporta e l'import XML non lo
cancella. MAIL_SCHEME=tls nel .env.example non era valido per Laravel 11.
- Proclamatori con email e telefono facoltativi, cifrati, nell'XML e
cancellati dall'anonimizzazione; il numero apre WhatsApp.
- Dopo l'assegnazione un riquadro in evidenza con il link del PDF,
"Invia su WhatsApp" con il messaggio pronto e la scelta "inviato /
non ancora", che resta finché non si sceglie.
- Conferma dell'email obbligatoria per tutti gli utenti, anche esistenti:
email in italiano, link valido senza login, nuova conferma a ogni cambio
di indirizzo, "Reinvia conferma" in Utenti. Senza conferma restano
raggiungibili profilo, cambio password e, per l'admin, il server di
posta; comando utenti:conferma-email per l'emergenza.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocco 2
- Esiti delle azioni Livewire come avvisi (trait Avvisa) invece di flash
che comparivano alla pagina dopo.
- PDF, miniature e versioni dei territori non più serviti da nginx su
/storage: TerritorioFileController con login, permessi e cache privata.
- Ripristino tutto o niente: verifica dell'archivio, una transazione con
import, piantine, blocco account e scambio dei file annullabile.
- Backup formato 2 con piantine, storico PDF e area KML.
- Posto unico preso in un passo (Cache::lock) e rispettato anche da
import XML e PDF.
- Import PDF da cartella: abbinamento corretto (1-A, 12 B, ambigui),
caricamento a lotti, file non PDF ignorati, PDF sostituito nello storico.
- L'import XML elimina i file dei territori che non usa più; comando
territori:file-orfani per quelli accumulati prima.
Blocco 3
- Password attuale richiesta al cambio volontario; AuthenticateSession
chiude le sessioni aperte altrove.
- Niente nomi dei proclamatori in chiaro nel registro attività.
- Export XML senza remember_token; chi riceve l'hash dal file deve
cambiare password.
- Campagne: ultimo giorno incluso, percentuale sui territori distinti.
- Coda: retry_after 960 s, stop_grace_period 16m, Redis volatile-lru,
impostazioni rilette a ogni job.
- Azzeramento che cancella anche piantine, area KML e anteprime.
- Pulsanti profilo e menu che non si nascondevano; icona del sito.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
I due piu' gravi potevano causare perdita di dati silenziosa.
AppServiceProvider chiamava key:generate --force a ogni richiesta quando
APP_KEY risultava vuota. Poiche' nome e cognome dei proclamatori sono
cifrati con quella chiave, ogni riga scritta sotto una chiave poi
sostituita diventava irrecuperabile. La chiave e' ora risolta una sola
volta all'avvio del container e il provider solleva un'eccezione se manca,
invece di rigenerarla.
importTerritoryPdfFolder() caricava i PDF, costruiva l'elenco dei file e
poi lo scartava senza mai accodare il job: nessun errore, nessun territorio
aggiornato, e i file restavano su disco a crescita illimitata perche' la
pulizia viveva solo nel finally del job mai eseguito.
Sicurezza:
- i permessi non venivano riapplicati alle richieste /livewire/update, per
cui un permesso revocato restava attivo fino al reload della pagina
- host header injection: nginx passava l'Host del client come
X-Forwarded-Host e Laravel si fidava di tutti i proxy, abbastanza per far
generare a route() link verso domini arbitrari, inclusi i PDF pubblici
che contengono un codice di accesso valido
- lo schema forwarded e' ora deciso dal server e non dall'header del client
- campagna_id in Rientra e' #[Locked]: era derivato lato server ma
manipolabile dal client, permettendo di conteggiare un rientro su una
campagna arbitraria
- sortField del registro passava non validato a orderBy(), con 500 su
colonna inesistente
- SESSION_SECURE_COOKIE ora vale true fuori da local
- limiti su dimensione e numero di voci negli import ZIP
Integrita' e prestazioni:
- il default di assignment_link_ttl_hours era rimasto 24 dopo la
conversione da ore a mesi: i link PDF pubblici duravano due anni invece
di uno mese
- il seeder usava syncPermissions(), che a un secondo giro azzerava i
permessi personalizzati dei ruoli; ora e' additivo
- pdftoppm senza timeout poteva bloccare il worker indefinitamente
- nomi file deterministici nell'import: "1 A" e "1-A" scrivevano sullo
stesso PDF, sovrascrivendosi
- Setting::flushCache() dopo le cancellazioni massive, che non emettono
eventi e lasciavano la cache puntata a una riga inesistente
- riga settings creata dal seeder, per evitare due singleton concorrenti
- rimosse due migrazioni ridondanti che rompevano migrate:rollback
- indici su assigned_at, (attivo, deleted_at) e deleted_at
- risolti gli N+1 negli elenchi territori e proclamatori
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>