# Handoff — TerManager2 Stato del progetto per chi ci mette mano dopo. Per installazione, deploy e uso quotidiano vedi [README.md](README.md); qui c'è il contesto che il README non può dare: perché le cose sono come sono, e cosa resta aperto. Ultimo aggiornamento: **12 ottobre 2026** — vedi [Lavori in corso](#lavori-in-corso--12-ottobre-2026-riprendere-da-qui). --- ## Stato attuale L'applicazione è **pronta per il deploy in produzione su Dokploy**. Lo stack è stato verificato end-to-end: build dell'immagine, primo deploy su volumi vuoti, redeploy, login, tutte le pagine, code e scheduler. | Aspetto | Stato | |-----------------------------|-------| | Deploy Dokploy (Compose) | ✅ verificato | | Primo avvio a zero-config | ✅ migrazioni + seed + admin automatici | | Redeploy senza interventi | ✅ ~25 secondi | | Sviluppo locale | ✅ stesso compose, profilo `dev` | | Backup / ripristino / azzeramento | ✅ verificati end-to-end in locale | | Ripristino da browser in linea | ⚠️ **limitato a 100 MB da Cloudflare** — vedi [Cosa resta aperto](#cosa-resta-aperto) | | Test automatici | ⚠️ **impalcatura pronta, 294 test** — copertura ancora parziale | **Punto in cui ci si è fermati (30/07/2026).** Su `develop` è pubblicato tutto: backup completo `.zip`, ripristino, azzeramento, cambio password forzato, barre di avanzamento reali e console di log (commit `f909791`, deploy verificato confrontando l'impronta degli asset). `MAX_UPLOAD_MB=2048` è impostato **solo** su develop; la produzione non è stata toccata e resta sul suo deploy precedente, senza quella variabile. **Il 31/07 è nata la sotto-app "Piantine"** (nuova voce nel menu Amministrazione): KML dell'area città, editor dei poligoni su OpenStreetMap, immagini HD dal container `map-renderer` e PDF sul modulo S-12 con storico versioni. Architettura e agganci sono descritti in [Decisioni architetturali](#le-piantine-sono-una-sotto-app-renderer-esterno-agganci-minimi). Al primo deploy il compose costruisce anche l'immagine del renderer; non servono variabili nuove in Dokploy. **Il 28/08 la sotto-app è stata rifatta e l'interfaccia ripassata.** Le piantine si sono staccate dai territori (una piantina vive anche scollegata, il territorio si crea dall'editor), il disegno è passato su una pagina a schermo intero, la cartolina S-12 è stata reimpaginata (confini sulla prima pagina, piantina al 98% sulla seconda) e la rigenerazione massiva è stata rimossa. In più il sistema visivo è stato ripassato su tutta l'applicazione, non solo qui: vedi [Il sistema visivo sta nei token](#il-sistema-visivo-sta-nei-token-non-nelle-viste). Nello stesso giro è emerso e corretto un guasto d'ambiente che bloccava **tutti** gli upload in sviluppo: vedi [`HTTP_HOST` a nginx deve conservare la porta](#http_host-a-nginx-deve-conservare-la-porta). Il 30/07 sono state fatte due cose. **La suite di test, che prima non esisteva**: 79 test eseguibili con un comando, senza dipendere da altri servizi. Sono **verdi** ma coprono ancora una frazione della logica di business — vedi *Cosa resta aperto*. Non fanno parte dell'immagine di produzione e non girano su un deploy: sono uno strumento locale. **La pagina "Backup e import" è stata riorganizzata**: cinque zone numerate con un indice che ci salta sopra evidenziandole, un solo sistema di pulsanti (con gli stati di focus, che prima non c'erano), e **una sola console** per tutte le operazioni, agganciata in fondo alla finestra, al posto dei cinque riquadri di log sparsi. L'azzeramento è diventato un componente a sé per poter stare in fondo alla pagina. Tutto verificato lato server dai test; **il comportamento nel browser — apertura automatica della console, scorrimento, lampeggio delle zone — non è stato provato**, perché richiede un browser: è la prima cosa da guardare aprendo la pagina. Il ripristino dall'interfaccia resta impraticabile per pacchetti grandi finché non si decide come aggirare Cloudflare: è la prima voce di *Cosa resta aperto* e l'unica che richiede una decisione, non del lavoro. --- ## Lavori in corso — 12 ottobre 2026 (riprendere da qui) Commit su `dev`, **nessuno pubblicato** (il push fa partire il deploy sulla demo): - `d433c93` — Modulo S-13 sul modulo ufficiale (regole in `app/Services/Registro/ModuloS13.php`) e blocco 1 della revisione (integrità dati). - `056d95c` — Editor piantine: bozza automatica, un solo "Pubblica" con anteprima, stati Bozza / Pubblicata / Modifiche da pubblicare. Come funziona: [Le piantine sono una sotto-app](#le-piantine-sono-una-sotto-app-renderer-esterno-agganci-minimi). - `426a952` — blocchi 2 e 3 della revisione (sotto); le ultime due righe della tabella sono nel commit successivo. Produzione: al 12/10/2026 non esiste ancora (il sito gira in Docker sul PC di sviluppo, più la demo da `dev`). Nessuna correzione una tantum da fare. ### Posta, contatti dei proclamatori, conferma email (12-13 ottobre 2026) Richieste dell'utente, con le sue scelte: - **Server di posta dall'app** (Impostazioni → Server di posta, rotta `posta.edit`, `Settings\PostaElettronica`): host, porta, cifratura (automatica / SSL / nessuna), utente, password cifrata, mittente; pulsante "Invia email di prova". Se compilato prende il posto del `.env` (`ConfigurazionePosta::applica()`, agganciata alla creazione del mail manager e a ogni job della coda). Non si esporta nell'XML e l'import non la cancella (`Setting::CAMPI_POSTA`). Nel `.env.example` `MAIL_SCHEME=tls` era un valore non valido per Laravel 11: ora vuoto. - **Proclamatori: email e telefono facoltativi**, cifrati come nome e cognome, nell'export/import XML, cancellati dall'anonimizzazione. Il numero apre WhatsApp (``, `Proclamatore::whatsappUrl()`: senza prefisso si considera italiano). - **Dopo l'assegnazione** — *rivisto il 19 ottobre 2026, vedi "Invio del link dopo l'assegnazione" qui sotto*. Il riquadro in sessione (`Assegna::DA_INVIARE`) non esiste più. - **Conferma email obbligatoria** per tutti gli utenti, anche quelli già esistenti (la migrazione `2026_10_13_000010` azzera `email_verified_at`). L'admin crea l'utente con la password come prima; parte l'email di conferma (in italiano, `VerifyEmail::toMailUsing`); il link funziona anche senza login. Cambiare email (profilo o admin) la rende da confermare e rimanda il link. In Utenti: stato "da confermare" e "Reinvia conferma". Raggiungibili senza conferma: profilo, cambio password, pagina di conferma e — per l'amministratore — il server di posta. Emergenza: `php artisan utenti:conferma-email `. Il primo admin creato da riga di comando nasce confermato. - Nei test gli utenti nascono confermati (`tests/TestCase.php`, `$confermaUtentiCreati`). Provato nel browser in locale con mailpit come server configurato dall'app: email di prova e di conferma arrivate, link aperto senza login, account sbloccato; riquadro dopo l'assegnazione con WhatsApp e scelta. Configurazione e dati di prova rimossi dopo. ### Pagina Assegna più leggera; "Vedi tutti" in testata nella Home (19 ottobre 2026) Segnalazione dell'utente: la pagina Assegnazioni era lenta. Misurato su dev con i dati di prod (79 assegnazioni aperte): il server la genera in ~80 ms con 10 query, ma l'HTML pesava **387 KB** (299 l'elenco dei territori assegnati, di cui 58 di icone SVG ripetute; 75 le opzioni dei campi di scelta) e Livewire lo rimandava **per intero a ogni interazione**: scegliere un territorio (anteprima con `wire:model.live`), scrivere nella ricerca dell'elenco (`linkSearch`), aprire l'invio del link. Rimedi: - L'elenco è un componente a sé, `Assegnazioni\ElencoAssegnati`, **lazy**: la pagina mostra subito il form e le sue azioni non lo ridisegnano. "Invia link" nell'elenco chiede alla pagina di aprire l'invio con l'evento `apri-invio` (`Assegna::apriInvio` ha `#[On('apri-invio')]`); `toggleLinkSent` sta nell'elenco. - La ricerca nell'elenco filtra nel browser (`data-cerca` senza accenti, Alpine `elencoCercabile`): nessuna richiesta mentre si scrive. - Il territorio va a Livewire con `wire:model` (non più `.live`): l'anteprima della miniatura segue la scelta nel browser (evento `scelta` di ``, URL della miniatura nelle opzioni). - Righe compatte: icone come simboli SVG definiti una volta e richiamati con ``, classi brevi `tm-assegnato-*` in `app.css` al posto delle catene di utility, `