++ gruppi: l'assegnazione dal pacchetto rilegge territorio e membro, e ricontrolla il pacchetto sotto lock

HANDOFF: trappola di Blade sul @php in linea, test sul server prima del push.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Francesco Picone
2026-10-19 18:00:45 +02:00
parent 93bc9cf2fe
commit 9999a3b031
2 changed files with 23 additions and 2 deletions

View File

@@ -195,7 +195,11 @@ Dove sta:
assegnazioni e il legame utenza ↔ proclamatore. assegnazioni e il legame utenza ↔ proclamatore.
- Informativa privacy aggiornata (utenza del sorvegliante, gruppo tra i dati - Informativa privacy aggiornata (utenza del sorvegliante, gruppo tra i dati
del proclamatore). del proclamatore).
- Test: `tests/Feature/GruppiServizioTest.php`. - L'azzeramento dell'applicazione (*Zona pericolosa*) cancella anche i gruppi.
- Test: `tests/Feature/GruppiServizioTest.php`. Eseguiti sul server **prima**
del push, su una copia della checkout di dev con i commit portati da un
`git bundle` (la checkout di Dokploy è shallow: il bundle deve partire dal
commit che ha, `git log -1` lì dentro).
Non provato nel browser. **In produzione non c'è**: serve l'ok dell'utente. Non provato nel browser. **In produzione non c'è**: serve l'ok dell'utente.
@@ -1628,6 +1632,14 @@ stringa invece di proteggere l'apostrofo, perché fra il file e l'attributo non
c'è alcun livello di escape. Regole: nessuna virgoletta doppia in quel blocco, c'è alcun livello di escape. Regole: nessuna virgoletta doppia in quel blocco,
da nessuna parte; apostrofi italiani solo dentro backtick. da nessuna parte; apostrofi italiani solo dentro backtick.
**In una vista Blade la forma in linea `@php(...)` non va messa prima di un
blocco `@php … @endphp`.** Blade estrae i blocchi `@php … @endphp` per primi,
con un'espressione che parte dalla prima `@php` che trova: se è quella in
linea, ingoia tutto fino al primo `@endphp` e la vista non compila più
("unexpected token class"). Successo in *Il mio gruppo* il 19/10/2026. E
vale anche dentro i commenti `{{-- --}}`, che Blade toglie *dopo*: lì la
parola `@php` non va scritta.
Un blocco `<script>` con `@script` eviterebbe la questione alla radice, ma Un blocco `<script>` con `@script` eviterebbe la questione alla radice, ma
**rompe il rilevamento della radice singola di Livewire** e restituisce 500 — **rompe il rilevamento della radice singola di Livewire** e restituisce 500 —
provato. Il file porta l'avvertenza in testa; leggerla prima di intervenire. provato. Il file porta l'avvertenza in testa; leggerla prima di intervenire.

View File

@@ -168,6 +168,12 @@ class GruppiServizio
{ {
$this->attivo($gruppo); $this->attivo($gruppo);
// Si decide sui dati di adesso, non su quelli con cui è partita la
// pagina: nel frattempo l'amministratore può aver cambiato pacchetto
// o membri.
$territorio->refresh();
$membro->refresh();
if ($territorio->gruppo_servizio_id !== $gruppo->id) { if ($territorio->gruppo_servizio_id !== $gruppo->id) {
throw new InvalidArgumentException("Il territorio {$territorio->numero} non è nel pacchetto del gruppo."); throw new InvalidArgumentException("Il territorio {$territorio->numero} non è nel pacchetto del gruppo.");
} }
@@ -182,7 +188,10 @@ class GruppiServizio
} }
$esito = DB::transaction(function () use ($gruppo, $territorio, $membro, $data) { $esito = DB::transaction(function () use ($gruppo, $territorio, $membro, $data) {
Territorio::whereKey($territorio->id)->lockForUpdate()->first(); $bloccato = Territorio::whereKey($territorio->id)->lockForUpdate()->first();
if (! $bloccato || $bloccato->gruppo_servizio_id !== $gruppo->id) {
return "Il territorio {$territorio->numero} non è più nel pacchetto del gruppo.";
}
$conflitto = Assegnazione::sovrappostaA($territorio->id, $data); $conflitto = Assegnazione::sovrappostaA($territorio->id, $data);
if ($conflitto) { if ($conflitto) {