641 lines
26 KiB
Markdown
641 lines
26 KiB
Markdown
# TerManager2 — Specifiche funzionali + istruzioni per container (Laravel)
|
||
|
||
> Documento operativo per realizzare **TerManager2**, applicazione Laravel per la gestione dell’assegnazione/rientro di cartoline territorio, statistiche di percorrenza e campagne speciali.
|
||
>
|
||
> **Obiettivo del documento**: chiarire requisiti, proporre un’architettura “container-ready”, definire modello dati e regole di calcolo, e fornire una **scomposizione in sottotask** con checklist di controllo a fine attività.
|
||
|
||
---
|
||
|
||
## 1) Visione d’insieme
|
||
|
||
**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 nell’anno 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 all’oblio**: 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 (nell’anno 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: l’hash 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)
|
||
- All’avvio 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 (sull’attuale assegnatario).
|
||
|
||
### 5.6 Media mensile di percorrenza (Home)
|
||
Definizione richiesta: media mensile di percorrenza di tutti i territori nell’anno teocratico corrente.
|
||
|
||
Interpretazione operativa (coerente con testo):
|
||
- Per ogni **assegnazione chiusa** (returned_at valorizzato) nell’anno 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 dell’anno teocratico corrente
|
||
- `mesi_trascorsi = numero mesi dall’inizio 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. L’importante è 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 un’assegnazione:
|
||
- 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 dall’anno 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 dell’azione)
|
||
- `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 l’app 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 l’assenza 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 l’intera 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”.
|