++ fix e controlli

This commit is contained in:
2026-07-30 17:05:39 +02:00
parent 712336d652
commit 440d63a6b9
54 changed files with 4921 additions and 1322 deletions

View File

@@ -14,7 +14,7 @@ operazione è tracciata in un **audit log** consultabile.
**Per iniziare**
- [Deploy su Dokploy](#deploy-su-dokploy) — la via consigliata per la produzione
- [Deploy su altri sistemi](#deploy-su-altri-sistemi) — Coolify, Portainer, server con Docker
- [Sviluppo locale](#sviluppo-locale)
- [Sviluppo locale](#sviluppo-locale) — compreso come lanciare i [test automatici](#test-automatici)
**Gestione quotidiana**
- [Variabili d'ambiente](#variabili-dambiente)
@@ -302,6 +302,42 @@ npm install
npm run dev
```
### Test automatici
La suite gira in un container dedicato: l'immagine di produzione installa le
dipendenze senza quelle di sviluppo, quindi PHPUnit lì dentro non c'è.
```bash
docker compose --profile test run --build --rm test
# una sola classe
docker compose --profile test run --build --rm test --filter BackupArchiveTest
# un solo gruppo
docker compose --profile test run --build --rm test --testsuite Unit
```
Il container esce col codice di PHPUnit, quindi la riga di comando si incatena
come qualsiasi altro comando.
**`--build` non è facoltativo.** Il sorgente non è montato: senza ricostruire,
si eseguono i test dell'ultima immagine costruita, che possono essere di due
modifiche fa. Ometterlo ha senso solo per rilanciare la stessa suite subito
dopo, quando si sa che nulla è cambiato.
Cosa serve sapere:
- **Non serve nient'altro acceso.** `phpunit.xml` impone SQLite in memoria,
cache `array` e code `sync`: la suite passa a stack spento e non tocca né il
database di sviluppo né il volume `storage_data`.
- **`APP_KEY` di test è fissa e scritta in `phpunit.xml`.** Serve perché nome e
cognome dei proclamatori sono cifrati: senza chiave nemmeno un test che non
parla di cifratura riuscirebbe a scrivere una riga. Non ha alcun rapporto con
la chiave di produzione.
- **SQLite non è MariaDB.** Resta un punto che usa SQL specifico di MySQL —
`CAST(... AS UNSIGNED)` nell'ordinamento del Registro — e che quindi va
provato sullo stack vero, non qui.
---
## Variabili d'ambiente
@@ -398,6 +434,29 @@ Un aggiornamento ordinario non richiede alcun intervento manuale.
## Backup e ripristino
### Com'è fatta la pagina *Backup e import*
Cinque zone numerate, in ordine di quanto sono definitive. L'indice in cima
salta su ciascuna evidenziandola:
| # | Zona | A cosa serve |
|---|------|--------------|
| 1 | Backup completo | Crea e scarica il pacchetto `.zip` |
| 2 | Ripristina da backup | Ricarica un pacchetto: **sostituisce** dati e file |
| 3 | Import PDF territori | Associa i PDF ai territori (da archivio ZIP o da cartella) |
| 4 | Dati in formato XML | Esporta/importa i soli dati, converte i dump della vecchia app |
| 5 | Zona pericolosa | Azzera l'installazione |
In fondo alla finestra c'è **una sola console**, comune a tutte le operazioni:
si apre da sé quando qualcosa parte, scorre da sola man mano che arrivano le
righe e riporta sia quello che succede nel browser (file scelto, avanzamento del
caricamento, codici HTTP, timeout) sia quello che succede sul server, in ordine
di tempo e con la sorgente accanto a ogni riga. Il pulsante **Copia** serve
proprio a questo: il primo passo di ogni diagnosi è farsi mandare quel testo.
Se torni indietro a leggere, lo scorrimento automatico si sospende e compare
*Torna in fondo*.
### Dall'applicazione: pacchetto `.zip` (consigliato)
*Backup e import* → **Crea e scarica backup**. Produce un unico `.zip` con
@@ -405,10 +464,11 @@ tutti i dati gestionali, gli utenti e tutti i file caricati (PDF dei territori,
miniature, logo). È la via da usare per spostare o rimettere in piedi
un'installazione senza toccare i container.
L'archivio si prepara in background e la pagina mostra l'avanzamento reale
L'archivio si prepara in background e la console mostra l'avanzamento reale
(file compressi / file totali); il download parte da solo appena è pronto.
Stessa cosa per il ripristino: prima la barra di caricamento del pacchetto,
poi quella delle fasi di lavoro (estrazione, database, file).
accanto al pulsante, poi le fasi di lavoro nella console (estrazione, database,
file).
Sulla stessa pagina, **Ripristina backup** ricarica il pacchetto: sostituisce i
dati gestionali correnti *e* i file caricati.
@@ -453,20 +513,21 @@ upload lunghissimo da browser è fragile.
> dell'origine; oppure usare il ripristino dai volumi qui sotto. Il piano
> Business arriva a 200 MB, spesso ancora insufficienti.
>
> La **Console** nella scheda di ripristino mostra il codice HTTP ricevuto: se
> La **console** in fondo alla finestra mostra il codice HTTP ricevuto: se
> leggi `413` con un pacchetto sotto `MAX_UPLOAD_MB`, il tetto è a monte.
### Zona pericolosa: azzera tutto
In fondo alla stessa pagina, **Scarica backup e azzera tutto** riporta
Zona 5, in fondo alla stessa pagina: **Scarica backup e azzera tutto** riporta
l'applicazione allo stato di installazione appena eseguita. Va scritto
`AZZERA TUTTO` per sbloccare il pulsante, e l'operazione procede in due tempi:
1. Viene creato e scaricato un backup completo di tutto ciò che c'è.
2. L'operazione **si ferma e aspetta**: controlli il file scaricato, digiti la
**tua password** e confermi con un secondo clic. Fino a lì non viene toccato
nulla, e puoi annullare. Dopo cinque password sbagliate l'azzeramento resta
bloccato per 5 minuti (l'accesso all'applicazione no).
2. L'operazione **si ferma e aspetta**, e la richiesta di conferma compare lì
nella zona 5, sotto il pulsante che l'ha avviata: controlli il file
scaricato, digiti la **tua password** e confermi con un secondo clic. Fino a
lì non viene toccato nulla, e puoi annullare. Dopo cinque password sbagliate
l'azzeramento resta bloccato per 5 minuti (l'accesso all'applicazione no).
3. Solo dopo la conferma vengono eliminati territori, proclamatori,
assegnazioni, campagne, zone, tipologie, anni di servizio, il registro
attività e tutti i file caricati; le impostazioni tornano ai default e i
@@ -824,14 +885,21 @@ TerManager2/
├── docker/
│ ├── nginx/default.conf # Vhost
│ ├── php/
│ │ ├── Dockerfile # Build multi-stage
│ │ ├── Dockerfile # Build multi-stage (runtime = ultimo stage)
│ │ ├── entrypoint.sh # Avvio: chiave, migrazioni, cache
│ │ ├── queue-entrypoint.sh # Avvio worker e scheduler
│ │ ├── php.ini
│ │ └── www.conf
│ └── supervisor/ # nginx + php-fpm nello stesso container
├── resources/ # CSS, JS, viste Blade
├── resources/
│ ├── css/app.css # Sistema di pulsanti, tabelle responsive, console
│ ├── js/
│ └── views/
│ ├── components/btn.blade.php # L'unico pulsante dell'applicazione
│ └── livewire/ # Una vista per componente
├── routes/web.php # Rotte con i relativi permessi
├── tests/ # Suite PHPUnit (profilo compose "test")
├── phpunit.xml # Configurazione e ambiente dei test
├── docker-compose.yml # Unico, produzione e sviluppo
├── .env.example # Tutta la configurazione
├── HANDOFF.md # Stato del progetto per chi subentra