Files
termanager2/TerManager2_v2.md
Francesco Picone 701f479b7f Primo commit
2026-04-05 19:26:04 +02:00

641 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TerManager2 — Specifiche funzionali + istruzioni per container (Laravel)
> Documento operativo per realizzare **TerManager2**, applicazione Laravel per la gestione dellassegnazione/rientro di cartoline territorio, statistiche di percorrenza e campagne speciali.
>
> **Obiettivo del documento**: chiarire requisiti, proporre unarchitettura “container-ready”, definire modello dati e regole di calcolo, e fornire una **scomposizione in sottotask** con checklist di controllo a fine attività.
---
## 1) Visione dinsieme
**TerManager2** gestisce:
- **Territori** (cartoline) con PDF, stato (in reparto / assegnato / da rientrare / prioritario / inattivo) e proprietà (Zona, Tipologia, ecc.).
- **Proclamatori** (assegnatari) con dati **illeggibili in DB** (cifratura applicativa a livello di colonna) e gestione **GDPR**.
- **Assegnazioni** con data assegnazione/rientro, teocratic year, opzionale “conteggio campagna”.
- **Campagne** (periodi speciali) con percentuali di percorrenza e dashboard.
- **Statistiche** (media mensile di percorrenza nellanno teocratico, indicatori di giacenza e “smarriti”).
**Ruoli (RBAC)**:
- **Amministratore**: tutto (impostazioni, territori, proclamatori, campagne, registro, proprietà territorio, assegnazione/rientro).
- **Assistente**: proclamatori, campagne, assegnazione/rientro.
- **Operatore**: assegnazione/rientro.
---
## 2) Requisiti non funzionali (sicurezza, GDPR, UX)
### 2.1 Sicurezza e dati illeggibili in DB
Requisito: i dati dei proclamatori devono risultare **illeggibili** se si accede direttamente al database.
**Scelta consigliata (Laravel)**:
- Password utente: **hash** (bcrypt/argon2id) (standard Laravel).
- Dati sensibili (nome, cognome, eventuali note): **cifratura applicativa per colonna**.
- Usare **Laravel Eloquent encrypted casts** (es. `protected $casts = ['nome' => 'encrypted', ...];`) oppure un **Custom Cast** che cifri/decifri con AES-256-GCM.
- La chiave di cifratura è `APP_KEY` (gestita come secret in ambiente). **Mai** versionarla.
**Nota importante**: la cifratura applicativa protegge “a riposo” nel DB. Per un livello ulteriore:
- cifrare anche **backup**;
- considerare cifratura volume/disco a livello host.
### 2.2 GDPR — criteri base da rispettare
Implementare almeno:
- **Minimizzazione**: salvare solo ciò che serve (nome/cognome e stato attivo).
- **Ruoli e autorizzazioni**: accesso ai dati solo per chi ha permessi.
- **Audit trail**: log di operazioni critiche (creazione/modifica/eliminazione, assegnazione/rientro, cambio stato territorio).
- **Retention**: definire policy su conservazione storici (es. registro assegnazioni conservato per X anni — parametro impostazioni).
- **Diritto alloblio**: possibilità di **disattivare/anonimizzare** un proclamatore (senza rompere lo storico).
- **Esportazione**: esportazione dati (CSV/PDF) su richiesta (opzionale ma consigliato).
- **Consenso e informativa**: pagina “Privacy / Informativa” e log di accettazione (se necessario al contesto).
### 2.3 UI/UX
- Responsive “mobile-first” (smartphone/tablet), grafica minimale e moderna.
- Layout con:
- header con logo + congregazione;
- menu laterale (collassabile su mobile);
- contenuti centrali con card e tabelle filtrabili.
Tecnologie UI consigliate:
- **TailwindCSS** + **Livewire** (rapido, server-driven) **oppure** Inertia + Vue/React.
- Componenti: ricerca veloce, paginazione, badge di stato, drawer per dettagli.
---
## 3) Architettura applicativa (Laravel)
### 3.1 Componenti
- Laravel (>=10) con:
- Auth (Breeze/Jetstream o Fortify) + **RBAC** (Spatie Laravel Permission consigliato).
- DB: MySQL/MariaDB o PostgreSQL.
- Storage: `storage/app` per PDF (in dev) + volume Docker; in produzione valutare S3/MinIO.
- Queue: Redis (opzionale ma utile per report/esportazioni).
- Scheduler: `artisan schedule:work` per job (es. calcoli, pulizie, report).
### 3.2 Concetti chiave di dominio
- **Anno teocratico**: da **Settembre** (anno precedente) ad **Agosto** (anno corrente).
- **Percorrenza**: giorni tra assegnazione e rientro (nellanno teocratico corrente) aggregati e convertiti in media mensile.
- **Campagna**: periodo con start/end; a ogni rientro si chiede se quel rientro conta per la campagna (anche retroattivo se assegnato durante il periodo ma rientrato dopo).
---
## 4) Modello dati (proposta)
> I nomi campi sono indicativi; adeguare naming (snake_case) e indici.
### 4.1 Tabelle
#### `users`
- auth utenti app (admin/assistente/operatore)
- campi standard Laravel (`email`, `password`, `name`, ecc.).
#### `roles`, `permissions`, `model_has_roles`, ...
- se si usa Spatie Permission.
#### `settings`
- configurazioni globali:
- `congregazione_nome`
- soglia `giorni_giacenza_da_assegnare`
- soglia `giorni_giacenza_prioritari`
- soglia `giorni_per_smarrito`
- `home_limit_list` (default 10)
- altre.
#### `proclamatori`
- `id`
- `nome` **encrypted**
- `cognome` **encrypted**
- `attivo` boolean
- timestamps
> (Opzionale) `display_name_hash` per ricerche rapide senza decifrare tutto (hash normalizzato di nome+cognome). Attenzione: lhash può comunque essere dato personale; trattarlo come tale.
#### `territori`
- `id`
- `numero` (string/int) **univoco**
- `zona_id`
- `tipologia_id`
- `note` (text)
- `confini` (text)
- `pdf_path` (string)
- `attivo` boolean
- `prioritario` boolean
- timestamps
#### `zone` e `tipologie`
- `id`, `nome`, `attivo`.
#### `anni_teocratici`
- `id`
- `label` (es. `2025-2026`)
- `start_date` (1 settembre)
- `end_date` (31 agosto)
- univoco per `label`.
#### `campagne`
- `id`
- `start_date`
- `end_date`
- `descrizione`
- `attiva` (derivabile da date, ma può essere utile una view/flag)
- timestamps
#### `assegnazioni`
- `id`
- `territorio_id`
- `proclamatore_id`
- `anno_teocratico_id`
- `assigned_at`
- `returned_at` (nullable)
- `counted_in_campaign` boolean nullable (null = non chiesto/non applicabile)
- `campaign_id` nullable (se conteggiata)
- `note` nullable
- `created_by` (user_id)
- `returned_by` (user_id) nullable
- timestamps
#### `audit_logs` (o `activity_log`) — per pagina Log attività
- tabella dedicata a tracciare azioni utenti (vedi §6.7)
- se si usa un pacchetto, mantenere naming/colonne del pacchetto; altrimenti creare tabella custom.
### 4.2 Vincoli e indici (essenziali)
- `territori.numero` unique
- `assegnazioni`:
- indice su (`territorio_id`, `returned_at`)
- indice su (`proclamatore_id`, `returned_at`)
- indice su (`anno_teocratico_id`)
- integrità referenziale con `ON DELETE CASCADE` dove sensato.
- **Attenzione**: requisito: eliminazione territorio => eliminazione su tutto il registro assegnazioni. Quindi `assegnazioni.territorio_id` con cascade.
---
## 5) Regole di business e calcoli
### 5.1 Anno teocratico (creazione automatica)
- Allavvio Home o in fase di assegnazione/rientro:
1. determinare data odierna;
2. se mese >= 9 (settembre) -> anno teocratico = `anno_corrente-anno_corrente+1`;
3. se mese <= 8 -> anno teocratico = `anno_corrente-1-anno_corrente`;
4. se non esiste in DB, crearlo con start_date=1/09 e end_date=31/08.
### 5.2 Stato territorio
- **In reparto**: nessuna assegnazione aperta (ultima assegnazione `returned_at` non null) e attivo.
- **Assegnato a X**: esiste assegnazione aperta (`returned_at` null).
- **Smarrito / da rientrare**: assegnazione aperta da più giorni rispetto a `settings.giorni_per_smarrito`.
- **Prioritario**: flag `prioritario=true` oppure giacenza in reparto > soglia `giorni_giacenza_prioritari`.
- **Inattivo**: `attivo=false` (non assegnabile).
### 5.3 “Territori da assegnare” (Home)
- Territori **in reparto** con giacenza > `giorni_giacenza_da_assegnare`.
- Mostrare primi N (`home_limit_list`).
- Azione: assegnazione rapida a proclamatore.
### 5.4 “Territori prioritari” (Home)
- Territori in reparto con giacenza > `giorni_giacenza_prioritari` **oppure** `prioritario=true`.
- Azione: assegnazione rapida.
### 5.5 “Territori da rientrare” (Home)
- Territori con assegnazione aperta da più giorni di `giorni_per_smarrito`.
- Azione: rientro rapido (sullattuale assegnatario).
### 5.6 Media mensile di percorrenza (Home)
Definizione richiesta: media mensile di percorrenza di tutti i territori nellanno teocratico corrente.
Interpretazione operativa (coerente con testo):
- Per ogni **assegnazione chiusa** (returned_at valorizzato) nellanno teocratico corrente:
- `giorni = returned_at - assigned_at` (in giorni, >=0)
- Sommare tutti i `giorni` e normalizzare su base mensile.
Proposta formula (trasparente e verificabile):
- `giorni_totali = Σ giorni` per tutte le assegnazioni chiuse dellanno teocratico corrente
- `mesi_trascorsi = numero mesi dallinizio anno teocratico a oggi (min 1)`
- `media_mensile = giorni_totali / mesi_trascorsi`
> Alternativa: media per territorio o per assegnazione; scegliere una e documentarla in impostazioni. Limportante è che sia consistente e testata.
### 5.7 Campagne (Home + Tab Campagne)
- Campagna attiva se `today` tra `start_date` e `end_date`.
- Percentuale percorrenza campagna:
- `territori_percorsi_in_campagna / territori_totali_pertinenti`.
Chiarimento necessario per “totali pertinenti”: suggerito:
- denominatore = numero di territori rientrati **conteggiati campagna** durante il periodo **+** territori assegnati nel periodo ma non ancora rientrati? (da definire).
Per evitare ambiguità e mantenere semplice:
- **Proposta**: percentuale = (numero assegnazioni chiuse conteggiate campagna) / (numero assegnazioni chiuse totali che hanno `assigned_at` nel range campagna) * 100.
#### Avviso rientro “con o senza campagna” (retroattivo)
Alla chiusura di unassegnazione:
- se esiste campagna tale che `assigned_at` è compreso nel range campagna **(anche se oggi è dopo end_date)**, mostrare prompt:
- “Questo rientro conta per la campagna X?”
- se sì: `counted_in_campaign=true` e `campaign_id`.
- se no: `counted_in_campaign=false`.
- se non applicabile: lasciare null.
#### Vista “territori percorsi e in quanto tempo”
Per campagna selezionata:
- lista assegnazioni conteggiate in campagna con:
- territorio, proclamatore (mostrato in chiaro solo in UI), assigned_at, returned_at, giorni.
---
## 6) Pagine e funzionalità (corrette/riordinate)
### 6.1 Wizard iniziale (primo avvio)
Se mancano impostazioni base (`settings` vuoto):
- Step 1: Nome congregazione + logo (upload).
- Step 2: soglie (giacenza, prioritari, smarrito) + limite liste Home.
- Step 3: conferma e creazione admin (se necessario).
### 6.2 Home
Header:
- sinistra: logo + nome congregazione
- destra: nome utente + ruolo + logout
Sidebar:
- voci variabili in base ai permessi.
Contenuto centrale:
1) **Anno teocratico in corso** (auto-creazione se non esiste)
2) **Media mensile di percorrenza** (anno teocratico corrente)
3) **Campagna in corso** (se attiva): descrizione + percentuale + pulsante “Dettagli in tempo reale”
4) **Assegnazione rapida** (3 colonne/zone):
- Territori da assegnare
- Territori prioritari
- Territori da rientrare
Ogni lista:
- mostra top N
- ricerca veloce
- pulsante “Vedi tutti” (pagina completa con filtri)
### 6.3 Gestione Territori
Lista filtrabile con colonne:
- Numero
- Zona / Tipologia
- Stato (badge)
- Ultimo rientro
- Azioni: Visualizza / Modifica / Elimina / Attiva-Disattiva
Dettaglio territorio (“Visualizza”):
- dati completi + PDF viewer
- storico assegnazioni raggruppato per anno teocratico
Regole:
- Eliminazione territorio => rimuove anche tutte le assegnazioni (cascade).
- Territorio inattivo non è assegnabile e non appare nelle liste “da assegnare/prioritari” (a meno di filtro admin).
### 6.4 Gestione Proclamatori
Lista filtrabile:
- Proclamatore (nome/cognome decifrati in UI)
- Attivo
- Territori attualmente in assegnazione (conteggio + link)
- Azioni: Visualizza / Modifica / Elimina / Disattiva
Regole consigliate:
- Eliminazione fisica solo se nessuno storico (oppure prevedere “anonimizza”).
### 6.5 Gestione Campagne
- Form creazione campagna (start, end, descrizione)
- Evidenza campagna attiva
- Elenco campagne completate (indipendente dallanno teocratico)
- Dettaglio: elenco assegnazioni conteggiate, tempi, export.
### 6.6 Registro assegnazioni
Lista filtrabile per:
- anno teocratico
- territorio
- zona
- tipologia
- proclamatore
Output:
- tabella con assegnazioni (assegnato, rientrato, giorni, campagna sì/no)
- export CSV/PDF (opzionale)
### 6.7 Log attività (Audit trail) — **REQUISITO OBBLIGATORIO**
> Deve essere disponibile una **pagina di log** che riporti **tutte le azioni degli utenti** (Amministratore, Assistente, Operatore) e in particolare le operazioni di:
> - **Assegnazione** territorio
> - **Rientro** territorio (con/senza campagna)
> - **Creazione / modifica / cancellazione** di: Territori, Proclamatori, Campagne, Zone, Tipologie, Impostazioni
> - **Attiva/Disattiva** territorio o proclamatore
> - **Upload / sostituzione / eliminazione** PDF territorio
> - (Consigliato) **Login/Logout**, tentativi falliti, export dati
#### 6.7.1 Scopo
- Tracciabilità e accountability (chi ha fatto cosa e quando).
- Supporto a sicurezza e requisiti GDPR (audit delle operazioni sui dati).
#### 6.7.2 Permessi di accesso alla pagina log
- **Visualizzazione log**: `audit.view` (almeno Amministratore).
- Opzionale: consentire anche ad Assistente una vista “limitata” (solo eventi di assegnazione/rientro e senza IP/user-agent).
- **Esportazione log**: `audit.export` (solo Amministratore).
#### 6.7.3 Dati minimi da registrare per ogni evento
Registrare per ogni azione:
- `id`
- `created_at` (data/ora evento)
- `causer_user_id` (utente che ha eseguito)
- `causer_role_snapshot` (ruolo al momento dellazione)
- `event` (es. `created`, `updated`, `deleted`, `assigned`, `returned`, `activated`, `deactivated`, `uploaded_pdf`)
- `subject_type` + `subject_id` (entità coinvolta: Territorio/Proclamatore/Campagna/Assegnazione/Setting...)
- `description` (testo leggibile)
- `properties` (JSON) con dettagli evento:
- **prima/dopo** per update (diff campi)
- motivazioni/flag (es. `counted_in_campaign=true`)
- valori di soglia usati in calcoli/decisioni (se rilevanti)
- (Consigliato) `ip_address` e `user_agent` (dato personale → retention e minimizzazione)
> Nota GDPR: retention configurabile (es. 365/730 giorni). Evitare di salvare nei log dati sensibili in chiaro non necessari: per Proclamatori salvare `proclamatore_id` e non nome/cognome.
#### 6.7.4 Implementazione consigliata (senza vincoli)
- È possibile implementare il log con tabella custom (`audit_logs`) oppure usare un pacchetto dedicato.
- Scelta spesso adottata in Laravel: **spatie/laravel-activitylog** per logging automatico su modelli + logging manuale per eventi “di flusso” (assegnazione/rientro).
#### 6.7.5 UI pagina Log
Funzioni minime:
- Tabella: Data/Ora, Utente, Ruolo, Azione, Oggetto, Esito, Dettagli.
- Filtri: date, utente, ruolo, tipo evento, entità.
- Dettaglio evento (drawer/modal): diff before/after + metadati.
- Paginazione + ricerca veloce.
---
## 7) Containerizzazione (Docker) — sviluppo e produzione
### 7.1 Struttura consigliata repository
```
termanager2/
docker/
nginx/
default.conf
php/
Dockerfile
php.ini
.env.example
docker-compose.yml
composer.json
package.json
...
```
> In dev si può usare `npm run dev` in un container separato o sul host.
### 7.6 Produzione (note rapide)
- Impostare `APP_ENV=production`, `APP_DEBUG=false`.
- Usare immagini “buildate” senza montare volume codice.
- Gestire segreti con Docker secrets o secret manager.
- Abilitare HTTPS con reverse proxy (Traefik/Nginx) e HSTS.
- Backup cifrati e rotazione.
---
## 8) RBAC: permessi e gating UI
Definire permessi granulari (anche se i ruoli sono solo 3):
- `settings.manage`
- `proclamatori.manage`
- `territori.manage`
- `campagne.manage`
- `registro.view`
- `territori.assign`
- `territori.return`
- `audit.view`
- `audit.export` (opzionale)
Mappatura ruoli:
- Admin: tutti (incluso `audit.view` e opzionale `audit.export`)
- Assistente: proclamatori.manage, campagne.manage, territori.assign, territori.return
- Operatore: territori.assign, territori.return
Applicare:
- Middleware route (`can:` / `role:` / `permission:`)
- Condizionali menu sidebar
## 8-bis) API routes / schermate (URL, metodi, middleware)
> Nota: di seguito sono indicate **route Web** (UI) e (opzionalmente) **route API**. Anche se lapp nasce “web”, formalizzare le route aiuta a:
> - applicare correttamente `auth` + permessi,
> - mantenere coerenza tra schermate e controller,
> - facilitare test e manutenzione.
### 8-bis.1 Convenzioni middleware
- `auth` su tutte le rotte applicative.
- `permission:<permesso>` (o `can:<permesso>`) per schermate/azioni.
- `throttle` (consigliato) su login e su endpoint di export.
### 8-bis.2 Mappa schermate principali
- **Home/Dashboard**: `/` (GET)
- **Wizard iniziale**: `/setup/*` (GET/POST)
- **Territori**: `/territori` (lista), `/territori/create`, `/territori/{id}` (dettaglio), `/territori/{id}/edit`
- **Proclamatori**: `/proclamatori` + CRUD
- **Campagne**: `/campagne` + CRUD + dettaglio
- **Registro**: `/registro` (filtri)
- **Audit log**: `/audit` (lista) + `/audit/{id}` (dettaglio)
### 8-bis.3 Route Web (UI) — dettaglio
#### Autenticazione
- `GET /login` → form login | middleware: `guest`
- `POST /login` → login | middleware: `guest`, `throttle:login`
- `POST /logout` → logout | middleware: `auth`
#### Wizard iniziale (primo avvio)
- `GET /setup` → step 1 | middleware: `setup.required`
- `POST /setup/step-1` → salva congregazione | middleware: `setup.required`
- `POST /setup/step-2` → salva soglie | middleware: `setup.required`
- `POST /setup/finish` → completa setup | middleware: `setup.required`
> `setup.required` è un middleware custom che intercetta lassenza di settings e forza il wizard.
#### Home
- `GET /` → dashboard | middleware: `auth`
#### Territori
- `GET /territori` → lista | middleware: `auth`, `permission:territori.manage`
- `GET /territori/create` → form create | middleware: `auth`, `permission:territori.manage`
- `POST /territori` → store | middleware: `auth`, `permission:territori.manage`
- `GET /territori/{territorio}` → dettaglio | middleware: `auth`, `permission:territori.manage`
- `GET /territori/{territorio}/edit` → form edit | middleware: `auth`, `permission:territori.manage`
- `PUT /territori/{territorio}` → update | middleware: `auth`, `permission:territori.manage`
- `DELETE /territori/{territorio}` → delete (cascade assegnazioni) | middleware: `auth`, `permission:territori.manage`
- `PATCH /territori/{territorio}/toggle-active` → attiva/disattiva | middleware: `auth`, `permission:territori.manage`
- `PATCH /territori/{territorio}/toggle-priority` → prioritario sì/no | middleware: `auth`, `permission:territori.manage`
- `POST /territori/{territorio}/pdf` → upload/sostituzione PDF | middleware: `auth`, `permission:territori.manage`
- `DELETE /territori/{territorio}/pdf` → rimuovi PDF | middleware: `auth`, `permission:territori.manage`
#### Proclamatori
- `GET /proclamatori` → lista | middleware: `auth`, `permission:proclamatori.manage`
- `GET /proclamatori/create` → form create | middleware: `auth`, `permission:proclamatori.manage`
- `POST /proclamatori` → store | middleware: `auth`, `permission:proclamatori.manage`
- `GET /proclamatori/{proclamatore}` → dettaglio | middleware: `auth`, `permission:proclamatori.manage`
- `GET /proclamatori/{proclamatore}/edit` → form edit | middleware: `auth`, `permission:proclamatori.manage`
- `PUT /proclamatori/{proclamatore}` → update | middleware: `auth`, `permission:proclamatori.manage`
- `DELETE /proclamatori/{proclamatore}` → delete/anonimizza (policy) | middleware: `auth`, `permission:proclamatori.manage`
- `PATCH /proclamatori/{proclamatore}/toggle-active` → attiva/disattiva | middleware: `auth`, `permission:proclamatori.manage`
#### Campagne
- `GET /campagne` → lista + campagna attiva | middleware: `auth`, `permission:campagne.manage`
- `GET /campagne/create` → form create | middleware: `auth`, `permission:campagne.manage`
- `POST /campagne` → store | middleware: `auth`, `permission:campagne.manage`
- `GET /campagne/{campagna}` → dettaglio + tempi real-time | middleware: `auth`, `permission:campagne.manage`
- `GET /campagne/{campagna}/edit` → form edit | middleware: `auth`, `permission:campagne.manage`
- `PUT /campagne/{campagna}` → update | middleware: `auth`, `permission:campagne.manage`
- `DELETE /campagne/{campagna}` → delete | middleware: `auth`, `permission:campagne.manage`
#### Assegnazioni (azioni core)
- `POST /assegnazioni/assign` → assegna territorio a proclamatore | middleware: `auth`, `permission:territori.assign`
- `POST /assegnazioni/{assegnazione}/return` → rientro territorio | middleware: `auth`, `permission:territori.return`
> Nota: `assign` e `return` devono sempre scrivere su **audit log**.
#### Registro
- `GET /registro` → lista filtrabile | middleware: `auth`, `permission:registro.view`
- (Opzionale) `GET /registro/export` → export | middleware: `auth`, `permission:registro.export`
#### Audit log
- `GET /audit` → lista log | middleware: `auth`, `permission:audit.view`
- `GET /audit/{log}` → dettaglio log | middleware: `auth`, `permission:audit.view`
- (Opzionale) `GET /audit/export` → export | middleware: `auth`, `permission:audit.export`
### 8-bis.4 Route API (opzionali, se si usa UI “dinamica”)
> Se si adotta Livewire spesso bastano le Web route. Se si usa SPA (Inertia/Vue/React) o si vuole un frontend più interattivo, prevedere API JSON:
- `GET /api/territori?filters=...` | `auth:sanctum`, `permission:territori.manage`
- `GET /api/home/quicklists` | `auth:sanctum`
- `POST /api/assegnazioni/assign` | `auth:sanctum`, `permission:territori.assign`
- `POST /api/assegnazioni/{id}/return` | `auth:sanctum`, `permission:territori.return`
- `GET /api/campagne/{id}/realtime` | `auth:sanctum`, `permission:campagne.manage`
---
## 9) Checklist di funzionalità (con sottotask e ricontrollo)
> Regola di lavoro: **ogni funzionalità va spezzata in sottotask**, ognuno con test + verifica UI. A completamento, ricontrollare lintera funzionalità end-to-end.
### EPIC A — Setup progetto e base security
**Sottotask**
1. Creazione progetto Laravel + repo + CI base (lint/test).
2. Setup Auth (login/logout) + password policy.
3. Setup RBAC (ruoli/permessi) + seed iniziale admin.
4. Setup cifratura colonne proclamatori + test round-trip.
5. Logging audit (azioni critiche) + retention log.
**Ricontrollo (DoD)**
- Login funziona, utenti e ruoli corretti.
- Dati proclamatori illeggibili in DB (verifica diretta tabella).
- Rotte protette da permessi.
### EPIC B — Wizard iniziale + Settings
**Sottotask**
1. Model/settings + migrazione.
2. Wizard UI 3 step + validazione.
3. Blocco app finché wizard non completato (redirect).
**Ricontrollo**
- Primo avvio porta al wizard.
- Home mostra logo/nome congregazione.
### EPIC C — Gestione Territori
**Sottotask**
1. Tabelle territori/zone/tipologie + seed.
2. CRUD territori + upload PDF.
3. Lista filtrabile + badge di stato.
4. Dettaglio con PDF viewer + storico per anno teocratico.
5. Attiva/disattiva + prioritario.
6. Delete con cascade su assegnazioni.
**Ricontrollo**
- Stati corretti e coerenti.
- PDF visibile e scaricabile.
- Eliminazione rimuove storico come richiesto.
### EPIC D — Gestione Proclamatori
**Sottotask**
1. CRUD proclamatori (encrypted fields).
2. Lista con filtro + indicazione territori assegnati.
3. Disattivazione / (opzionale) anonimizzazione.
**Ricontrollo**
- Dati illeggibili in DB.
- Non assegnabile se attivo=false.
### EPIC E — Assegnazione e rientro (core)
**Sottotask**
1. Flusso assegnazione: selezione territorio + proclamatore + conferma.
2. Prevenire doppia assegnazione (vincolo logico).
3. Flusso rientro: chiusura assegnazione + calcolo giorni.
4. Prompt campagna (retroattivo) al rientro.
5. Audit: created_by/returned_by.
**Ricontrollo**
- Un territorio non può avere due assegnazioni aperte.
- Prompt campagna compare quando dovuto.
### EPIC F — Home Dashboard
**Sottotask**
1. Calcolo anno teocratico corrente + autocreazione.
2. Calcolo media mensile percorrenza.
3. Liste rapide (da assegnare/prioritari/da rientrare) con filtri e “vedi tutti”.
4. UI responsive.
**Ricontrollo**
- Numeri coerenti con registro.
- Liste mostrano gli stessi risultati delle pagine complete.
### EPIC G — Campagne
**Sottotask**
1. CRUD campagne.
2. Indicazione campagna attiva.
3. Percentuale e dettaglio “in tempo reale”.
4. Lista campagne completate.
**Ricontrollo**
- Retroattività corretta.
- Dettaglio mostra tempi e territori.
### EPIC H — Registro e statistiche
**Sottotask**
1. Vista registro per territorio con filtri richiesti.
2. Export (opzionale).
3. Test prestazioni su query con indici.
**Ricontrollo**
- Filtri corretti.
- Dati coerenti con assegnazioni.
### EPIC I — Audit Log (pagina log e tracciamento eventi)
**Sottotask**
1. Definizione eventi da loggare (CRUD + flussi assegnazione/rientro + login/logout opzionale).
2. Implementazione persistenza log (tabella custom o activity log) + migrazioni.
3. Hook automatici su modelli (created/updated/deleted) e log manuali per `assign/return`.
4. Pagina `/audit` con filtri, paginazione, dettaglio evento (before/after).
5. RBAC: `audit.view` e (opzionale) `audit.export`.
6. Retention configurabile + job scheduler (opzionale) per pulizia log.
**Ricontrollo**
- Ogni operazione critica genera un record log.
- Il log non espone dati sensibili non necessari (es. nomi proclamatori in chiaro nei properties).
- Filtri e dettaglio mostrano correttamente chi/cosa/quando e diff.
---
## 10) Test consigliati
- **Unit test**: calcolo anno teocratico, stati territorio, logica campagne.
- **Feature test**: RBAC per pagina, assegnazione/rientro, wizard.
- **Security test**: accesso non autorizzato, CSRF, rate limit login.
- **UX test**: mobile viewport, tabelle filtrabili, azioni rapide.
- **Audit test**: ogni create/update/delete e assign/return produce log con subject/causer corretti.
---
## 11) “Done” globale (criteri di completamento)
- Tutte le funzionalità richieste presenti e testate.
- Responsività verificata su smartphone/tablet.
- Dati proclamatori cifrati e illeggibili in DB.
- Log operazioni critiche + policy di retention.
- Backup e gestione segreti definiti (per produzione).
---
### Allegato — Note di chiarezza (minime)
- La formula di “media mensile” e la definizione di denominatore percentuale campagna vanno **documentate** e rese consistenti con i test.
- La cancellazione territorio con cascade è conforme al requisito, ma valutare impatto GDPR/contabile: in alternativa soft-delete + “nascondi dallo storico”.