++ gruppi: email fittizia iniziale+cognome per il sorvegliante; sciolto il gruppo l'utenza si elimina

- L'utenza del sorvegliante ha un'email fittizia creata dall'app:
  iniziale del nome e cognome @termanager.it (ffontana@termanager.it),
  come gli altri utenti. Via il nome utente: login di nuovo per email.
- Sciolto il gruppo l'utenza si elimina, il sorvegliante torna un
  proclamatore come gli altri: assegnazioni a chi scioglie, registro a nome
  "Sorvegliante del gruppo ...". Via le utenze disattivate.
- User::eliminaConservandoStorico(): l'eliminazione della pagina Utenti in
  un metodo solo, usato anche dallo scioglimento.
- Migrazione 000030: elimina le utenze gia' disattivate, toglie
  users.username e users.disattivato_at, email di nuovo obbligatoria.
- XML, informativa privacy, README, HANDOFF e test aggiornati.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Francesco Picone
2026-10-20 12:09:15 +02:00
parent 69250ecb8c
commit ec2e7bd7e9
26 changed files with 347 additions and 311 deletions

View File

@@ -150,21 +150,12 @@ e non vede nient'altro. Scelte dell'utente:
pacchetti li gestisce **solo l'amministratore**.
- Utenza: password temporanea da cambiare al primo accesso, **senza
conferma dell'email** (`User::hasVerifiedEmail()` è vero per il
sorvegliante). *Dal 20 ottobre: niente email, nome utente dal nome del
gruppo — vedi sotto.*
- **Togliere il ruolo = sciogliere il gruppo** (`GruppiServizio::sciogli`):
non dati in reparto, membri liberi, utenza senza ruolo e disattivata
(`users.disattivato_at`: login rifiutato, sessione aperta chiusa da
`LimitaSorvegliante`). I territori già dati restano ai membri. Si riparte
con un gruppo nuovo. *Dal 20 ottobre il gruppo sciolto si elimina — vedi
sorvegliante). *Dal 20 ottobre l'email è fittizia, creata dall'app — vedi
sotto.*
Casi aggiunti di mio, da far confermare all'utente:
- Un ex sorvegliante può guidare un gruppo nuovo: `crea()` **riattiva** la
sua utenza disattivata (un proclamatore, un'utenza: `users.proclamatore_id`
è unico), con nome utente e password temporanea nuovi.
- `Proclamatore::anonimizza()` anonimizza anche l'utenza dell'ex sorvegliante
(nome, email, password, ruoli).
- **Togliere il ruolo = sciogliere il gruppo** (`GruppiServizio::sciogli`):
non dati in reparto, membri liberi. I territori già dati restano ai membri.
Si riparte con un gruppo nuovo. *Dal 20 ottobre gruppo e utenza del
sorvegliante si eliminano — vedi sotto.*
Decisioni successive dell'utente (20 ottobre 2026):
- **Sorvegliante non più attivo ⇒ gruppo sciolto** e territori non dati
@@ -179,7 +170,7 @@ Decisioni successive dell'utente (20 ottobre 2026):
territori); nel cestino esce dal gruppo.
- **Dettagli nel profilo**: la scheda del proclamatore (`ProclamatoreShow`)
mostra il gruppo che guida con i numeri (`GruppoServizio::riepilogo()`),
l'utenza (nome utente solo all'amministratore, password temporanea o no,
l'utenza (email solo all'amministratore, password temporanea o no,
ultimo accesso dal registro), oppure il gruppo di cui è membro. Il
*Profilo* del sorvegliante mostra il suo gruppo con gli stessi numeri e
"Torna al mio gruppo".
@@ -192,19 +183,33 @@ Decisioni successive dell'utente (20 ottobre 2026):
territorio): **confermato dall'utente il 20 ottobre 2026**. Dopo lo
scioglimento si torna all'elenco dei gruppi; nella scheda del proclamatore
non c'è più "In passato sorvegliante di".
- **Nome utente al posto dell'email**: creando il gruppo non si chiede
l'email; `GruppiServizio::nomeUtente()` ricava `users.username` dal nome
del gruppo (`Str::slug` con il punto: «Gruppo Zisa» → `gruppo.zisa`,
numero in coda se già preso; mai una chiocciola). `users.email` è diventata
facoltativa. Il login ha un solo campo, "Email o nome utente"
(`LoginController`: con la chiocciola cerca l'email, senza il nome utente,
in minuscolo). Dove si mostrava l'email dell'utente ora c'è
`User::identificativo` (email, o nome utente). Il profilo del sorvegliante
mostra il nome utente e non chiede l'email. Il nome del gruppo è unico.
Sciolto il gruppo, il nome utente si libera e l'utenza disattivata prende
`ex.sorvegliante.<id>` (l'anonimizzata `anonimo.<id>`): resta riconoscibile
per l'import XML, che individua gli utenti per email o, senza, per nome
utente. Un gruppo con `<sciolto_at>` in un XML vecchio non si importa.
- **Email fittizia, niente nome utente** (seconda decisione del 20 ottobre,
che sostituisce il nome utente ricavato dal nome del gruppo fatto qualche
ora prima): creando il gruppo l'email non si chiede,
`GruppiServizio::emailFittizia()` la ricava da iniziale del nome e cognome,
minuscoli, senza accenti, spazi né apostrofi, sul dominio
`GruppiServizio::DOMINIO_EMAIL` = `termanager.it` (Francesco Fontana →
`ffontana@termanager.it`, D'Angelo → `fdangelo@…`, numero in coda se già
presa) — la stessa convenzione degli altri utenti. Il login è di nuovo solo
per email. Il profilo del sorvegliante mostra l'email ma non la fa
cambiare. Il nome del gruppo è unico.
- **Sciolto il gruppo, l'utenza del sorvegliante si elimina** ("torna
proclamatore normale, non tenere traccia"): `User::eliminaConservandoStorico()`
— la stessa eliminazione della pagina *Utenti*, ora in un metodo solo — passa
le assegnazioni che aveva fatto o fatto rientrare a chi scioglie (o al primo
amministratore) e lascia le sue voci nel registro a nome "Sorvegliante del
gruppo …", senza email. Niente più utenze disattivate: via
`users.disattivato_at` e i controlli in `LoginController` e
`LimitaSorvegliante`; una sessione aperta resta senza utente.
`Proclamatore::anonimizza()` non tocca più utenze: se era sorvegliante, il
salvataggio scioglie il gruppo e l'utenza sparisce.
- Migrazione `2026_10_20_000030_sorveglianti_con_email_fittizia`: elimina le
utenze già disattivate (assegnazioni al primo amministratore, registro a
nome "Ex sorvegliante di gruppo"), dà l'email fittizia a chi non l'aveva,
toglie `users.username` e `users.disattivato_at`, rende di nuovo
obbligatoria `users.email`. XML: niente più `<username>` né
`<disattivato_at>`; da un file vecchio non si importano le utenze
disattivate né i gruppi con `<sciolto_at>`.
- **Anche i membri si segnalano**: `Proclamatore::gruppo_etichetta`
("Gruppo Zisa" / "Sorvegliante del gruppo Zisa") come badge nell'elenco
(più il filtro *In un gruppo di servizio*, `filtroStato=gruppo`) e in testa
@@ -220,8 +225,8 @@ Decisioni successive dell'utente (20 ottobre 2026):
Dove sta:
- Migrazione `2026_10_20_000010_gruppi_di_servizio`: tabella
`gruppi_servizio`, colonne `gruppo_servizio_id` su proclamatori, territori e
assegnazioni, `users.proclamatore_id` (unico) e `users.disattivato_at`,
permesso `gruppo.gestisci` e ruolo `sorvegliante`. Il seeder dà
assegnazioni, `users.proclamatore_id` (unico) e `users.disattivato_at`
(tolto dalla `000030`), permesso `gruppo.gestisci` e ruolo `sorvegliante`. Il seeder dà
all'amministratore tutti i permessi **tranne** `gruppo.gestisci`.
- Regole in `App\Services\GruppiServizio` (crea, aggiungiMembri, togliMembro,
aggiungiAlPacchetto, rimandaInReparto, assegna, sciogli); i componenti
@@ -238,7 +243,7 @@ Dove sta:
- La voce di menu "Il mio gruppo" guarda il **ruolo**, non `@can`:
l'amministratore passa ogni `@can` (`Gate::before`).
- XML: si esportano e reimportano gruppi, membri, pacchetto, provenienza delle
assegnazioni (id e nome del gruppo), nome utente e legame utenza ↔
assegnazioni (id e nome del gruppo) e legame utenza ↔
proclamatore.
- Informativa privacy aggiornata (utenza del sorvegliante, gruppo tra i dati
del proclamatore).