Changelog
Storico delle modifiche rilasciate. Il formato segue «Keep a Changelog».
- v0.45.0 10 novembre 2026 Ultima versione
Correzioni dal collaudo UAT del 10 novembre
Corretto
- Form di registrazione: se l'invio è fermato perché manca qualcosa, il cursore va sul **primo** campo da sistemare e non più sull'ultimo in fondo alla pagina.
- Elenco registrazioni, tendina «E-mail / Pass»: si sceglie una voce alla volta, la nuova prende il posto della precedente (prima si sommavano e la colonna mostrava stati misti). Vale anche per l'export.
- Elenco registrazioni: la selezione delle righe si azzera cambiando pagina, filtro o righe per pagina, invece di restare nascosta e riapparire.
- Richiesta di conferma: l'avviso di accessibilità nomina anche i componenti del gruppo con ♿ seduti in galleria, dalla scheda, dal menù ⋯ e nell'invio in blocco. La scheda del referente mostra il ♿ accanto al componente.
- Pianta delle assegnazioni: nel pannello di un nucleo, chi è già In attesa di conferma, Confermato o Entrato ha la scritta «poltrona ferma» e il suo «Sposta» spento; anche «Sposta in …» è spento finché nel nucleo c'è una poltrona ferma. Il motivo compare al passaggio del mouse.
Modificato
- Collaudo UAT: report del 10 novembre e dieci nuove note di esecuzione nel playbook.
- v0.44.0 9 novembre 2026
Pagine pubbliche scure e senza cornice, Serata Live in grigio, backoffice rifinito
Modificato
- Pagine pubbliche (registrazione, conferma, rinuncia, biglietto): sempre scure, anche con il telefono in modalità chiara, e senza cornice su ogni schermo: fondo unico e contenuto in una colonna centrata.
- Form di registrazione: riscritti gli aiuti del minore sotto i 3 anni e dei minori 3–17, e la nota sull'accessibilità («…e provvederemo noi alla tua richiesta»).
- Serata Live: poltrone e palcoscenico grigi, così il verde degli entrati risalta. Chi è passato più volte ha un triangolo rosso pieno sulla poltrona e accanto al nome, al posto della poltrona rossa e del «×N». Il simbolo ♿ è monocromatico.
- Configurazione: il riquadro si chiama «Data e ora evento» e mostra lo stato («Bozza» / «Pubblicato»). Sotto la data bloccata una riga dice se si può ancora tornare in bozza per cambiarla; passando col mouse sui campi bloccati un suggerimento ne spiega il motivo.
- Gestione Accessi: tre righe (Confermato, In attesa di conferma, Assegnato) e una nota per chi non può entrare (Registrato, Rinuncia, Cancellato).
- Dashboard: dal giorno dopo la serata la richiesta di conferma non è più disponibile (niente caselle, voce di menù o comando nella scheda). L'esito dell'invio in blocco dice a quanti è partita; le tre tendine dei filtri sono larghe uguali.
- Assegnazione: le mappe si aprono sempre al 100%; la galleria al 100% è larga quanto il riquadro e lo zoom sta a filo del palcoscenico.
- Menù: «Comprimi menù» è in fondo, accanto al nome; accanto al titolo della pagina c'è l'icona della sua voce.
- Inserimento manuale: il gruppo ha titoli e pulsante «Aggiungi una persona» come il resto del modulo.
Documentation
- Manuale del backoffice riscritto per voce di menù, con operazioni passo per passo e limiti.
- Documenti e casi di collaudo allineati al comportamento attuale.
- v0.43.0 6 novembre 2026
Le pagine pubbliche da telefono occupano tutto lo schermo
Modificato
- Pagine pubbliche (registrazione, conferma, rinuncia, biglietto): sotto i 520 px di larghezza la card perde bordo, angoli e ombra e occupa tutta la larghezza. Su tablet e computer non cambia nulla.
- Form di registrazione: se l'invio si ferma per un campo mancante, non compare più la nuvoletta del browser «Compila questo campo»; restano i messaggi rossi e il riepilogo in cima. Il cursore va sul primo campo da sistemare e la pagina lo porta in vista.
Corretto
- Pagina di conferma: dopo la conferma dice che il biglietto in PDF è in allegato all'e-mail, non più che c'è un link per scaricarlo.
- Configurazione › E-mail automatiche: nell'e-mail con il biglietto il secondo campo del corpo si chiama «Secondo paragrafo», non più «Testo dopo il pulsante».
- Pagina del biglietto: il logo è centrato come nelle altre pagine.
- v0.42.0 5 novembre 2026
Il biglietto arriva in allegato, rinunciare è più corto, la Serata Live è una sala
Modificato
- E-mail con biglietto/QR: il PDF
biglietto-rainbow-awards.pdf(la persona e i suoi minori) è in allegato; tolto il pulsante «Scarica il tuo biglietto». Parte alla conferma, con «Reinvia e-mail» e con «Invia e-mail». Se il PDF non si genera, l'invio risulta fallito e la conferma resta valida. - Configurazione › E-mail automatiche: l'e-mail con il biglietto non ha più il campo «Etichetta del pulsante» e ha un testo di fabbrica nuovo. Se il corpo era stato personalizzato, il testo resta e potrebbe ancora parlare del link: da controllare.
- PDF del biglietto (persona e backoffice): al posto del link di rinuncia, la riga «Se non puoi più partecipare, usa il link di rinuncia nell'e-mail con cui hai ricevuto questo biglietto.»
- Pagina
/rinuncia/[token]: una domanda con nome, posto e minori, e i pulsanti Annulla e Rinuncia affiancati. Annulla chiude la pagina; se il browser non la chiude, mostra «Nessuna rinuncia». - Serata Live in modalità sala: filtri come pillole in alto, mappa più larga e poltrone più grandi, colonna laterale da 260 px con l'ultimo ingresso in grande, un anello piccolo e la cronaca. Il posto selezionato si apre in una scheda sopra la mappa.
- Serata Live: il bagliore di chi entra è fatto di onde attorno alla poltrona e dura 6 s invece di 10. Le righe della cronaca hanno solo ora, pallino della categoria e nome.
- Piattaforma: Node 26 (immagine
node:26-alpine, corepack installato da npm), SvelteKit 3, adapter-node 6, Paraglide 3, postgres 4, drizzle 1.0.0-rc.5, Biome 2.6, pnpm 12.16.1. Login e logout OIDC dichiarano come redirect esterno solo l'origin dell'issuer configurato. - Pool del database: le connessioni ferme si chiudono dopo 30 s.
Corretto
- Assegnazioni: dopo un'assegnazione dalla mappa l'URL non diventa più
?aperta=stalls.
Database
- Nessuna migrazione: gli SQL non cambiano. I
snapshot.jsonindrizzle/*sono portati al formato di drizzle-kit rc.5 (drizzle-kit up).
- E-mail con biglietto/QR: il PDF
- v0.41.0 3 novembre 2026
Lo scanner web dice le stesse cose dell'app
Modificato
- Scheda della persona in
/ingresso: riquadro viola «Rinuncia del partecipante», rosso «Biglietto annullato», e «Da confermare» per chi ha un posto ma non è ammesso in Gestione Accessi. - Categorie al singolare nello scanner web: Ospite, Stampa, Sponsor, Istituzioni.
- Esiti della scansione Rinuncia, Cancellato e Non valido: «Nessun posto assegnato» al posto della frase di spiegazione.
- Il tab «Cerca» premuto di nuovo, anche da una scheda, fa ripartire la ricerca.
- Scheda della persona in
- v0.40.0 3 novembre 2026
Gli omonimi si distinguono nell'app, i biglietti di chi non entra si vedono grigi
Modificato
- API per l'app: in
GET /api/v1/events/{id}/ticketse/attendeesl'email arriva **intera** se un'altra registrazione ha lo stesso nome e cognome (senza maiuscole né accenti); per gli altri resta mascherata. - Scheda partecipante: per
RinunciatoeCancellato«Scarica biglietto» e «Scarica pass» sono grigio chiaro (nuovo tonomuteddiButton), e la riga sotto i comandi dice perché il biglietto (o il pass) non è più valido: «ha rinunciato al posto» oppure «non ha più un posto assegnato». - Icona del pass grigia per rinunce e cancellati, nella colonna Stato dell'elenco e nella scheda.
- Elenco Registrazioni: i membri di un gruppo partono mezzo centimetro più a destra del referente, con la freccetta ↳ magenta.
- API per l'app: in
- v0.39.0 2 novembre 2026
L'app Ticket Validator fa entrare per nome anche chi non ha il QR, e mostra lo stato giusto
Aggiunto
- API per l'app:
registrationIdnei risultati diGET /api/v1/events/{id}/ticketse/attendees;POST /api/v1/checkinsecheckins:batchlo accettano al posto diticketId(conentryMethod: "NAME") per chi non ha un QR attivo. Stesse regole dello scanner web: se lo stato non è ammesso in Gestione Accessi risponde422 ticket-not-confirmed; nuovo motivounknown-registration. - API per l'app: campo
status(stato della registrazione:CONFIRMED,AWAITING_CONFIRMATION,ASSIGNED,REGISTERED,ENTERED,RENOUNCED,CANCELLED) nei risultati di ricerca ed elenco, per il badge. docs/modifiche-app-ticket-validator.md: le modifiche da fare nell'app (badge, ingresso per nominativo, due colori), al posto diaggiornamenti-app-ticket-validator.md.
Database
- Migrazione
drizzle/20261102133804_checkin_registration_id: colonnaregistration_id(facoltativa) incheckin_requestsecheckin_scans, eticket_iddiventa facoltativo in entrambe. Non distruttiva, nessun dato da convertire. Da applicare conpnpm db:migrate.
- API per l'app:
- v0.38.0 27 ottobre 2026
Il biglietto si scarica dalla scheda, i filtri si aprono uno alla volta, il design system ha la sua Tavola
Aggiunto
- «Scarica biglietto» nella scheda: lo stesso PDF A4 dell'e-mail, una pagina per persona del nucleo, da qualunque scheda del nucleo. Non cambia il QR e non manda niente; lo storico registra «Biglietto scaricato dal backoffice». Se c'è il pass resta solo «Scarica pass».
- Biglietto e pass di chi ha rinunciato o è stato cancellato: fascia rossa «RINUNCIATO · NON VALIDO» / «CANCELLATO · NON VALIDO», posto «Liberato». Il QR resta leggibile e all'ingresso dà «Rinuncia» o «Cancellato».
- Filtro «E-mail / Pass» nell'elenco Registrazioni: E-mail partita, E-mail non partita, Biglietto emesso, Pass emesso. Il vecchio
?email=failedfunziona ancora. - Voce «Gruppo con adulti» nel filtro «Altro» (ex «Richieste»).
- Tavola del design system: in Storybook (*Design System / Panoramica* e *Tavola*) e come pagina statica
docs/design-system.html, rigenerata conpnpm docs:tavola. Storie nuove per otto componenti che non ne avevano. - Script
scripts/strip-digits-from-names.tsper ripulire dal database i nomi con le cifre lasciate dai test (anteprima, poi--apply).
Modificato
- Elenco Registrazioni: una tendina dei filtri aperta alla volta, si chiude con un clic fuori o con Esc, e ha larghezza fissa. Chi ha il pass non conta più fra le «E-mail non partite».
- Elenco Registrazioni: «Assegna posto» / «Sposta» sono la prima voce dei tre puntini, con le tre aree in un sottomenù; nella riga non c'è più il bottone.
- Colonna «E-mail / Pass»: «✓ Biglietto emesso» per l'e-mail col biglietto; in grigio per chi ha rinunciato o è stato cancellato.
- «Scarica pass» si riscarica anche da Entrato, Rinunciato e Cancellato, e dalla scheda di un membro dà il pass di tutto il nucleo.
- Grafica di biglietto e pass: serata e luogo nel corpo, rinuncia come link «Rinuncia al posto», QR di 250 pt su entrambi, piè «Pagina N di M».
- Colori: «In attesa di conferma» in ciano chiaro, con l'angolo piegato sulla mappa; il pass è verde («Genera pass» magenta); «Libera posto» neutro, con la finestra di conferma in bianco; «Cancella» solo scritta rossa.
- La scheda partecipante usa
Button, che guadagna la varianteoutlinecoi toni e il disabilitato grigio; tolta la variantespectrum. - Testi più brevi nelle finestre di cancellazione del gruppo, nell'avviso di accessibilità e nel riquadro dell'e-mail non partita.
- «Libera posto» in galleria non avvisa più che il posto torna subito al form.
- API per l'app:
GET /api/v1/events/{id}/attendeeslegge dal database solo la pagina richiesta invece dell'intera tabella.
Corretto
- I grassetti dei PDF uscivano in Light: il font Space Grotesk è variabile e pdfkit non lo regola. Biglietto e pass usano ora due istanze statiche, Medium e Bold.
- Nove token di colore arrivavano nel tema scuro col valore del chiaro (fondi tenui, verdi e rossi semantici nel backoffice e all'ingresso).
--text-3sotto il contrasto minimo per il testo: ora ≥ 4,5:1.- Storie Storybook composte che mostravano un solo elemento.
- Seed demo: il QR di chi rinuncia o è cancellato resta corrente, come nel flusso reale.
- v0.37.0 26 ottobre 2026
Chi passa più volte, il gruppo entra a testa, l'app sa chi è l'operatore
Aggiunto
- Ingressi ripetuti: avviso nel backoffice («N persone sono passate più volte» → «Vedi»), filtro «Passati più volte» nell'elenco registrazioni, segno ×N nella Serata e riga «Passato di nuovo» nel dettaglio dell'ingresso. Offline un secondo passaggio scrive
entered_againnel registro di audit. - API per l'app:
GET /api/v1/events/{id}/attendees, l'elenco completo delle persone a pagine (limit,cursor), con biglietto, posto e stato d'accesso. - API per l'app:
entryMethod(APP_SCAN/NAME) nei check-in online e nel batch; lo snapshot dà per ogni entrato le sue scansioni, con operatore, dispositivo e metodo (WEB_SCANper lo scanner web). - L'operatore dell'app diventa un utente di Rainbow Ticket: a ogni check-in il backend crea o aggiorna la riga
usersdal token, come al login web, e l'audit e la Serata mostrano il suo nome.
Modificato
- Gestione Accessi: se In attesa di conferma o Assegnato sono ammessi, il membro di un gruppo entra da solo col suo «Conferma» (cade «Solo col gruppo», tutti o nessuno). Vale per tutte le categorie.
- Coda senza rete dell'ingresso: solo voci per persona; una vecchia voce
party:rimasta sul telefono risponde «non valido» ed esce dalla coda. - Ricerca per nominativo dell'app (
/tickets): un solo parametroqa testo libero su nome, cognome ed e-mail, risultati per pertinenza.
Documentation
- Contratto con l'app Ticket Validator (§6.1–6.6, §10); B54 e B55 chiusi; allineati requisiti, casi d'uso, stati e workflow, analisi funzionale, manuale del backoffice e glossario.
Database
- Nuova tabella
checkin_scans(una riga perIdempotency-Key, indice suticket_id): migrazionedrizzle/20261023135016_checkin_scans. - Nuova colonna
checkin_scans.entry_method(defaultAPP_SCAN): migrazionedrizzle/20261023150506_checkin_scans_entry_method. Non distruttive.
- Ingressi ripetuti: avviso nel backoffice («N persone sono passate più volte» → «Vedi»), filtro «Passati più volte» nell'elenco registrazioni, segno ×N nella Serata e riga «Passato di nuovo» nel dettaglio dell'ingresso. Offline un secondo passaggio scrive
- v0.36.0 23 ottobre 2026
Gestione Accessi, «Conferma» all'ingresso, un nome solo per l'e-mail
Aggiunto
- Configurazione → tab unico «Impostazioni» con tre card, ognuna col suo «Salva»: Evento, Apertura form pubblico e Gestione Accessi.
- Gestione Accessi: un interruttore per In attesa di conferma e per Assegnato («Accesso consentito» / «Accesso non consentito»); di partenza entrano solo i Confermati. Il check-in e la ricerca dell'app seguono la scelta (evento di audit
settings.updated). - Ingresso: badge dello stato della registrazione nei risultati e nelle schede, come nel backoffice; «Conferma» già nella riga per chi entra da solo.
Modificato
- Ingresso: «Conferma» al posto di «Registra»; tolti «Registra tutti i presenti» e «Registra il gruppo» del nucleo che non ha confermato, e i riquadri di avviso nella scheda. Esiti con il verdetto come titolo.
- Ingresso su schermo largo: la shell sta in un riquadro da telefono (390 × 844), centrato; sul telefono non cambia nulla.
- L'inserito a mano senza e-mail non entra più per nominativo d'ufficio: ha il pass, oppure segue il suo stato come tutti.
- Comando dell'e-mail col biglietto: «Invia e-mail» / «Reinvia e-mail» sia nei tre puntini sia nella scheda, con un'unica finestra «Conferma invio e-mail»; col pass la finestra avvisa che il QR resta lo stesso.
- «Cancella» non compare più per chi è Entrato o ha Rinunciato; il server la rifiuta.
- Scheda del partecipante: fino a tre comandi affiancati senza tre puntini; «Libera posto» nascosto quando una poltrona del nucleo è ferma. Finestre di «Libera posto» in ambra e di «Genera pass» in azzurro.
- Pass A5: QR più grande (circa 88 mm di lato).
- Form pubblico: un solo riquadro «Accessibilità e altre richieste»; tolta la riga di contatto sotto il pulsante.
- Riquadro dell'e-mail non partita più breve.
Documentation
- RF-BO-061 (Gestione Accessi) e B53 (lacune dell'API per l'app); §10 del contratto con l'app Ticket Validator; riconciliati requisiti, casi d'uso, stati e workflow, manuale, glossario, ADR 0006/0013/0014 e casi UAT.
Database
- Nessuna migrazione: la scelta degli accessi è la chiave
entrance_policydella tabellasettings(riga assente = solo Confermati).
- v0.35.0 22 ottobre 2026
Pass consegnato a mano, elenco registrazioni compatto
Aggiunto
- Comando «Genera pass» nella scheda del partecipante: PDF A5 con il QR, conferma dei membri del nucleo con posto (evento di audit
pass.issued). «Scarica pass» ristampa lo stesso QR; un biglietto inviato dopo il pass mantiene il QR. - «Libera posto» nella scheda del partecipante, come dalla mappa (libera il posto di tutto il nucleo).
- Inserimento manuale: si possono aggiungere persone a un gruppo.
Modificato
- Elenco registrazioni: tolta la colonna «Origine», etichette di posto brevi («Platea / F 30 - P 18», gallerie senza settore), colonna rinominata «E-mail / Pass» con «E-mail partita» / «Pass emesso». Anche nell'export CSV.
- Scheda del partecipante: «Libera posto» e «Annulla» spostati in un menu.
- Configurazione → E-mail automatiche: le quattro schede su una riga, tolto il suggerimento sulle gallerie al completo.
Documentation
- RF-BO-060 e UC22; allineati requisiti, casi d'uso, stati e workflow, manuale del backoffice, glossario e casi UAT.
Database
- Nessuna migrazione: il pass è un evento del registro di audit.
- Comando «Genera pass» nella scheda del partecipante: PDF A5 con il QR, conferma dei membri del nucleo con posto (evento di audit
- v0.34.0 22 ottobre 2026
E-mail non partite, testi delle e-mail rivisti
Aggiunto
- Colonna «E-mail» nell'elenco registrazioni e nell'export CSV: esito dell'ultimo invio fra richiesta di conferma e biglietto, col motivo leggibile del fallimento.
- Avviso su tutte le pagine del backoffice con il numero di e-mail non partite e il link «Vedi» all'elenco filtrato (
?email=failed). - Riquadro rosso nella scheda del partecipante quando l'ultimo invio non è partito; righe d'invio fallito in rosso nello storico.
- Comando «Invia biglietto»: quando l'ultima e-mail col biglietto non è partita, rimanda lo stesso biglietto con lo stesso QR, senza revoche.
- Variante «posti al completo» dell'E-mail di registrazione, configurabile in una nuova scheda di Configurazione → E-mail automatiche.
- Serata Live: anche le poltrone libere si selezionano («Posto libero»).
Modificato
- Richiesta di conferma non partita (anche al reinvio): la registrazione e il suo nucleo tornano «Assegnato», il link decade. Esiti dell'invio con i nomi di chi non l'ha ricevuta.
- Invio in blocco dell'e-mail con richiesta conferma solo per gli «Assegnato»: il reinvio si fa una persona alla volta.
- L'E-mail di registrazione parte dopo la collocazione del posto.
- Testi di fabbrica delle e-mail e del form non aperto/chiuso;
{data_serata}riporta giorno e ora della serata in e-mail, PDF e/biglietto. - «Reinvia biglietto» chiude i link di rinuncia dedicati non ancora usati.
- Serata Live: bagliore di chi entra più visibile (alone chiaro che pulsa, fermo con riduzione del movimento).
Corretto
- Ricerca per nominativo dell'app Ticket Validator: un membro di gruppo non confermato risulta
NEEDS_CONFIRMATION, nonCAN_ENTER. - Rinuncia dal QR disponibile anche per l'adulto aggiunto.
- Messaggio di salvataggio dei testi delle e-mail in Configurazione.
- La ricerca dell'elenco registrazioni non apre più lo storico del browser.
.app.yaml.example: la sezioneticketsè obbligatoria.
Documentation
- ADR 0014, caso UAT «E-mail non partite», riconciliazione di requisiti, casi d'uso, stati, analisi funzionale e manuale del backoffice.
Database
- Nessuna migrazione.
- v0.33.0 20 ottobre 2026
QR firmato e cifrato, API per l'app Ticket Validator
Aggiunto
- API
/api/v1per l'app Ticket Validator:events,events/{eventId}/snapshot, ricerca bigliettievents/{eventId}/tickets(nome, cognome, email in AND, con email mascherata),checkinsecheckins:batchidempotenti,ticket-keys. - Autenticazione delle API con access token Keycloak dello stesso realm e issuer del backoffice:
auddeve contenereauth.oidc.clientIderealm_access.rolesil ruolostaff-ingresso. - Pagina pubblica
/biglietto(destinazione del QR) con la richiesta di rinuncia via email (limite di frequenza) e due nuove email: richiesta e conferma di rinuncia. - Sezione
ticketsin.app.yaml:event(defaultRAINBOW-AWARDS-DEMO-2027, «Rainbow Awards Demo») eqr(base URL e chiavi, obbligatorie). Scriptscripts/ticket-keys.tsper generare chiavi e vettori di test. - Keycloak nel devcontainer, con realm
rainbowimportato all'avvio e audience mapper sul client dell'app.
Modificato
- Configurazione della serata: data e ora, bozza/pubblicata, blocchi da pubblicata; dopo la data dell'evento si imposta la serata successiva senza intervento tecnico.
- Il PDF del biglietto usa il nuovo formato del QR.
- Ricerca dell'app: lo stato «Col gruppo» risulta
NEEDS_CONFIRMATION(nessun QR attivo).
Documentation
- ADR 0013, guida
integrazione-app-ticket-validator.md, casi d'uso, requisiti, analisi funzionale e manuale del backoffice aggiornati.
Database
- Migrazione
drizzle/20261013163056_renounce_tokens: nuova tabellarenounce_tokens(FK suregistrations) e valorerenounce_requestper l'enumcommunication_kind. - Migrazione
drizzle/20261013164244_renounce_confirmation_email: valorerenounce_confirmationpercommunication_kind. - Migrazione
drizzle/20261013165318_checkin_requests: nuova tabellacheckin_requestsper l'idempotenza dei check-in da app. src/lib/server/db/schema.tsaggiornato di conseguenza. Modifiche solo additive, non breaking.
- API
- v0.32.0 20 ottobre 2026
Email 2 e accessibilità: lo stesso avviso da ogni strada
Aggiunto
- Invio in blocco dell'Email 2: la barra di selezione nomina, con l'area, chi fra i selezionati ha l'esigenza di accessibilità ed è in galleria (fino a tre nomi, poi «e altri N»).
- Menù ⋯ della riga: la conferma dell'Email 2 porta lo stesso avviso della scheda.
- Modulo di registrazione: riga di contatto generale in fondo al form, con l'indirizzo già usato per l'accessibilità (B24), e link «Torna al form» dopo l'invio riuscito, che ricarica il modulo vuoto.
Modificato
- Il regolamento di sala punta alla pagina del Teatro Brancaccio in ogni ambiente, non più a un segnaposto
example(B49); l'email per l'accessibilità resta un segnaposto fino alla messa in produzione. - La regola «esigenza di accessibilità non ancora sistemata» è una sola (
isAccessibilityPending), condivisa da scheda, riga e invio in blocco.
Rimosso
- Documenti superati:
docs/timeline.md,docs/cronologia-modifiche.mdedocs/design-system.html(le regole visive stanno indocs/design-brief.mde nell'ADR 0006).
- v0.31.0 14 ottobre 2026
Ingresso: chi ha un posto entra per nominativo, il nucleo solo se c'è tutto
Aggiunto
- Esito di accesso «Col gruppo» (
with_party) e ingresso del nucleo intero (enterPartyByName): blocca insieme le righe del nucleo, scrive un auditregistration.entered_by_nameper persona e avvisa la Serata Live. - In
/ingresso, nella scheda del gruppo, il comando «Ci sono tutti: registra il gruppo (N)» con un riquadro che spiega la regola; senza rete il nucleo va in coda come una voce sola (party:<referente>) e parte intero al ritorno della rete.
Modificato
- Inserimento manuale: non parte più l'E-mail di registrazione (Email 1), per nessuna categoria; la prima e-mail è la richiesta di conferma, inviata dal coordinatore dopo la collocazione. La pagina diventa un modulo unico a sezioni (Categoria, Anagrafica, E-mail, Segnalazioni e Note interne), l'avviso di email già registrata sta sotto il campo e il posto accessibile è un interruttore.
- Serata Live: l'anello degli Entrati passa in cima alla colonna destra, con la percentuale in sala e l'ora dell'ultimo ingresso; Confermati, In attesa di conferma e Assegnati diventano tre righe compatte accanto alla scheda del posto selezionato.
- Dashboard: l'esito di un invio riuscito (E-mail con richiesta conferma, singola o di massa, e reinvio del biglietto) esce in magenta invece che in rosso; l'annullamento resta rosso, gli invii parzialmente falliti arancio.
- Seed demo: gli Ospiti dal form nascono collocati in galleria e gli inseriti a mano non generano più l'Email 1.
Documentation
- Riconciliazione dei documenti da 0.28.0: RF-COM-032, UC10, flusso 5 di
stati-e-workflow.md, analisi funzionale, manuale, ROADMAP e punti aperti (A10, B45) allineati alle decisioni del 13/10.
Database
- Nessuna modifica allo schema né migrazioni.
- Esito di accesso «Col gruppo» (
- v0.30.0 12 ottobre 2026
Serata Live: chi è entrato, a che ora e da chi, in diretta
Aggiunto
- Pagina
/backoffice/seratacon voce nel menu del backoffice, messaggi in italiano e inglese e storie Storybook diLiveHallMap. - Canale
NOTIFYdi Postgresevening_live, emesso dal check-in nella stessa transazione dell'ingresso (parte solo al commit); un ascolto per processo (live-channel) lo gira ai flussi aperti. - Regola di passaggio fra SSE e polling (
$lib/entrance/live-transport), con test unitari, test e2e e caso UAT15-serata-live.
Documentation
- ADR 0012, UC21, RF-BO-059, manuale del backoffice e punto aperto B48 aggiornati; per ora nessun altro indicatore del cruscotto (RF-BO-001/002).
Database
- Nessuna modifica allo schema né migrazioni: la pagina legge
audit_log,registrations,seat_assignmentseusers.
- Pagina
- v0.29.0 9 ottobre 2026
Ingresso della sera: scansione del QR e ricerca per nome
Il link di conferma segue la data viva della serata
Aggiunto
- Avviso d'esito dopo assegnazione e spostamento di posto, con testo comune alla mappa e all'elenco (
placement-notice). - Nel form pubblico, messaggi distinti per ciascun consenso mancante (Informativa Privacy, Regolamento di Sala, dichiarazione per i minori), badge «errore» sulle righe degli adulti con campi non validi e avviso se lo stesso indirizzo e-mail è ripetuto nella stessa registrazione.
- Nell'invio dell'E-mail con richiesta conferma, la conferma indica quante persone del nucleo passano in attesa insieme ai referenti.
Modificato
- L'unicità dell'e-mail vale fra le registrazioni **attive**: chi è cancellato o ha rinunciato libera l'indirizzo, così «cancella e reinserisci» funziona.
- Il messaggio di e-mail già registrata invita a controllare la casella e, altrimenti, a scrivere agli organizzatori.
- La mappa posti, il pannello del partecipante e le pagine di conferma e rinuncia allineano comandi e messaggi (galleria, carrozzina, riapertura del pannello, ricerca che si svuota); lo storico delle modifiche e la paginazione sono rifiniti.
- Il rimedio della Configurazione («Imposta apertura form e data») mostra la data bloccata e i nuovi errori.
Documentation
- Aggiunti i diari e i rapporti delle esecuzioni UAT del 2026-10-07 e 2026-10-08; aggiornati i casi d'uso UAT,
docs/requisiti.mdedocs/punti-aperti.md.
Database
- Aggiunta la migrazione
drizzle/20261008125153_email_unique_among_active. - Indice univoco
registrations_email_unique_idxsuregistrations.emailora parziale: vale solo per stati diversi dacancellederenounced(src/lib/server/db/schema.ts). Non distruttiva; può solo consentire reinserimenti prima rifiutati.
- Avviso d'esito dopo assegnazione e spostamento di posto, con testo comune alla mappa e all'elenco (
- v0.28.0 7 ottobre 2026
Annullare il referente porta con sé gli adulti del gruppo non confermati
Modificato
- Nelle e-mail il pulsante-link non è più in grassetto ma sottolineato, e l'anteprima nella Configurazione (scheda «E-mail automatiche») è semplificata e allineata al messaggio reale.
- La pagina Registrazioni e il pannello del partecipante (menù della riga, scheda) allineano comandi e messaggi ai casi d'uso riscritti.
Documentazione
- I casi d'uso UAT sono riscritti e rinumerati (assegnazione da elenco e da mappa, conferma e invio biglietto, cambio sala, liberazione del posto, cancellazione della registrazione); i vecchi file sono assorbiti dai nuovi.
- Riallineati i documenti funzionali (
docs/) e il registro delle modifiche.
Chore
- Aggiornate le feature del devcontainer; permessi eseguibili sugli script.
Database
- Nessuna modifica di struttura né migrazione.
- v0.27.0 2 ottobre 2026
I testi delle e-mail si cambiano dalla Configurazione, a blocchi
La data della serata la imposta il coordinatore
Documenti riallineati, e ciò che nessuno chiamava esce
- la scheda e l'export CSV non mostrano più la «**Scadenza conferma**»: il termine è sempre la serata;
- la pagina di conferma dice «**Conferma entro la serata di …**»;
- l'introduzione della Configurazione non parla più dei «non confermati» né presenta la data come un'ipotesi;
- l'etichetta del QR di chi ha rinunciato è «**Rinuncia**», come lo stato.
Configurazione
logging.levelora conta davvero: il livello del logger si prende dalla configurazione a ogni snapshot valido (prima valeva soloLOG_LEVEL).- Tolte le opzioni senza lettori
auth.oidc.initiatingIdp(OIDC_INITIATING_IDP) eCONFIG_BASE64, eregistration.eventDateLabel(REGISTRATION_EVENT_DATE_LABEL);.app.schema.jsonè rigenerato. .env.exampleelenca tutte le variabili che il codice legge,TZcompresa.
Rimosso
- La form action
assignGallerydella pagina Registrazioni, senza più un bottone che la chiamasse dal 30/09, e i suoi messaggi. - La funzione di dominio
deleteNote: le note interne sono indelebili.
Database
- Nessuna modifica di struttura né migrazione. I testi delle e-mail sono righe nuove della tabella
settingsesistente (chiave/valore).
- v0.26.0 1 ottobre 2026
I comandi d'invio dicono due parole, e la conferma chiede una cosa sola
Chi non ha una casella non ha i comandi che ci scrivono
Via l'ultima scadenza rimasta scritta nell'interfaccia
Le note interne si leggono, e basta
L'avviso ♿ cambia tono e cambia posto
Dalla scheda si colloca in un modo solo
La demo somiglia di più al vero
Documenti
- **Passata di riconciliazione sulla finestra 0.17.0 → 0.25.0** (21–30 settembre), su tutta
docs/più [CONTEXT.md](CONTEXT.md) e gli ADR. Metodo nuovo: invece di rileggere i documenti in cerca di incongruenze — che su testi di questa lunghezza non funziona, perché la prosa sembra sempre plausibile — si parte da un **registro dei fatti cambiati** e per ciascun fatto si cerca chi lo afferma ancora al presente. **Undici difetti**, tutti dentro **enumerazioni** e mai nella prosa: elenchi di stati, di motivi di blocco, di operazioni, di colori. Sette vengono dal solo **A8**. Otto candidati scartati, tenuti a verbale perché misurano il rumore della passata. Il procedimento è fissato nella skill di progettoallinea-docs. - **Seconda passata sui casi di collaudo in
uat/**, che del perimetro non facevano parte ed erano enumerazioni pure anche loro. Puliti su tutti i fatti tranne uno, e pesante: la **scadenza di conferma**, uscita dalla Configurazione il 28/09. Altri sei difetti, fra cui **B43**, che diceva «scritto nei documenti, non ancora nel codice» elencando tre cose da fare: **erano fatte tutte e tre**. È il più costoso dei diciassette — un punto aperto che dà per da fare ciò che è fatto non invecchia in silenzio come gli altri, invita a rifare il lavoro. - **Nuovi casi UAT**: [cambio sala dal pannello](uat/use-cases/cambio-sala-dal-pannello.md), [liberazione posto nucleo](uat/use-cases/liberazione-posto-nucleo.md), [poltrona ferma sulla mappa](uat/use-cases/poltrona-ferma-sulla-mappa.md) e la serie numerata dei **cinque form pubblici** — ospiti, minori e accessibilità, gruppo adulti, stampa, sponsor — che sostituisce il caso unico di registrazione. Ritirati i due casi rimasti senza comando: assegnazione di galleria in blocco e ripiego in galleria con rientro in platea.
- Riconciliati [requisiti](docs/requisiti.md), [analisi funzionale](docs/analisi-funzionale.md), [casi d'uso](docs/casi-uso.md), [punti aperti](docs/punti-aperti.md), il [manuale di backoffice](docs/manuale-backoffice.md), la [cronologia](docs/cronologia-modifiche.md), il [design brief](docs/design-brief.md) e gli [ADR 0001](docs/adr/0001-consegna-biglietto-tramite-link-verifica.md), [0006](docs/adr/0006-design-system-palette-tema.md) e [0008](docs/adr/0008-poltrona-ferma-lato-server.md).
Database
- **Passata di riconciliazione sulla finestra 0.17.0 → 0.25.0** (21–30 settembre), su tutta
- v0.25.0 30 settembre 2026
Sulla pianta l'attesa ha il suo colore
«Manca il posto» tace sul pannello appena aperto
«Libera posto» si spegne quando non c'è niente da liberare
Nell'elenco la spunta è di chi l'e-mail la riceve
Sotto il cofano
Documenti
- Riconciliati [requisiti](docs/requisiti.md), [analisi funzionale](docs/analisi-funzionale.md), [casi d'uso](docs/casi-uso.md), [punti aperti](docs/punti-aperti.md) (**B40** chiuso), il [manuale di backoffice](docs/manuale-backoffice.md), la [cronologia](docs/cronologia-modifiche.md) e il [design brief](docs/design-brief.md).
- **Due code stantie chiuse per strada**, in contraddizione con quanto deciso il 28 settembre: un caso d'uso diceva ancora che per liberare il posto di chi è In attesa «si aspetta la scadenza, che porta a Non confermato», e i requisiti della selezione elencavano
Non confermatofra gli stati esclusi. Quello stato e quella scadenza non esistono più dalla 0.24.0: resta la cancellazione, o la rinuncia del partecipante.
Database
- v0.24.0 29 settembre 2026
«Libera posto»: la poltrona si toglie, la persona resta in lista
Il pannello di collocazione respira
Chi non conferma tiene il suo posto
La fila 11 si può assegnare
Una registrazione porta quante persone servono
Database
- Nuova migrazione
drizzle/20260928121003_legal_gamora: l'enumregistration_statuspassa da otto a **sette** valori — esceunconfirmed— insrc/lib/server/db/schema.ts. È la prima migrazione **distruttiva** su un enum del progetto: Postgres non sa togliere un valore da un tipo, quindi il tipo si ricrea, e le righe che lo portavano diventanoregistered**prima** del cast finale. Nessuna riga perde dati: cambia l'etichetta dello stato. - **Effetto sulla colonna:**
registrations.statusviene riscritta per intero (tipo atext, conversione, tipo nuovo, default ripristinato a'registered'). - **Lo storico non si tocca:** le voci d'audit
confirmation.expiredrestano come sono, col lorovalueAfteraunconfirmed— sono il verbale di quello che è successo davvero quel giorno. Per la stessa ragione restaconfirmationTokens.expiresAt, che oggi annuncia una data senza più chiudere niente. seat_block_reason**non cambia**:row_11resta nell'enum, ma il seed non lo scrive più su nessun posto — toglierlo costerebbe una migrazione per nulla.
- Nuova migrazione
- v0.23.0 25 settembre 2026
Il codice parla inglese, l'interfaccia resta italiana
- **Il motore di collocazione** sta in
src/lib/design/placement, le regole di posti e stati inplacement-rules.ts, la pianta del teatro inhall-layout.{ts,json}; la scrittura dei posti èassignments/placement.ts, la propostaproposal.ts, la lettura della salahall.ts. - **
PlateaMapdiventaSeatMap**: è la stessa mappa per le tre aree. Lo stato del pannello del nucleo sta inplacement-panel.ts. - **La Sala di prova** è
src/lib/server/testing/test-hall.ts, contestPerson,testPartyetestMailer. - **Gli script** si chiamano
extract-gallery-layout,extract-stalls-layout,clean-test-dataesimulate-placement(--parties,--seed). - **I parametri della pagina assegnazioni** sono
?open=(nonechiude ogni pannello),?anchor=e?placed=; i filtri della lista portano i valori inglesi (?status=confirmed,?category=guest,press). I vecchi link?tab=galleriefunzionano ancora; un link salvato con altri valori italiani non filtra più.
Ogni assegnazione ha la sua poltrona
Via le azioni di galleria che nessuna pagina chiamava
Corretti
- **I dati demo non spezzano più il nucleo**: prima davano a ogni minore un posto in platea anche col referente in galleria. Ora il nucleo si siede tutto insieme — in G1, in G2 se in G1 non c'è spazio per tutti, in platea se non c'è in nessuna delle due.
- Due regressioni delle rinomine, trovate in revisione prima del rilascio: il motore tornava a considerare i palchetti nel punto ideale della platea, e il vecchio link
?tab=gallerienon apriva più le gallerie.
Documenti
- Le domande al coordinatore si arricchiscono di nuove richieste e chiariscono quelle già aperte.
- I commenti non rimandano più ai numeri dei ticket e della cronologia: dicono la cosa. L'allegato dell'ADR 0009 riporta i nomi scelti davvero.
- Le tabelle di
docs/stati-e-workflow.mdmostrano il valore in codice di ogni stato.
Database
- **Breaking: la banca dati va ricreata.** Le 14 migrazioni lasciano il posto a una sola migrazione iniziale,
drizzle/20260925115840_init, generata dallo schema di oggi. Una banca dati fatta con le vecchie migrazioni non si aggiorna: **subito dopo il deploy, sull'ambiente dev va lanciatopnpm db:reset --demo** (chiede di riscrivere il nome della banca dati). I dati presenti si perdono. - **Valori salvati in inglese**: stati della registrazione e del QR, categorie, origine, tipo, stato delle comunicazioni, aree, settore (enum
seat_section), motivi di blocco, codici e attori del registro, chiavi delle impostazioni (form_window.guest, …) e modalità della scadenza di conferma (days,date). - **Colonne di
seatsin inglese**:row,section,number,position(dafila,settore,numero,ordine), con indici ed enum rinominati; la fotografia del posto nel registro usa le stesse chiavi. - **
seat_assignments.seat_idèNOT NULL**, e l'indice unico del posto attivo non ha più bisogno diseat_id IS NOT NULL. - Escono
seat_assignments.progressivoeseating_areas.next_progressive, che lo schema non dichiarava più dalla 0.22.0.
- **Il motore di collocazione** sta in
- v0.22.0 25 settembre 2026
La poltrona ferma lo è anche per il server
Una strada sola per scrivere i posti, e cinque difetti che ne sono usciti
- un
Non confermatospostato in galleria **restavaNon confermato**, mentre l'audit scrivevaAssegnato; - lo spostamento singolo scriveva nell'audit **sempre**
Assegnato, qualunque fosse lo stato; - lo spostamento singolo **ignorava il nucleo**: un membro di un nucleo in galleria si poteva portare da solo in platea. Ora risponde
party_incomplete; dentro la platea si sposta ancora da solo; - il pannello del nucleo verso una galleria **non prendeva il blocco** di quella galleria, e due collocazioni contemporanee potevano contendersi le stesse poltrone;
- il suggerimento del pannello costruiva il nucleo intorno alla poltrona cliccata **senza controllare che fosse libera**. Ora la proposta è una sola (
propostaDiCollocazione): intorno all'ancora se è libera e assegnabile a mano, ♿ compreso, altrimenti la collocazione migliore.
Tre comandi della riga e della scheda allineati
- **«Reinvia biglietto»** compare anche nella riga dell'elenco di un membro adulto del gruppo, come già nella scheda: il biglietto è suo;
- la dimensione del nucleo nella scheda **non conta più** i membri annullati o rinunciatari;
- **«Assegna posto»** dalla scheda di un membro adulto apre il pannello del nucleo, invece di una pianta senza nessuno selezionato.
Via quello che restava per le righe vecchie
- il **numero progressivo di galleria** — il «Posto n° 12» di chi in galleria aveva un'area ma non una poltrona — con il suo contatore: da quando anche le gallerie hanno posti veri (RF-BO-053) non lo scriveva più nessuno. I dati demo mettono ora gli ospiti di galleria su poltrone vere, prima G1 poi G2, e ai minori il cognome di uno dei genitori, non sempre quello del referente;
- la migrazione dei posti di galleria, che era l'unica eccezione alla poltrona ferma: ora vale **senza eccezioni**. Con lei gli script una tantum
migra-posti-galleria,ripara-attesa-orfanaerigenera-posti; unassignSeateunassignRow, che nessuna interfaccia chiamava più e che non sapevano del nucleo. B16 resta aperto: se tornerà un «sì», la liberazione si riscrive dentro la collocazione, per il nucleo intero;- tre etichette d'audit che nessuno scriveva più.
Sotto il cofano
Dipendenze
- **pnpm 12**, **vitest 5**, nodemailer 10, pdfkit 0.20, SvelteKit 2.70, Svelte 5.57, Storybook 10.6. TypeScript resta alla 6: svelte-check e SvelteKit non reggono ancora la 7.
- **
dotenvpassa fra le dipendenze di produzione.** L'adattatore Node impacchetta inbuild/le dipendenze di sviluppo, e la 18 così impacchettata faceva caderenode buildall'avvio; la suite e2e, che gira suvite preview, non lo vedeva. - Tolte
mdsvex,@tailwindcss/typography,@chromatic-com/storybook,@vitest/coverage-v8,pge@types/pg: il driver Postgres è uno solo,postgres.js, anche negli script.
Documenti
- **[ADR 0009](docs/adr/0009-codice-in-inglese.md)**: il codice è in inglese — fino alle colonne, ai valori salvati e alle chiavi dei messaggi — mentre documenti, commenti e interfaccia restano in italiano. Questo rilascio porta la decisione; le rinomine vengono dopo.
- La cronologia delle modifiche passa da 1.646 righe a una **sintesi** di 203 per tema, e i documenti vivi perdono il testo barrato e le note «prima era…»: resta la regola di oggi, col suo perché datato. Il resto lo tiene git.
- Requisiti, casi d'uso, analisi funzionale, stati e manuale sono stati **confrontati col codice** passaggio per passaggio, e riscritti dove dicevano altro. Le domande che solo il committente può chiudere sono diventate punti aperti: B35 (un familiare non si aggiunge dopo la registrazione) e B38–B43.
Database
- **Nessuna migrazione nuova, ma lo schema cambia**:
src/lib/server/db/schema.tsnon dichiara piùseat_assignments.progressivonéseating_areas.next_progressive. Le 14 migrazioni indrizzle/restano com'erano, quindi una banca dati esistente tiene le due colonne e una ricreata le ricrea: la prima ammette il nullo e la seconda ha un default, e il codice non le legge né le scrive. Non breaking. Usciranno con la migrazione iniziale unica che sostituirà le 14 (ADR 0009). - Se in una banca dati esistente restano righe di galleria **senza poltrona**, lo script che le portava su posti veri non c'è più: la strada è ricrearla.
- **
pnpm db:resetè riscritto.** Mostra host e nome della banca dati e chiede di riscriverlo (--yessalta la domanda); poi cancella tabelle, viste, sequenze ed enum, registro delle migrazioni compreso, applica le migrazioni condrizzle-kit migratee semina la sala;--demoaggiunge i dati demo. Prima ricreava lo schema condrizzle-kit push, che lascia vuoto il registro: ilpnpm db:migratedel container avrebbe poi provato a riapplicare tutto.
- un
- v0.21.0 24 settembre 2026
Dal pannello di collocazione si cambia sala
Nei riquadri d'assegnazione l'anello prende il posto della barra
Il posto «Confermato» torna verde pieno: il quadratino resta all'«Entrato»
I posti ♿ escono dai «bloccati»: la platea ha 726 liberi, non 720
La pulizia: 18 dipendenze, 74 chiavi e nove componenti in meno
- **74 chiavi** su 555 in
messages/it.jsonemessages/en.jsonnon le leggeva nessuno: famiglie intere lasciate da schermate rimosse (assign_modal_*,assign_card_*,gallery_map_*,assign_galleries_*). - **18 dipendenze** non erano importate da nessun file, fra cui
svelte-i18n— una **seconda libreria di internazionalizzazione** accanto a paraglide —,bits-ui,handlebars,pg-boss,markedeuuid(il progetto usaulid). - **Nove componenti**:
AssignmentOverview,CapacityStrip,SubTabs,GalleryCole la provaProvaTrePiante, più l'impalcatura mai tolta —src/stories/(804 KB di Button, Header e Page di esempio) e le rotte/demoe/demo/playwright, che erano raggiungibili in produzione. - Nuovo
knip.json: le segnalazioni scendono da **570 a 46** ignorando il codice generato da paraglide e dichiarandoscripts/**come entry. Un rapporto che nessuno leggerà è un rapporto che non esiste.
La suite e2e riportata al presente: da 76 verdi su 111 a 110 su 110
Un cancello che prima non c'era
Documenti e stringhe
Database
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio. Lo schema resta quello della 0.12.0, e
src/lib/server/db/schema.tsnon è toccato. - I posti ♿ cambiano **come vengono contati**, non come sono scritti: il
blockReasonin banca dati resta, sono i tre contatori applicativi (seatCounts,areaCapacities,freeSeatsByArea) a non trattarlo più come un blocco. Nessun intervento richiesto, non breaking.
- **74 chiavi** su 555 in
- v0.20.0 24 settembre 2026
Le card-filtro passano da nove a otto, su due righe
I tre anelli della sala, accanto alle card
«Assegnato» non è più teal ma azzurro
La colonna «Area» diventa «Posto» e dice la poltrona
I minori 3–17 hanno un tetto: cinque per registrazione
Un manuale operativo per il coordinatore
Database
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio. Lo schema resta quello della 0.12.0, e
src/lib/server/db/schema.tsnon è toccato. - Il filtro di stato dell'elenco passa da
eqainArraysulla colonnaregistrations.status: cambia la query, non la struttura. Nessun intervento richiesto, non breaking.
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio. Lo schema resta quello della 0.12.0, e
- v0.19.0 23 settembre 2026
Una finestra sola per chiedere «sei sicuro?»
Chi è in attesa di conferma non si sposta più
La scheda partecipante si riordina
Elenco e piante, tre pulizie
- Le righe dei **minori 3–17** non hanno più comandi: dove siedono e la loro cancellazione stanno nella scheda dell'adulto che li porta.
- Un badge **«Referente»** accanto al nome di chi risponde per un nucleo.
- La barra delle **azioni multiple** non è più sospesa in fondo allo schermo ma sotto i filtri, sopra la tabella.
- Via il riquadro **«Da assegnare»** da tutt'e tre le piante: portava quasi sempre uno zero, e la coda ha già la sua card nella Dashboard.
Un posto ♿ dato a chi non l'ha chiesto, ora si vede
L'Email 1 non promuove più l'app del televoto
Dati di prova
Database
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio. Lo schema resta quello della 0.12.0.
src/lib/server/db/schema.tsè toccato da **soli commenti**: sopraregistration_notesè annotato che il contenuto delle note è ora a discrezione del coordinatore — il divieto di dati sanitari è caduto — e che quindi quei dati possono finire in banca dati, backup e copie. Nessun effetto sulla struttura, nessuna rigenerazione necessaria.- Quel cambio riguarda **che cosa ci si aspetta di trovare** nelle note, non i dati già scritti: non è breaking e non serve alcun intervento. L'unico modo di togliere il contenuto di una nota resta cancellarla, e la cancellazione è soft — la riga rimane.
- v0.18.0 22 settembre 2026
Una sola strada per collocare, e la mappa che dice lo stato prima del clic
Aggiunto
- **
SeatingPlacementButton.svelte**: il comando della collocazione vive ora in un componente solo, usato dalla riga dell'elenco **e** dalla scheda. La scheda aveva tre bottoni nati in momenti diversi — «Assegna posto» (sola platea), «Sposta in platea», «Assegna in galleria» — con verbi che l'elenco non usava. Resta il terzo, che fa una cosa diversa: colloca al primo posto utile invece di portare sulla pianta. - **
AccessibilityMark.svelte**: il ♿ del prodotto in un componente solo, al posto del simbolo riscritto a mano in ogni schermata. Nell'elenco torna **accanto al nome** — la segnalazione è della persona, non della categoria — e resta azzurro, che è ciò che lo tiene fuori dalla famiglia delle categorie; nella pillola del pannello porta **solo il simbolo** (RF-BO-046b2). - **Filtri a più valori nell'URL**: i gruppi viaggiano separati da virgola (
?category=ospiti,stampa), in ordine canonico e senza ripetizioni, così due link che dicono la stessa cosa danno la stessa vista e lo stesso export. Lo **stato** resta a valore singolo, perché è una card che porta anche il conteggio. Nuovilist-filters.spec.tse l'e2efiltri-elenco.e2e.ts. - **La colonna «QR» ha un titolo.** Il badge del biglietto stava dentro la cella dello stato: due informazioni diverse — a che punto è la persona, a che punto è il suo biglietto — in una colonna sola. Ora la colonna è sua; una riga senza biglietto porta un trattino, perché una cella vuota non distingue «nessun QR» da «dato mancante».
- **
party-move.spec.ts** e nuovi casi insala-layout.spec.ts,PlateaMap.svelte.spec.tsetokens.spec.ts, che ora verifica che ogni alias di stato sia dichiarato in **ogni** blocco di tema e punti alla stessa tinta.
Modificato
- **
non_confermatodiventa uno stato collocabile**, entra nell'invariante di nucleo, e ricevere un posto lo riporta adAssegnato(entersAssignedindesign/status.ts, dove prima la regola era scritta due volte). Il comando di riga compare anche su di lui, col verbo «**Riassegna**». - **Il bottone di riga passa da «Cambia» a «Sposta»**: è il verbo del comando da cui si arriva, e «cambiare» presuppone che un posto ci sia già, mentre il pannello serve anche a collocare chi non l'ha mai avuto.
- **La conferma dell'E-mail 2 dice «Invia»**, singola e di massa — prima dicevano «Sì, invia» e «Sì, invia alle selezionate», due nomi per lo stesso atto — e spiega che la scadenza del link si misura in **giorni** a partire dall'invio.
- **L'avviso della collocazione** è verde, si spegne da sé dopo 5 secondi e per un nucleo elenca tutti i posti con l'area nominata una volta e le poltrone accanto raggruppate — «Settore A · Fila 5 · Posti 2, 4, 6» — perché il controllo che si fa subito dopo è «sono rimasti insieme?».
- **L'export scende all'estremo destro della barra**: stava attaccato alle tendine come se fosse il terzo filtro, e invece scarica ciò che i filtri hanno già scelto.
- **Il link di chiusura dei pannelli** — «Chiudi» in uno, «Annulla» nell'altro — diventa una **✕** uguale nei due, e in fondo restano due bottoni metà e metà della stessa altezza.
- **
scripts/pulisci-prove.ts** sfoltisce la banca dati di sviluppo: esigenze di accessibilità da venti a **dieci** (i posti ♿ sono cinque o sei, RF-FORM-021) cancellando le registrazioni in eccesso e non spegnendo il flag, via le registrazioni di collaudo, e i **minori prima dei referenti** perché è la foreign key a dettare l'ordine.
Corretto
- **Un nucleo si spezzava dalla mappa, senza un avviso.** Cliccare la poltrona di un adulto con minori e premere «Sposta» armava la mossa **singola**: i figli restavano dov'erano. L'invariante di nucleo (RF-BO-029c) non se ne accorgeva perché guarda l'**area**, e dentro la stessa sala restava soddisfatta — il gruppo si rompeva sull'**adiacenza**. Era il difetto più grave del rilascio, ed era muto.
- **Gli alias di stato non seguivano il tema.**
--status-assegnato: var(--sp-teal)era dichiarato solo su:root: ilvar()si risolveva **là** col valore chiaro, e il risultato già calcolato scendeva per eredità dentro.theme-dark— la shell del backoffice e quella dell'ingresso. Chip di stato e posti assegnati sulla mappa uscivano con le tinte del tema **chiaro**, e il verde dell'assegnazione su fondo scuro faceva **3,1:1** contro il 4,5:1 richiesto. Gli otto alias sono ora ridichiarati in ogni blocco di tema; il verde è passato a **9,8:1**. - **Una poltrona confermata perdeva l'anello di fuoco da tastiera.** Le classi di stato scrivevano il
box-shadowper intero e, con tre classi di specificità, vincevano su.seat:focus-visible, che ne ha due. Ora dichiarano solo la variabile e l'ombra la disegna.seat.assigned, così il fuoco la **compone** con la propria invece di sostituirla. - **Il pannello restava aperto dopo una conferma riuscita**, lasciando l'impressione che non avesse funzionato: lo apre
?party=nell'URL, quindi azzerare lo stato locale non bastava. Si chiude con un flag legato all'identità del nucleo, senza buttare via l'avviso di esito. - **Esc non chiudeva più il pannello**, che è una delle tre cose che un
dialogdava gratis e un pannello no; rimesso. - **La modale di cancellazione usciva dal riquadro**: ereditava
white-space: nowrapdal<td>in cui vive, e la domanda misurava 546px in uno spazio da 392 invece di andare a capo. - **Gli e2e della mappa erano rossi per ragioni che non c'entravano nulla**: non aspettavano l'idratazione prima di cliccare una poltrona — premevano un bottone reso in SSR — e portavano nomi rimasti al rifacimento del 18/09. Sulla cartella
backoffice, da **29 rossi su 72 a 21**.
Rimosso
- **
SeatAssignModal.svelte** e il suo spec, col relativo scrim e focus trap.PartyProposalè passato inplatea-map-view.ts, col resto del vocabolario della mappa. - **La coda «Non confermati» e la proroga della scadenza** — rotta
registrazioni/non-confermati,extend.tscoi suoi test e ventuno stringhe. La proroga provava a ridare **quel** posto, che alla scadenza era già tornato libero: dipendeva da una corsa che perdeva spesso, e con un nucleo valeva tutto-o-niente. **Resta** l'etichetta d'audit «Proroga della scadenza», perché le righe già scritte vanno ancora lette. Il seguito è in A8. - **Quattro chiavi di messaggio del popover**, rimosse invece che svuotate, e «biglietto emesso» dalla colonna azioni: era una didascalia grigia con l'aria di un comando spento, ripetuta su ogni riga confermata, mentre lo stato lo dice già il chip due colonne prima.
Database
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio. Lo schema resta quello della 0.12.0.
src/lib/server/db/schema.tsè toccato da **soli commenti**: sopracommunication_kindè annotata la corrispondenza fra i valori del dominio (email_1/2/3, invariati) e i nomi nuovi che si leggono a schermo. Nessun effetto sulla struttura, nessuna rigenerazione necessaria.- Lo sfoltimento della banca dati di sviluppo descritto sopra scrive **dati**, non struttura, riguarda il solo ambiente di dev e va lanciato a mano.
- **
- v0.17.0 21 settembre 2026
Il pannello di collocazione dice che cosa si sta facendo
Corretto
- **
partyMembersMissingSeatguardava'platea'scritto in chiaro.** Era vero quando il pannello serviva la sola platea; da quando si apre su tutte e tre le aree, chi sedeva già in Galleria 1 risultava «senza posto» proprio sulla mappa della Galleria 1, e la conferma non si accendeva mai. Ora l'area di lavoro si dichiara. Nella stessa passata il conteggio sul bottone contava i membri **fuori** dall'area invece dei posti scelti in quest'atto, che è ciò che l'atto muove. - **La platea si apriva tagliata a destra.** Tolta la card dalla testa della pagina, la sala ha guadagnato novanta pixel d'altezza e l'ingrandimento d'apertura è salito: il boost del 45% esiste per usare la larghezza che il fit lascia vuota quando a limitare è l'**altezza**, ma quando a limitare è la larghezza moltiplicare fa uscire la pianta dal riquadro. Ora il boost ha per tetto il fit orizzontale (
fitZoomWidth), a qualunque altezza si apra. - **
assignGallerySeatriportava adassegnatol'intero nucleo.** L'update di stato era rimasto incondizionato e retrocedeva unin_attesacol token ancora valido o unconfermatocol QR attivo, mentre l'audit scritto daplacementOfdiceva già la cosa giusta: due righe che si contraddicevano sullo stesso evento, e restava il DB. Ora avanza **solo chi eraregistrato**, come inmoveToGallerye inmovePartyToArea. - **Quattro test e2e non compilavano.** Nel commit di rilascio della 0.16.0 il legame
const posto = await assignViaModal(...)era stato tolto da cinque chiamate, ma quattro test continuavano a usarepostosubito dopo: un autofix da «variabile inutilizzata» applicato troppo in largo.svelte-checkera rosso da allora.
Aggiunto
- **
scripts/ripara-attesa-orfana.ts**, riparazione **una-tantum** del dato: i membri di un gruppo rimasti «In attesa di conferma» **da soli**. Il link di conferma è uno solo, quello del referente (RF-FORM-039), quindi un membro lasciatoin_attesamentre il referente non ci sta più è in uno stato **senza uscita** — non può confermare, non può scadere (lo sweep del timeout cerca un token che un membro non ha) e intanto tiene occupato il suo posto senza che nessuna coda del backoffice lo segnali. Ci finivano dalla disassegnazione del referente, che lo riportava aregistratosenza toccare il gruppo; la regola ora sta nel dominio e lo script chiude le righe rimaste indietro. Il membro **tiene il posto** e tornaassegnato, oregistratose un posto attivo non ce l'ha, con un evento auditgruppo.attesa-annullataper ciascuno. Senza--applyla transazione viene annullata, così l'esito si vede prima di decidere; è **idempotente**.
Database
- **Nessuna migrazione**: nessuna tabella, colonna, vincolo o enum cambia in questo rilascio, e
src/lib/server/db/schema.tsnon è toccato. Lo schema resta quello della 0.12.0. Lo script di riparazione qui sopra scrive **dati**, non struttura, e va lanciato a mano.
- **
- v0.16.0 18 settembre 2026
La collocazione dei posti passa a una funzione di costo, e nasce il pannello
Database
- Nessuna migrazione: nessuna tabella, colonna o vincolo cambia in questo rilascio. In
src/lib/server/db/schema.tsè aggiornato solo il commento diseats, che descriveva ancora il numero di posto come progressivo unico 1…900 in platea: l'ancora d'integrità è(area, fila, settore, numero)per tutte e tre le aree, e il numero è quello stampato sulla poltrona, che ricomincia a ogni fila.
- Nessuna migrazione: nessuna tabella, colonna o vincolo cambia in questo rilascio. In
- v0.15.0 17 settembre 2026
Aggiunto
- **«Assegna» / «Sposta» in fondo alla riga** (RF-BO-029, ritirata il 03/09 e riaperta l'11/09 come **B31**; nuova RF-BO-029e). Il bottone è pieno e porta il verbo giusto per lo stato; la colonna «Area» torna a essere un **dato** e non un comando. Al clic si scelgono le **tre aree** coi posti liberi, quella corrente compresa («attuale · cambia posto»), e ogni voce apre la **pianta di quell'area con la persona già armata**. Il
loaddella mappa legge a parte la persona armata e la tiene **fuori** dai candidati — nella finestra «chi siede qui?» non deve comparire chi è già seduto. Il ritorno all'elenco viaggia nel **form** e solo per la persona arrivata dal link: chi resta sulla mappa a sistemare la sala non viene rispedito indietro a ogni piazzamento. - **Il menù azioni della riga** (
RowActions.svelte, che sostituisceSeatingCell). I due comandi non si ripetono: il verbo dice **dove** mettere la persona, i tre puntini **cosa farne**. Le voci che il dominio salterebbe non compaiono — l'Email 2 solo aAssegnatoeIn attesa, e mai sulla riga di un membro di gruppo (la riceve il referente, RF-FORM-039); il reinvio biglietto solo aConfermato. - **La cancellazione torna in riga, con la modale che le mancava.** Era stata confinata nella scheda il 01/09 perché dall'elenco non si vede che quella persona porta tre minori che cadono con lei: ora la voce c'è, in fondo al menù, staccata e rossa, e la conferma dice il nome per esteso, **quanti minori cadono insieme** e — se ce ne sono — che gli **adulti della stessa registrazione restano**, perché hanno un biglietto proprio e si cancellano uno per uno (RF-BO-038b).
- **L'avviso «Posti non sufficienti»**, prima di far attraversare mezza applicazione. Al clic si confrontano i posti liberi dell'area con le persone del nucleo (
freeSeatsByArea,countPartySizeByRow); verso l'area in cui il nucleo **già siede** non si chiede spazio nuovo, perché cambiare poltrona libera nello stesso atto i posti che lascia. È un controllo **grossolano per costruzione**: non sa nulla di poltrone accanto, quindi un'area con dieci liberi sparsi lo supera e poi rifiuta un nucleo di tre sulla mappa, dove l'adiacenza vive davvero (RF-BO-046c). Serve a non far viaggiare a vuoto, non a sostituire il dominio. - **Il gruppo continua nella fila davanti o dietro** (**B27**). Scelto il posto d'ancora si riempie **prima la fila**, destra e sinistra alternate così il referente resta in mezzo ai suoi; se i posti non bastano si passa alla fila adiacente **sulle colonne allineate** — «davanti e dietro» vuol dire sopra e sotto, non due gruppi lontani nella stessa sala — e fra le due vince la più compatta. Lo stesso ripiego entra nel dominio delle **gallerie** (
bloccoSuDueFile), dove la collocazione è automatica: le tre aree si comportano uguale. - **I minori non si separano dagli adulti** — regola nuova, in un modulo puro condiviso da mappa e dominio (
party-seating-rules.ts:isNearby,minorsAwayFromAdults,isPartySplit). Un **minore 3–17** deve stare nel blocco di posti che si toccano in cui siede un adulto della sua registrazione — accanto, davanti, dietro o in diagonale. La conferma resta spenta **e** il dominio rifiuta (minor_separated), perché una regola che vive solo nell'interfaccia si aggira con una form costruita a mano. Gli **adulti** si possono dividere: la finestra lo dichiara e lascia fare. Cade con questo la «modalità safe/unsafe» ipotizzata in call — la deroga non è un interruttore, è la differenza fra chi può stare lontano e chi no. - **La dichiarazione di responsabilità sta dentro il riquadro del minore dichiarato per primo** (RF-FORM-020). Dal 31/08 era una sola casella **fuori** da entrambi i riquadri: la scelta risolveva il difetto di allora — annidata nei 3–17 non compariva col solo minore sotto i 3 anni — ma la lasciava lontana dai nomi che la riguardano. Ora vive sotto Nome e Cognome del minore, allineata a quei campi, e resta **una sola**: uno
{#snippet}reso in due punti, quindi un solo campo inviato e la spunta che sopravvive al cambio di idea sulle due caselle.
Modificato
- **Fino a «In attesa di conferma» compreso, e non un passo più in là.** La richiesta era «finché l'Email 2 non è stata inviata», ma leggendo il template è venuto fuori che l'**Email 2 il posto non lo dice**: annuncia che c'è e chiede di confermarlo, mentre il posto viaggia col **biglietto**, generato alla conferma con la collocazione di quel momento. La linea si sposta di uno stato: da **Confermato** in poi la riga dice «biglietto emesso» e resta la strada di sempre, spostamento dalla mappa e **reinvio del biglietto** (UC12, RF-BO-029b), che è il rimedio dell'accessibilità e non andava chiuso per fare spazio a questo.
- **Cadono le due restrizioni legate al flag di accessibilità.** «Sposta in platea» è ora offerta a chiunque sia in galleria con lo stato modificabile (e in più, come prima, a chi ha segnalato, in qualunque stato); «Assegna in galleria» a chiunque non abbia un posto. Resta l'avviso «in galleria posti accessibili non ce ne sono» per chi ha il flag: era la parte che serviva davvero (RF-BO-052 generalizzata).
- **In interfaccia si cancella, non si annulla.** L'azione e l'etichetta dello stato diventano **«Cancellato»** — badge, card-filtro, export, riga d'audit. Nel modello, nei documenti canonici e in banca dati resta
annullato: cambia la parola che si legge, non il modello, e la mappatura è scritta una volta sola instati-e-workflow§1. - **Due strade tolte perché senza punto d'ingresso non restano in casa.** Via il **filtro «Area»** dalla toolbar dell'elenco (la toolbar era già piena) e via la **collocazione automatica in galleria** con la sua funzione di dominio
placeInGallery; i suoi due test sono stati riscritti sumoveToGallery, perché quelle regole valgono comunque. - **Il form pubblico: la nota del tetto segue il pulsante** (RF-FORM-037). «Puoi aggiungere fino a 5 persone» stava **sopra** i riquadri, prima ancora che si sapesse dell'esistenza di un pulsante — ed è la risposta a una domanda che nasce guardandolo: quante volte posso premerlo? Ora lo segue, allineata al suo bordo sinistro (il rientro di 28px serve ad allinearsi al testo di una casella, e sotto un pulsante di caselle non ce ne sono).
- **E pesa meno, perché non è una scelta.** Con lo stesso corpo delle due caselle che aprono i riquadri, le tre righe si leggevano come tre richieste equivalenti: «viene con me un minore» è una **scelta**, la dichiarazione è la **conferma** dei dati appena scritti. Il testo scende a 12,5px sul grigio secondario; quadratino, stati ed errore restano identici e il
line-height**non** si tocca, perché è lui a tenere il bersaglio a 24px (WCAG 2.5.8, finding UAT del 31/08). - **La nota sull'età dice di chi è l'età** (RF-FORM-020b): «**L'età dei minori si calcola alla data della serata, 1 marzo 2027.**» — il soggetto era implicito, e la nota sta sotto due caselle che parlano d'altro. La data continua a venire dalla configurazione (
registration.eventDateLabel), non dal testo. - **Il conteggio «205 di 264» esce dalla toolbar dell'elenco.** Diceva una cosa che la pagina dice già due volte e meglio: le **card in cima** portano il conteggio di ogni stato più il totale, la **paginazione** in fondo dice a che punto si è. Restava un terzo numero in una terza grammatica, proprio nella riga in cui si sceglie *che cosa vedere*, non *quanti sono*.
- **L'inserimento manuale perde l'anteprima esito e si distende in larghezza.** L'anteprima veniva dal wireframe e occupava 340px per ridisegnare a ogni tasto un esito che da questa rotta è **sempre lo stesso** (categoria scelta, stato
Registrato, QR non generato, origine «Inserimento Manuale»); l'unica riga che cambiava — email sì o no — la dice già, in tempo reale e accanto al campo che la decide, la nota della regola RF-BO-049. Sparita lei, sparisce la ragione della colonna di destra: il form si riordina in **due righe di due riquadri** — a sinistra ciò che si compila (**Anagrafica**, poi **E-mail**), a destra ciò che si spunta o si annota (**Segnalazioni**, poi **Note interne**) — con Nome, Cognome e Professione sulla stessa riga e la CTA **«Crea la registrazione» in fondo alla pagina**, che si preme quando si è finito di scrivere. La pagina passa da 1100 a **1600px** come la Dashboard; sotto i 1000px tutto torna in pila. - **La card della categoria si accende del proprio colore.** La selezione prendeva bordo, fondo e alone da
--accent, il rosa del backoffice: un pallino verde «Sponsor» dentro una card rosa era l'unico punto in cui il codice colore delle categorie (D3) si contraddiceva da sé. Ora bordo, alone e fondo vengono da--c, la tinta che la card già porta per il pallino. - **«Istituzioni» passa dal teal al giallo.**
#0f766eaccanto al verde#0f7a3ddi Sponsor si distingueva per poco più della saturazione — su un pallino di 11px, per niente. Ora è il **giallo della bandiera** nella taratura già verificata di--sp-gold(#8a6400sul tema chiaro, 5,38:1 sul bianco;#f5c04asullo scuro). Il **teal resta** dov'era,--sp-teal, che è il colore dello stato «Assegnato»: cade così anche la collisione fra una categoria e uno stato, che nella stessa riga d'elenco stanno a due centimetri. - **Due riquadri dicono il loro nome una volta sola.** L'introduzione dell'inserimento manuale diventa «Con questo form puoi registrare manualmente un partecipante», e il riquadro del contatto si chiama **«E-mail»** e basta, facendo da etichetta al campo via
aria-labelledby. Per permetterlo,Fieldha imparato a **omettere l'etichetta visibile** — ma solo quando chi chiama passa un nome accessibile, condizione scritta nel tipo: senza etichetta e senzaaria-labelledbyil campo resterebbe muto per uno screen reader.
Corretto
- **Spostare un nucleo in galleria declassava l'intero nucleo** — difetto latente, che si vedeva solo ora che l'operazione ha un punto d'ingresso.
moveToGalleryriportava **tutti** i membri adassegnato: ammettendo gliIn attesaavrebbe declassato chi ha un token di conferma ancora valido — badge «Assegnato» e link che funziona — e unConfermatoavrebbe perso lo stato tenendosi il QR attivo. Ora lo stato **avanza solo per chi eraRegistrato**, come già facevamovePartyToPlatea, e l'audit scrive gli stati veri invece della coppia fissaregistrato→assegnato. - **La persona armata veniva disarmata un istante dopo l'idratazione** — difetto: un
$effectla cercava fra i candidati della mappa, dove per costruzione non c'è (e non deve esserci), e la lasciava cadere. - **Il banner della mappa diceva «Assegna» a chi stava cambiando sala** — difetto: per il dominio restano due azioni diverse, per chi guarda è uno **spostamento**, ed è una parola sola.
- **Le card del pannello «Nucleo da collocare» erano bianche col testo chiaro sopra**, illeggibili — difetto: usavano
--bg-elevatede--fg-muted, due token che nel progetto **non esistono**, quindi valevano i fallback di un tema chiaro scritti a mano lì dentro. Il pannello scende anche da 380 a 270px: elenca tre o quattro nomi, mentre lo spazio serve alla sala. - **Tre campi su una riga andavano a capo qualunque
flex-basissi scrivesse** — difetto: la larghezza minima automatica di un flex item è quella del suo contenuto, e un<input>senzawidthporta con sé la larghezza propria dei suoi ~20 caratteri (~316px). La metà che conta èmin-width: 0sull'elemento del campo. - **
e2e-helpers.tscercava ancora la casella «*esigenza di accessibilità*»**, rinominata il 15/09: il locator segue l'etichetta nuova e i rossi che ne dipendevano rientrano.
Database
- **Nessuna modifica strutturale**:
drizzle/**è invariato esrc/lib/server/db/schema.tsnon cambia — nessuna tabella, colonna, enum o vincolo, nessuna migrazione da applicare. Lo schema è quello della 0.12.0. - Lo stato
annullato**non cambia nome** in banca dati: la rinomina in «Cancellato» vive solo nelle etichette d'interfaccia, export e audit compresi, ed è mappata in un punto solo.
- **«Assegna» / «Sposta» in fondo alla riga** (RF-BO-029, ritirata il 03/09 e riaperta l'11/09 come **B31**; nuova RF-BO-029e). Il bottone è pieno e porta il verbo giusto per lo stato; la colonna «Area» torna a essere un **dato** e non un comando. Al clic si scelgono le **tre aree** coi posti liberi, quella corrente compresa («attuale · cambia posto»), e ogni voce apre la **pianta di quell'area con la persona già armata**. Il
- v0.14.0 15 settembre 2026
Aggiunto
- **La nota si scrive già nell'inserimento manuale** (RF-BO-015b(f), chiude metà di **B15**). Il form porta una card «Note» con un campo da **200 caratteri**
[provvisorio]: il testo diventa la **prima nota interna** della registrazione, dallo stesso modulo che le scrive dalla scheda — stessa tabella, stesso autore e momento, stesso evento di audit, stesso elenco. Serve al percorso di UC16: il legame fra un accompagnatore e la persona che assiste è l'unica cosa che nessun campo modella, e prima andava scritto aprendo la scheda del record appena creato. La nota è validata **prima** della creazione e scritta **dopo il commit**, fuori dalla transazione come l'Email 1: un rifiuto non lascia registrazioni a metà, e una nota mancata non annulla un inserimento riuscito. Di B15 resta l'**assegnazione contestuale** (RF-BO-022/023).
Modificato
- **La platea è quella della pianta, e il numero è quello stampato sulla poltrona** (decide **B32**). Riletta dal disegno cella per cella come le due balconate: **31 file e 880 celle** contro 900 posti in 30 file — 874 poltrone, 2 postazioni per carrozzina, 4 nella fila 31. La numerazione lascia il progressivo 1…900 e diventa quella **all'italiana** della pianta: dispari 27…13 a sinistra, 11…1 e 2…12 al centro, pari 14…32 a destra. Poiché dentro una fila nessun numero si ripete, il posto si comunica «**Platea — Fila 3 · Posto 25**», **senza settore**: sinistro/centro/destro resta la sola chiave d'identità in banca dati. Le due postazioni per carrozzina del fondo si **nominano** invece di numerarsi («Fila 30 · Carrozzina 1»), perché la pianta lì un numero non lo stampa. Capienza dichiarata: **880** (era 900).
- **«Accanto» in platea non è più
numero ± 1.** Con i numeri stampati due poltrone vicine **differiscono di due**, tranne la coppia 1 · 2 al centro della fila: la ricerca dei posti per un nucleo passa aordine ± 1, la posizione nella fila, che salta i corridoi da sé perché anche le celle vuote consumano un indice. È la stessa correzione fatta in galleria il 14/09 (RF-BO-046c). Il filtro sul settore cade: non serve più. - **Una mappa sola per le tre aree.** La platea era l'unica disegnata dal CSS — file dritte, tre settori, uno stacco ogni dieci file per regola — e la sua forma non veniva dalla pianta. Ora tutte e tre passano dalla **griglia di celle** del layout: corridoi e spazi sono celle vuote, gli stacchi li dà il disegno (prima della 11, della 21 e della 31), e un **tratteggio** separa le due fasce stampate in pianta, **Poltronissima** (file 1–21) e **Poltrona** (22–31), come già fa per i settori A e B in galleria — col loro **nome scritto a lato**, in verticale come sul disegno: i posti liberi hanno un colore solo, quindi senza la scritta il tratteggio non direbbe di che cosa è confine.
- **I posti di platea viaggiano per id, non per numero.** Assegnazione, spostamento e collocazione di nucleo portano l'**id** del posto: con i numeri stampati in platea esistono trentuno «Posto 25», e il numero da solo non identifica più una poltrona. Le gallerie lo facevano già.
- **Il bagliore sul posto appena assegnato segue l'id** — difetto. Leggeva dal form il campo
numero, che col passaggio all'id non c'è più (quindi non si accendeva mai), e lo confrontava col numero della poltrona: riparato così, avrebbe acceso una cella per ogni fila che porta quel numero. - **In platea l'unico blocco invalicabile è la fila 11.** I quattordici posti «chiuso» del dato di agosto erano il modo vecchio di dire che le file di fondo sono corte — ora lo dice la pianta — e i sei ♿ «segnaposto» della fila 20 non erano in pianta affatto. Al loro posto sei posti **veri**, tutti in fondo: 2 postazioni per carrozzina (fila 30) e i 4 della fila 31, marcati
accessibile— assegnabili dal coordinatore, mai dagli automatismi né fra i posti proposti «accanto» (RF-BO-032b). Da confermare col teatro (**B2**, domanda 4). - **Il dato di sala è uno solo.**
$lib/design/gallerie-layoutdescrive anche la platea e si chiama ora **sala-layout**; il seed passa da due moduli a uno (seed/sala-layout.ts) eseed/platea-layout.jsonè cancellato. La **capienza è il conteggio delle celle disegnate** per tutte e tre le aree: platea 880, G1 411, G2 318.scripts/rigenera-posti-galleria.tsdiventascripts/rigenera-posti.tse riallinea anche la platea, rinominando i posti **in loco** per non perdere le assegnazioni. - **Il form di inserimento manuale dice meno.** Via il sottotitolo della pagina, via l'introduzione che elencava i campi obbligatori (lo dicono gli asterischi), via il «Facoltativa.» sotto Professione — lo stesso che il 31/08 era già stato tolto dal form pubblico — e via le tre righe che spiegavano il flag di accessibilità, la regola dei soli adulti e l'esclusione dall'assegnazione automatica. **Nessuna regola cambia**: il dominio continua a imporle, RF-BO-016/019/028c e UC02 restano il posto in cui si leggono. La nota sulla regola email sì/no, senza email, è riscritta come conseguenza invece che come elenco: «*se non inserisci l'email del partecipante il QR non sarà generato e l'accesso avverrà attraverso la verifica nominativa*».
- **La casella dell'accessibilità si chiama «Ha necessità di un posto accessibile»** (prima: «Ha segnalato un'esigenza di accessibilità»). Il flag in banca dati **non cambia** — è lo stesso che alimenta il filtro Richieste → Accessibilità, le tre strade della scheda e la guardia sull'Email 2 — ma l'etichetta è quella che RF-FORM-021 aveva superato il 31/08, perché «posto accessibile» lascia fuori l'ingresso senza gradini, il cane guida, l'accompagnatore. Divergenza voluta e tracciata: nuovo punto **B33**, domanda **15** al coordinatore.
Database
- **Nessuna modifica strutturale**:
drizzle/**è invariato e insrc/lib/server/db/schema.tscambiano soltanto i commenti — nessuna tabella, colonna, enum o vincolo. L'unicità dei posti resta(area, fila, settore, numero), già introdotta l'11/09 per le gallerie e ora indispensabile anche in platea, dove(area, numero)non è più unica: con i numeri stampati esistono trentuno «Posto 25». - I valori di
seat_block_reasonin uso scendono a **due**:fila-11eaccessibile.chiusoeriservato-tecnicorestano nell'enum, che nasce completo apposta per non richiedere migrazioni quando arriverà l'editor dei posti riservati (RF-BO-050, punto aperto **B4**), ma nessun posto li porta più: i quattordicichiusodel dato di agosto dicevano che le file di fondo sono corte, cosa che ora dice la pianta. - Cambia il **dato**, non la struttura.
seating_areas.capacitydiventa il conteggio delle celle disegnate: platea **880** (era 900),galleria_1**411**,galleria_2**318**.seats.ordine, finora nullo in platea, è popolato anche lì. Il riallineamento del database dev passa da **scripts/rigenera-posti.ts** (erarigenera-posti-galleria.ts), che rinomina i posti **in loco** tenendo id e assegnazioni: 876 rinominati, 24 obsoleti rimossi, 4 inseriti — idempotente, e senza--applyprova e annulla.
- **La nota si scrive già nell'inserimento manuale** (RF-BO-015b(f), chiude metà di **B15**). Il form porta una card «Note» con un campo da **200 caratteri**
- v0.13.0 14 settembre 2026
Aggiunto
- **Gli Ospiti si inseriscono di nuovo a mano** dal backoffice (RF-BO-018): tolti il 03/09, tornano per gli invitati personali dell'organizzazione e per chi scrive all'indirizzo dedicato per un'esigenza di accessibilità. L'automatismo continua a non toccarli: esclude l'origine manuale, non la categoria (RF-BO-028c).
- **Le 84 assegnazioni fatte col modello vecchio salgono su poltrone vere** (
scripts/migra-posti-galleria.ts). In banca dati restavano assegnazioni «area più progressivo», senza poltrona: sulla pianta non comparivano e la Galleria 1 diceva «2 occupati» con 86 persone in sala, ognuna con un «Posto n° 12» comunicato che non corrispondeva a nessuna sedia. Lo script le colloca **nella stessa galleria** — l'area è già stata comunicata — col nucleo su posti accanto e nell'**ordine d'arrivo** che il progressivo esprimeva; chi ha il biglietto già emesso non viene saltato ma **nominato**, uno per uno, perché il posto stampato è cambiato e serve il reinvio (UC12): sull'ambiente dev 11 su 84. Senza--applyprova in transazione e annulla; è idempotente ed è già stato applicato su dev, dove le assegnazioni di galleria senza poltrona sono zero. - **Il percorso di registrazione di gruppo ha il suo e2e** (
registrazione/gruppo.e2e.ts): apre tre righe adulto, **toglie quella in mezzo** e verifica che i dati delle altre non slittino — un difetto che passerebbe in silenzio registrando due persone con l'email l'una dell'altra — poi controlla che il gruppo nasca già seduto su poltrone accanto. Il caso UATbatch-gallerie-e-nucleiè **ritirato**, non riscritto — il flusso non esiste più — e sostituito dacollocazione-automatica-alla-registrazione, che verifica lo stesso merito guardando il risultato invece del comando.
Modificato
- **La Galleria 1 è quella della pianta** (RF-BO-053). La I balconata riletta dal PNG cella per cella e rivista col committente: **12 file, 26 palchetti, 411 poltrone** — undici sopra i 400 dichiarati, non una sotto. Il dato dell'11/09 (399 su 14 file), estratto dal testo del PDF e dato per verificato, aveva le **file sfasate di due** (i palchetti 3/4 e 5/6 entrati come file 3 e 4), **70 «palchetti» che erano poltrone del settore B** ai capi delle file, e dodici palchetti veri scartati come doppioni; i numeri delle file 1, 2 e 12 sono stampati in bianco su bianco, invisibili a occhio e presenti nel testo, ed è per questo che l'estrazione trovava «il numero di fila ripetuto». Deciso sulla pianta: il numero è quello stampato; **A e B restano un'indicazione** su mappa e biglietto, non un'identità né un confine — un nucleo **può stare a cavallo** dei due settori (domanda 12); nei palchetti la vicinanza corre **lungo la colonna** (2-4-6-8) e si riempiono **per ultimi**, finché il coordinatore non dice se e come si assegnino (domanda 13, con la capienza 400 o 411). L'indirizzo del posto diventa «Galleria 1 — Settore A · Fila 3 · Posto 25» oppure «Galleria 1 — Palchetto sinistra · Posto 21», perché un palchetto la fila non l'ha: mappa, finestra, popover e scheda del partecipante.
- **Il layout delle gallerie è un JSON a celle**,
src/lib/design/gallerie-layout.json, condiviso fra seed e mappa: ogni fila è la sequenza da sinistra a destra, vuoti e corridoio compresi, e i palchetti sono colonne con i livelli allineati alle file. Da lì discendono forma, vicinanza e capienza. **Il dato cambia forma, non schema**: l'identità in banca dati resta(area, fila, settore, numero), i palchetti stanno a fila 0 col lato come settore, eordineconta anche le celle vuote — così il corridoio centrale separa davvero i posti 1 e 2, cosa che il dato vecchio non faceva. La mappa disegna la galleria come **griglia** dal layout, con lo stesso disegno del posto della platea: corridoi, numeri di fila, tratteggio dove A e B si toccano, una riga tratteggiata e la scritta per ciascun blocco di palchetti, «Platea» sopra e «Galleria 2» sotto al posto del palcoscenico, apertura al 100% che sta nel pannello; una cella disegnata dal layout ma assente in banca dati resta visibile come sagoma, così la forma non dipende dal seed. Lo script di estrazione dal PDF resta come storia, marcato superato: la trascrizione si corregge a mano leggendo la pianta. Il database dev è stato **riallineato in loco** conscripts/rigenera-posti-galleria.ts: le 399 poltrone della G1 rinominate nella loro identità vera tenendo id e assegnazioni — **nessuna delle 89 persone sedute ha perso il posto** — e i 12 palchetti mancanti inseriti. Nessuna migrazione. - **La Galleria 2 è quella della pianta** (RF-BO-053). La II balconata letta cella per cella dal PNG e rivista col committente: **318 poltrone** = 258 nel settore A + 30 + 30 nei laterali B, dieci file, numeri di fila nei passaggi, nessun palchetto. Il dato precedente (321) leggeva tre numeri di fila come poltrone. Le identità dei posti non cambiano: in dev lo script di rigenerazione ha tolto le tre poltrone fantasma e aggiornato l'ordine di 288, senza toccare assegnazioni. Nessuna migrazione.
- **Il tratteggio fra i settori corre anche dove A e B non si toccano**: dove si guardano attraverso un passaggio, sul lato del laterale B verso la sala — i laterali della Galleria 2 e i capi delle file 9–11 della Galleria 1.
- **La finestra di assegnazione dice cosa farà del nucleo.** In galleria, per un candidato con nucleo, proponeva il pulsante dello spostamento di platea e parlava di «posti accanto ai minori»: ora dice che il nucleo sarà seduto accanto e che **se non c'è spazio per tutti non si sposta nessuno**, che è ciò che il dominio fa. Accanto al nome della galleria torna il **riempimento** («*n* su *n* occupati · *n* liberi»), l'unica cosa che le vecchie colonne dicevano meglio della pianta: è calcolato dai posti disegnati, con la stessa base della platea per occupati e liberi, e li chiama «posti» e non «capienza» — le poltrone disegnate sono un altro numero da quello dichiarato, ed è la distanza fra i due a fare la domanda 10.
- **Un nucleo in galleria è seduto «uno accanto all'altro», non «numerato di seguito».** Le balconate sono numerate **all'italiana** — dispari da un lato, pari dall'altro — e due poltrone accanto differiscono di due (3, 5, 7): il codice calcola l'adiacenza sulla colonna
ordinee fa la cosa giusta, erano l'esito e i documenti a promettere numeri consecutivi — vero finché il numero lo dava un contatore nostro, falso da quando è quello stampato sulla poltrona. In platea la frase resta vera. Corretti RF-BO-029d, UC13 e il caso UAT (B32); **A6** non dà più lo spostamento fra G1 e G2 per realizzato — dentro ciascuna galleria sì, fra le due no — e **RF-BO-030** («in galleria nessun fila/numero»), ribaltato da RF-BO-053, porta l'annotazione di superamento. - **L'accessibilità esce dal form pubblico** (B22, deciso col coordinatore). Nel riquadro «Accessibilità» non c'è più la casella «Ho un'esigenza di accessibilità»: resta la riga di contatto — «Se hai bisogno di un posto accessibile, non compilare il modulo: scrivici a … indicando il tuo nome e cognome, ed eventualmente il nome e cognome del tuo accompagnatore. Ci occuperemo noi della tua richiesta.» Chi scrive viene registrato a mano dal coordinatore con la segnalazione (RF-BO-019), che dal form non arriva più. Il backoffice — filtro Richieste → Accessibilità, le tre strade della scheda, la guardia sull'Email 2 — resta com'è.
Corretto
- **La collocazione delle assegnazioni «solo area» prometteva tre cose che il codice non manteneva**, trovate in revisione prima del commit. L'**ordine d'arrivo** era dichiarato, ma
loadPartiesrileggeva le righe senzaORDER BYe chi prendeva le file davanti lo decideva il piano di query. Un nucleo **per metà già collocato** a mano dalla mappa si spezzava: ora il membro con un posto fa da **ancora** e gli altri gli si siedono accanto, come in platea. L'**area** si leggeva dal primo membro e valeva per tutti: un nucleo diviso fra G1 e G2 sarebbe stato accorpato in silenzio, rompendo una promessa già sul biglietto per ripararne un'altra; ora ciascuno resta nella sua galleria. Tre test unitari nuovi: senza le correzioni falliscono. - **L'assegnazione dalla finestra non funzionava in galleria**: posto e persona scelti, conferma, non succedeva niente e il server rispondeva «dati non validi». Gli id dei form dentro la mappa erano **stringhe fisse**: con una mappa sola funzionavano, nella scheda Gallerie ce ne sono **due** e il browser risolveva
form="…"sulla mappa dell'altra galleria, senza finestra aperta e senza il campo del posto. Ora gli id sono unici per istanza. - **La pianta della galleria non si vedeva**: intestazione, legenda e zoom c'erano, in mezzo il nulla. Il contenitore che scorre riempiva la colonna con
flex: 1 1 0, che in platea ha un'altezza e nella scheda Gallerie collassava a **zero**; e l'ingrandimento si apriva al massimo, perché il *boost* d'apertura era tarato sulla platea, trenta file strette e lunghe. Ora lo scroll ha un'altezza minima propria — solo in galleria, dove serve — e le gallerie si aprono sul fit puro. - **La scheda del partecipante diceva «In galleria, senza numero»** a chi un numero ce l'ha dalla 0.12.0: il dato arrivava dal server, quello del biglietto (RF-BO-029d), ma la resa chiedeva «sei in platea?» prima di leggerlo. La mappa mostrava i posti, la scheda no, ed è la scheda che il coordinatore apre quando qualcuno telefona. Ora porta fila e posto, anche per le righe del gruppo.
- **La suite e2e è tornata al presente.** Non girava dall'11/09 — il dev server e il build di Playwright si contendono
.svelte-kit/— e **42 test erano rossi** per cose cambiate quel giorno: undici aspettavano il bottone «Assegna Ospiti alle gallerie», tolto con RF-BO-028; diciassette registravano un Ospite dal form e lo cercavano fra i candidati della platea, dove non c'è più perché **nasce già seduto in galleria**; tre cadevano sulla colonna «Gruppo di». Riscritti senza indebolirli: chi va collocato a mano in platea si registra come **Stampa**, l'Ospite si usa dove si prova l'automatismo — e i test affermano anche l'assenza del bottone —, il ripiego di RF-BO-052 parte dalla **scheda** e non da un elenco d'esito che non c'è più (accessibilita-fuori-dall-automatismo.e2e.ts), le righe dell'elenco si prendono dal link «Apri la scheda di …», che nomina la persona giusta. Due difetti della suite stessa: l'e2e della Configurazione apriva Stampa **nel 2027** e non ripristinava, lasciando la categoria chiusa sul DB dev condiviso per il resto del giro; e il form si apre ora a rete ferma, perché una casella spuntata prima dell'idratazione restava spuntata nel DOM senza che lo stato la vedesse. Restano rossi i **15 test che hanno bisogno di Mailpit**, che sulla macchina di sviluppo non gira. - **Il test unitario «intermittente» delle gallerie non era concorrenza**: era l'helper della capienza dello spec, che ritagliava la sala tenendo poltrone già occupate sul DB dev condiviso e, da quando i palchetti stanno a fila 0, li prendeva per primi. Ora segue l'ordine del dominio e guarda le assegnazioni attive. La morale resta: i test delle gallerie leggono lo stato del database condiviso.
Rimosso
- Il campo
accessibleSeatdal form pubblico e dal suo input di dominio, e la chiaveregistration_accessible_label. Nessuna migrazione: la colonna resta, la accende l'inserimento manuale.
- v0.12.0 11 settembre 2026
Aggiunto
- **La registrazione è di gruppo: fino a sei adulti, ciascuno con la sua email** (RF-FORM-035…040). Sotto il campo Professione del form pubblico c'è «Aggiungi un adulto», nella forma già in uso per i minori: una riga con Nome, Cognome, **Email obbligatoria** e Professione, fino a cinque oltre al referente. Due differenze deliberate dal blocco minori — **nessuna casella da spuntare prima**, perché aggiungere la riga *è* la dichiarazione, e al tetto il pulsante **sparisce** invece di restare disabilitato, sostituito dalla nota che dice perché. Le righe sono numerate **a partire da 2**: chi compila è l'adulto 1, e la numerazione dice quante persone ci sono in tutto. L'email di ogni riga è univoca **anche dentro la stessa registrazione**, dove due righe con lo stesso indirizzo sono la stessa persona due volte, e l'errore si accende **sulla riga** di quell'indirizzo — il vincolo d'unicità dice *che* c'è un duplicato, non *di chi*, quindi il modulo tiene traccia di quale INSERT è in volo quando l'indice scatta. Il tetto vive in configurazione (
registration.maxAdultsPerRegistration, default 6): è una scelta **provvisoria del team** per poter costruire, non la risposta del cliente (B23), e quando arriverà cambierà un valore, non il codice. - **Un clic di conferma, un biglietto a testa.** La verifica reale dell'indirizzo resta **una sola**, quella del referente — «farla su tutte è troppo» — ma il biglietto va **alla persona**: il referente clicca e nella stessa transazione tutto il gruppo passa a
confermatocon un QR ciascuno, poi ogni adulto riceve la **propria Email 3**, al proprio indirizzo, col proprio biglietto e il proprio link di rinuncia. Per dargli un link personale senza dargli un secondo clic di conferma, alla conferma si emette per ciascuno un token **già speso** (usedAtvalorizzato): non conferma nulla — la conferma è avvenuta — ma apre biglietto e rinuncia. Il PDF unico resta quello della **famiglia**: il referente e i suoi minori. - **Le gallerie hanno posti veri, estratti dalla pianta** (RF-BO-053). Il dato non esisteva: della platea c'era un foglio digitalizzato, delle gallerie solo una capienza dichiarata. La fonte è la pianta del Brancaccio, dove si chiamano **I e II balconata** — un PDF vettoriale, quindi ogni numero di posto è un'etichetta con la sua posizione e la geometria si ricostruisce dalle coordinate. Lo script riconosce **ed elimina le etichette di fila** che il disegno stampa in mezzo alle poltrone (si smascherano perché rompono il passo della numerazione: …27, **5**, 25), separa i settori dai vuoti orizzontali — che sono i corridoi — e scrive un JSON committato e revisionabile con un rapporto delle anomalie. Risultato: **G1 399 posti su 14 file, G2 321 su 10**, contro i 400 e 300 dichiarati e mai confermati dal teatro. La **capienza diventa una conseguenza del layout** — tanti posti quanti ne disegna la pianta — invece di un numero tenuto a parte, che infatti dal disegno divergeva.
- **La pianta delle gallerie è la stessa della platea.** Non una mappa nuova: quella della platea, resa capace di disegnare un'altra area. Stessa griglia, stessa legenda, stesso zoom, stessi due gesti — clic su un posto libero per assegnare, «Sposta» dal posto occupato per spostare. Un primo tentativo aveva prodotto un componente dedicato (
GalleryMap): è stato **buttato** quando è emerso che serviva la stessa interazione, perché due mappe che si comportano diversamente sono due cose da imparare invece di una. Il componente condiviso prende tre parametri e nient'altro: l'**area**, l'**azione** a cui inviare — in galleria una sola,assignGallerySeat, che assegna e sposta col medesimo gesto e viaggia con l'**id** del posto perché il numero da solo non ne identifica uno — e i corridoi trasversali, che sono della platea. Le due gallerie stanno una **sopra** l'altra: affiancate, ognuna resterebbe stretta e le file si spezzerebbero. La legenda dice ciò che nell'area **c'è**: nelle gallerie non risultano né posti bloccati né posti accessibili, quindi restano *libero* e *assegnato*, e la condizione guarda i posti e non l'area — se il teatro confermerà che esistono (domanda 10) le voci torneranno da sé. - **Il posto si assegna alla registrazione** (RF-BO-028, chiude B26).
placeOnRegistrationcolloca il nucleo **nell'atto stesso dell'iscrizione**, sulle poltrone accanto, con le stesse esclusioni di prima valutate su una registrazione sola: non Ospiti, non da inserimento manuale, nessuna segnalazione di accessibilità. Non fallisce mai verso l'esterno — a sala piena la registrazione resta valida e compare fra i «Posto da assegnare» — e scrive l'audit con un attore proprio, **sistema-registrazione**: sulla timeline dev'essere chiaro che il posto l'ha dato il sistema, non una persona che non ha premuto nulla. - **Il backoffice dice chi va con chi**, in quattro punti dove un gruppo sarebbe apparso come righe slegate: chi è collegato a un referente **non è più un candidato a sé** e la card del referente porta il badge «*n* adulti del gruppo» accanto a «*n* minori 3–17»; l'elenco ha la colonna **«Gruppo»** — un «Sì» sul referente, il nome del referente sulla riga di chi è stato aggiunto — e si **ordina per gruppo**, referente in testa e membri rientrati sotto un filo verticale; la scheda si intitola **«Gruppo»** invece di «Famiglia» appena c'è un adulto, perché chiamare famiglia tre colleghi sarebbe una parola sbagliata su una schermata che si legge per decidere; l'export CSV guadagna la colonna **«Gruppo di»**, che sulla lista stampata della sera è l'unico modo di sapere chi siede con chi.
- **Sette casi d'uso UAT nuovi**: configurazione di fase zero, invio Email 2 con la guardia di accessibilità, assegnazione di un nucleo in platea, ripiego in galleria e rientro in platea, proroga di un non confermato, reinvio del biglietto con revoca del QR, batch gallerie e nuclei.
Modificato
- **Il nucleo non è più «un adulto e i suoi figli»: è la registrazione.**
referentIdcollegava solo minori, e chi componeva i nuclei risaliva al referente **guardando il tipo** della riga. È bastato togliere quel controllo — il legame diceva già «questa gente si è registrata insieme» — perché tutto il resto seguisse: la collocazione mette il gruppo intero nella stessa galleria su posti contigui, l'invariante di area vale per tutti, lo spostamento di nucleo li muove insieme. **Nessuna regola nuova**: è cambiato *chi* fa parte del nucleo. È anche il punto dove sta il costo vero della registrazione di gruppo — non nel form. - **Il settore si comunica al partecipante.** «Galleria 1 · Palchetti sinistra — Fila 11 · Posto 21», perché con i numeri fisici «Fila 11 · Posto 21» da solo indica **due poltrone diverse**. In galleria i laterali si chiamano *palchetti* e non *settore sinistro/destro*: chiamarli col nome della platea manderebbe la persona a cercare una poltrona in mezzo alla fila. Il progressivo resta nell'etichetta solo per le assegnazioni **vecchie**, fatte quando le gallerie non avevano posti: finché esistono in banca dati vanno mostrate, ed è meglio un «Posto n° 12» storico che una riga vuota.
- **Il dominio assegna poltrone, non progressivi.** La collocazione cerca **posti contigui** — stessa fila, stesso settore, posizioni consecutive — con la stessa regola della platea (RF-BO-046c): un nucleo che non trova un blocco abbastanza lungo passa all'altra galleria e, se neanche lì entra, **resta da collocare invece di spezzarsi**.
- **Scadenza e proroga cascano su tutta la registrazione.** Conseguenza diretta del clic unico: chi è stato aggiunto **non ha modo di confermarsi da sé**, quindi alla scadenza decade col referente e la proroga lo ripristina con lui — «tutta la registrazione o niente», che prima valeva per la sola famiglia. È il prezzo dichiarato della verifica unica, scritto nei requisiti perché il coordinatore lo sappia prima e non la sera. Nuova azione di audit
gruppo.in-attesa, gemella diminore.in-attesa: la timeline di un adulto non può dire «minore». - **Rinuncia e annullamento invece *non* cascano sugli adulti**, deliberatamente. La cascata segue la **credenziale**: chi non ha un link proprio dipende dal referente (i minori, come prima), chi ha un **biglietto proprio** decide per sé — l'adulto del gruppo rinuncia solo per sé e, se il referente si sfila, resta seduto. Portargli via il posto significherebbe cancellare il biglietto di qualcuno che non ha fatto niente. Si annulla uno per uno dalla sezione «Gruppo» della scheda.
- **L'Email 2 non si manda a chi è stato aggiunto.** Un adulto del gruppo un'email ce l'ha, quindi senza guardia sarebbe risultato eleggibile come chiunque altro — e un secondo link di conferma spezzerebbe l'atomicità del nucleo su scadenza e proroga. Il rifiuto vive **nel dominio**, non nell'interfaccia: qualunque percorso ci arrivi — invio massivo, deep-link, URL a mano — trova la stessa risposta. L'email al referente **nomina** chi conferma con lui e dice che ognuno riceverà il proprio biglietto sulla propria casella: è ciò che rende comprensibile il fatto che agli altri, fino a quel momento, non arrivi nulla.
- **L'azione «Assegna Ospiti alle gallerie» è uscita dall'interfaccia.** Non ha più niente da innescare: la collocazione avviene alla registrazione. L'operazione **resta nel dominio** come rete di recupero, senza pulsante — stessa sorte già toccata a
moveGallerynella 0.11.0 — e al suo posto, nella scheda, c'è la mappa.
Database
- Migrazione
drizzle/20260911150145_posti-gallerie: l'identità di un posto passa da(area, numero)a **(area, fila, settore, numero)**. Con i numeri **fisici** delle balconate il vecchio indice non regge — ogni fila riparte e dentro la stessa fila i palchetti hanno la loro numerazione, tanto che **in G1 fila 11 esistono due posti 21**, uno nel palchetto e uno al centro. È anche la ragione per cui il settore entra nell'indirizzo comunicato al partecipante. Non breaking: la platea numera 1…900 e resta unica anche sotto la chiave più larga. - Migrazione
drizzle/20260911152810_posto-ordine: nuova colonna **seats.ordine** (integer, nullable), la posizione nella fila **da sinistra**, 1-based. Serve alle gallerie, dove i numeri non crescono da sinistra a destra (i dispari scendono, poi i pari risalgono): senza, «il posto accanto» non sarebbe calcolabile e la mappa non saprebbe in che ordine disegnare la fila. In platea resta nulla, perché lì il numero è già progressivo per posizione. src/lib/server/db/schema.tsaggiornato di conseguenza; il seed statico popola i posti di G1 e G2 daseed/gallerie-layout.json, estratto dalla pianta e committato come dato revisionabile.
Corretto
- **Il contatore dei progressivi di galleria era monotòno e non riusava i numeri liberati**: su G1 era arrivato a **463 con 400 posti**. Finché il progressivo era interno non faceva danno; da quando è il numero stampato sul biglietto (RF-BO-029d, 0.11.0) si poteva comunicare una poltrona che in sala **non esiste** — e lo si sarebbe scoperto alla porta. Con i posti veri il contatore non serve più e il difetto sparisce con lui.
- **Spostarsi *dentro* la stessa galleria falliva contro sé stesso**, bruciando un numero: lo spostamento non considerava libere le poltrone che il nucleo stava lasciando. Ora sì.
- **Tre test browser della mappa erano rossi**, e due lo erano da prima di questo rilascio: verificavano una conferma a due clic sostituita dalla domanda unica del 03/09 e un filtro professione **tolto** il 02/09 (testo libero del form, la tendina elencava grafie invece di raggruppare persone). Allineati al comportamento vero — il terzo al popover, che ora riceve la collocazione già scritta, settore compreso, invece di comporla da sé scrivendo «Platea» anche in galleria. Rimosso anche
galleryRowsOfnelloaddelle assegnazioni: la mappa condivisa vuole i posti, non le file già raggruppate.
- **La registrazione è di gruppo: fino a sei adulti, ciascuno con la sua email** (RF-FORM-035…040). Sotto il campo Professione del form pubblico c'è «Aggiungi un adulto», nella forma già in uso per i minori: una riga con Nome, Cognome, **Email obbligatoria** e Professione, fino a cinque oltre al referente. Due differenze deliberate dal blocco minori — **nessuna casella da spuntare prima**, perché aggiungere la riga *è* la dichiarazione, e al tetto il pulsante **sparisce** invece di restare disabilitato, sostituito dalla nota che dice perché. Le righe sono numerate **a partire da 2**: chi compila è l'adulto 1, e la numerazione dice quante persone ci sono in tutto. L'email di ogni riga è univoca **anche dentro la stessa registrazione**, dove due righe con lo stesso indirizzo sono la stessa persona due volte, e l'errore si accende **sulla riga** di quell'indirizzo — il vincolo d'unicità dice *che* c'è un duplicato, non *di chi*, quindi il modulo tiene traccia di quale INSERT è in volo quando l'indice scatta. Il tetto vive in configurazione (
- v0.11.0 3 settembre 2026
Aggiunto
- **Il batch gallerie tiene fuori chi ha segnalato un'esigenza di accessibilità — e lo nomina** (RF-BO-028d). Il flag dice che *c'è qualcosa da concordare* (RF-FORM-021), e l'accordo si fa per email fuori dalla piattaforma: accorpare queste persone al mucchio degli altri Ospiti significa deciderne la sistemazione prima di sapere di cosa hanno bisogno. Restano
registratoe l'esito del batch le elenca **per nome**, una riga per nucleo sul referente, ciascuna cliccabile verso la propria scheda: un contatore direbbe quante sono e non su chi andare (UC18). Il controllo sta **dopo** quelli sull'ancora di proposito — se il nucleo è già in una galleria chi manca la raggiunge lo stesso, altrimenti l'esclusione lascerebbe indietro un minore col padre già seduto. Il riquadro ha la tinta d'attenzione, è staccato dall'esito verde e **non si ritira dopo otto secondi** come gli altri avvisi (RF-BO-051): quella è una coda di lavoro da percorrere clic per clic, e ritirarla mentre il coordinatore ci sta dentro sarebbe il difetto, non la cura. - **«Assegna in galleria» dalla scheda** (RF-BO-052), il ripiego del percorso accessibilità. Chi è rimasto fuori dal batch aspetta l'email all'indirizzo dedicato; se quell'email non arriva mai, questo bottone lo tratta come gli altri Ospiti invece di lasciarlo senza posto — e quindi senza Email 2, che al posto è legata. Conferma a due passi con l'avviso esplicito che **in galleria posti accessibili non ce ne sono**: dirlo prima di scriverlo è il minimo. Offerto solo a un
registratocon la segnalazione, mai a un minore, che nel nucleo non decide; il messaggio d'esito nomina la galleria e il numero di posto, che è il dato che finirà sul biglietto (RF-BO-029d). - **Le note interne hanno un'etichetta nella timeline** (RF-BO-015b):
nota.aggiuntaenota.cancellatamancavano daAUDIT_ACTION_LABEL, e senza etichetta la scheda mostrava il codice grezzo in mezzo a righe scritte in italiano. Le due righe restano senza transizione di stato, che è giusto: una nota non muove niente, si aggiunge. - **Otto casi di accessibilità nel seed demo**, scelti e non sparsi a percentuale: tutti Ospiti e tutti
registrato, perché è esattamente l'elenco che il batch lascia indietro. Cinque adulti soli, uno con un minore sotto i 3 anni, due con minori 3–17 — la proporzione è il punto, se metà della coda avesse minori il caso raro diventerebbe quello normale e la demo insegnerebbe la cosa sbagliata. - **Otto nuovi percorsi end-to-end**: esclusione dal batch e assegnazione dalla scheda per l'accessibilità, guardia dell'Email 2, collocazione di un nucleo in platea, cascata di annullamento su una famiglia, note interne (aggiunta, cancellazione, assenza dall'export CSV), pagina account, etichetta di build, sonde di salute
live/ready.
Modificato
- **
assignToGalleryaccettaareacome parametro opzionale**: omessa, sceglie da sé il **primo posto utile** — prima la galleria che contiene il nucleo intero, G1 e poi G2, lo stesso ordine di riempimento del batch. È la forma che serve alla scheda, dove il coordinatore sta rimediando e non sta scegliendo un'area: chiedergliela sarebbe una domanda senza una risposta informata. Se il nucleo è già ancorato in una galleria vince quella, perché ricomporre viene prima dell'ordine di riempimento; ancorato **in platea** l'operazione resta rifiutata, perché quello è uno spostamento (RF-BO-029b), non un'assegnazione.hasAccessibilityRequestentra inPartye si legge sull'intero nucleo: la conseguenza è del nucleo, se c'è qualcosa da concordare si concorda per tutti quelli che viaggiano insieme. - **La colonna di galleria è sola lettura.** Ritirato lo spostamento G1↔G2 nella 0.10.0,
GalleryColconservava ancora il form, la destinazione e lo stato che serviva a decidere cosa disabilitare: col bottone se ne va anche quello, e la colonna non fa più POST. Il dominio (moveToGallery) e la form actionmoveGallery**restano**, senza punto d'ingresso, in attesa della conferma del coordinatore. - **Il testo introduttivo del batch dichiara l'esclusione** invece di lasciarla scoprire dall'esito: chi ha segnalato un'esigenza resta fuori, si trova elencato sotto e si colloca dalla sua scheda, uno a uno.
- **La documentazione recepisce RF-BO-028d e RF-BO-052** — requisiti, casi d'uso, analisi funzionale, punti aperti e domande al coordinatore.
Corretto
- **La suite e2e affamava la platea.** Gli end-to-end girano contro il Postgres di sviluppo **condiviso**, che non si azzera fra un giro e l'altro: ogni giro registrava ~20 persone e ne collocava altrettante senza mai liberare i posti. In quattro giri gli occupati sono passati da 225 a 305 su 900 — 196 dei 305 erano righe dei test — e a quel punto gli spec d'integrazione che hanno bisogno di spazio libero hanno cominciato a fallire per accumulo:
reverse.spec.tsnon trovava più una fila di platea sgombra,party-move.spec.tsnon trovava posti adatti. Test rossi per accumulo, non per il codice in prova, e quindi rossi che non puntavano a niente. UnglobalTeardown(tests/e2e-teardown.ts) restituisce ora i posti alla sala, cancellando **solo** ciò che la suite crea e riconoscendolo per come lo crea, non per quando: il dominio email@e2e.test.invalid, i minori collegati perreferent_ide gli inserimenti manuali senza email, che l'helper marca con un suffisso sul cognome. Nessuna FK èon delete cascade, quindi l'ordine di cancellazione è esplicito;E2E_KEEP_DATA=1lo salta per ispezionare un giro andato male. - **
playwright.config.tsmette nero su bianco che la suite non va lanciata conpnpm devattivo**: dev server e build della suite scrivono nella stessa.svelte-kit/e si pestano i piedi. Il sintomo non punta alla causa —ERR_MODULE_NOT_FOUNDsumanifest-full.jscancellato sotto i piedi del prerender, oppure un preview che parte da un build parziale e cade a metà giro lasciando una scia diERR_CONNECTION_REFUSEDche sembrano test rotti. Le porte sono diverse (5173 contro 4173): è la cartella condivisa a fare il danno.
Database
- **Nessuna modifica strutturale**:
src/lib/server/db/schema.tsedrizzle/**sono invariati dalla 0.10.0.
- **Il batch gallerie tiene fuori chi ha segnalato un'esigenza di accessibilità — e lo nomina** (RF-BO-028d). Il flag dice che *c'è qualcosa da concordare* (RF-FORM-021), e l'accordo si fa per email fuori dalla piattaforma: accorpare queste persone al mucchio degli altri Ospiti significa deciderne la sistemazione prima di sapere di cosa hanno bisogno. Restano
- v0.10.0 3 settembre 2026
Aggiunto
- **Collocazione di un nucleo dalla mappa: i minori 3–17 nei posti accanto** (RF-BO-046). Un minore 3–17 è una registrazione a sé, quindi si collocava da solo, tre giri di finestra, scoprendo solo dopo il primo posto se accanto ce n'erano altri. Ora la card dichiara il legame nei due versi — «Con 2 minori 3–17 da sedere accanto» sul referente, «siede con Mario Rossi» sul figlio — e scegliere il referente non assegna: apre la **proposta dei posti accanto**, che una conferma sola colloca insieme. «Accanto» non è
numero ± 1: nella pianta del Brancaccio i numeri corrono *attraverso* il corridoio (fila 1: sinistro 1–8, centro 9–20), quindi la ricerca resta dentro **fila e settore** e un test dedicato afferma che una famiglia non venga proposta a cavallo del passaggio. Se i posti non bastano **non si assegna nulla** e si dice quanti liberi si sono trovati: collocare il referente e lasciare indietro i figli è il danno esatto che il vincolo di nucleo esiste per evitare. Modulo purosrc/lib/components/adjacent-seats.ts, dieci unit test; i posti ♿ restano fuori dalle proposte automatiche pur essendo assegnabili (RF-BO-032b), perché si concordano, non si riempiono perché capitavano accanto. - **Filtro «Richieste»** (RF-BO-008…013, parte mai realizzata): isola le tre segnalazioni dichiarate in registrazione — minore sotto i 3 anni, minori 3–17, accessibilità. Le prime due sono flag di riga; «minori 3–17» è un
existssui figli legati dareferentId, quindi seleziona i **referenti** che ne hanno dichiarato almeno uno e non i minori stessi, perché l'unità di lavoro del coordinatore è il nucleo. Vale anche per l'export CSV, che condivide la query. Con questo l'«Accessibilità» di RF-BO-031/032/033 smette di essere una colonna da leggere a occhio. Vocabolario condiviso insrc/lib/design/requests.ts, comestatus.tsper stati e categorie. - **Le card in cima alla Dashboard sono i filtri di stato**: la prima è il totale di tutte le richieste di partecipazione arrivate — form pubblico e inserimento manuale — le altre otto sono gli stati del dominio, ciascuna col conteggio sull'intera popolazione. Cliccarne una riscrive il solo
?status=, conserva ricerca/categoria/richiesta e riparte da pagina 1. - **Il posto in galleria ha un numero** (RF-BO-029d). Il progressivo era un contatore interno «per QR e monitoraggio», dichiarato mai comunicato — salvo che
seatPlacementLabello stampava sul biglietto da mesi. Ora è ufficialmente il posto del partecipante e compare anche in backoffice, accanto a ogni nome nelle colonne G1/G2: senza numero, un nucleo che il batch colloca insieme si sparpagliava comunque all'arrivo. I numeri di una famiglia sono **consecutivi** per costruzione, perché il batch colloca i nuclei uno dopo l'altro dal contatore monotòno. - **Badge sulle card della finestra di assegnazione** (minore <3, *n* minori 3–17, ♿ accessibilità): quel che cambia la mossa si legge **prima** di scegliere.
- **Collegamento contestuale alla coda «Non confermati»**, che compare nell'elenco quando il filtro è su quello stato — l'unico momento in cui serve — con il ritorno all'elenco dalla coda. Tolte le sotto-viste a tab, la proroga di RF-BO-040b, che vive **solo** in quella pagina, sarebbe rimasta senza alcun percorso che ci portasse.
- **Voce di legenda «Accessibile assegnato»** sulla mappa (RF-BO-032c): prima la legenda spiegava il ♿ libero e lasciava indovinare l'altro.
- **
scripts/pulisci-prove.ts**: rimuove dall'ambiente dev il detrito delle prove manuali — registrazioni finte, minori, posti occupati e quanto vi pende. Mirato ai soli cognomi degli script di prova, mai ai dati di collaudo UAT o inseriti da altri; senza--applyelenca e basta.
Modificato
- **La finestra di assegnazione diventa una domanda sola** (RF-BO-046b). Al clic la card sale in cima, elenco, ricerca e filtri spariscono, e sotto un divisorio resta una domanda con Annulla a sinistra e Conferma a destra. La domanda cambia col caso e i casi si sommano: un referente con minori *e* segnalazione vede l'elenco dei posti del nucleo insieme alla richiesta di conferma sull'email. Prima la conferma esisteva solo per il ♿, come secondo clic sulla stessa card, mentre i posti del nucleo comparivano in un riquadro sopra l'elenco ancora aperto — due grammatiche per la stessa domanda, e in nessuna delle due si leggeva per intero cosa si stava per assegnare.
- **I minori 3–17 escono dall'elenco dei candidati** (RF-BO-046c): non vanno a posto da soli, si sceglie l'adulto e vengono con lui. Restano in elenco solo quando il referente ha già un posto, perché lì il nucleo non è più da comporre e nasconderli li renderebbe irraggiungibili. Sparisce anche il deep-link «Assegna posto» dalla scheda di un minore, che li avrebbe portati sulla mappa per poi ignorarli in silenzio.
- **I posti accanto si prendono alternando i lati**: il posto subito a destra, quello subito a sinistra, poi il secondo a destra. Prima si esauriva un lato e con due minori il referente finiva a un capo del gruppo — accanto a un figlio e separato dall'altro; ora resta **in mezzo ai suoi**, e quando un lato si chiude l'altro prosegue senza buchi. L'elenco della conferma è in ordine di posto, così si legge come la fila reale.
- **La mappa platea è una volta e mezza più grande**: il posto passa da 16 a 24 px e al 100% si vede quel che prima si vedeva al 150%. Un solo fattore (
MAP_BASE_SCALE) moltiplica ogni misura della griglia via la custom property--sc, così le proporzioni non si spostano; l'intervallo dello zoom scende di conseguenza da 60–240% a **40–160%**, quindi le dimensioni raggiungibili a schermo sono le stesse e si sposta solo dove cade l'etichetta. Senza quel secondo passo il vecchio minimo faceva da pavimento al calcolo di adattamento e la mappa si apriva al **doppio** — misurato, non dedotto. - **In cima alla Platea tre contatori di sola lettura** — da assegnare, assegnati sul totale, posti liberi — al posto della riga «liberi · assegnati · bloccati»: i bloccati non hanno un numero proprio perché non c'è nulla da farci, restano nel totale e in grigio sulla mappa. Le sottoschede passano da pillole riquadrate a **schede sottolineate**, che accanto alle card-filtro della Dashboard non si leggono più come altri filtri.
- **L'inserimento manuale non ammette più gli Ospiti** (RF-BO-028c,
MANUAL_ENTRY_CATEGORIES): restano stampa, sponsor e istituzioni. Un Ospite arriva dal form pubblico e lo colloca il batch in galleria; ammetterlo qui creava l'unico caso di persona che il batch non prende e che nessuno segnala — restava senza posto e, non essendo assegnata, senza Email 2.[DA CONFERMARE con il coordinatore], v.docs/domande-coordinatore.md. - **La selezione per l'Email 2 di massa è ristretta agli stati che il dominio accetta**,
AssegnatoeIn attesa(RF-BO-034…037). Prima si poteva spuntare chiunque non fosseAnnullato— unConfermato, unEntrato— e premere «Invia Email 2» per vederseli contare fra i saltati: un'azione offerta che non sarebbe stata eseguita, col conto che arrivava a selezione già fatta.Non confermatoresta fuori: alla scadenza il posto è stato liberato, quindi quell'invito chiederebbe di confermare una poltrona che non c'è più — la via è la **Proroga**, che prima ripristina il posto. - **Gli avvisi di esito dicono la parola giusta** (RF-BO-050) — «Assegnati» per una prima collocazione, «Spostati» per uno spostamento, perché la stessa operazione serve i due percorsi — portano fila e numero per intero e si ritirano dopo otto secondi; gli errori restano, perché chiedono di fare qualcosa.
- **La sidebar perde i badge numerici**: un «359» accanto a «Dashboard» e un «40» accanto ad «Assegnazione» non dicevano *di che cosa* fossero il conto, e sospesi lì si leggevano come notifiche da smaltire — i due numeri esistono già dove significano qualcosa, nelle card di stato e nei contatori della Platea. Via con loro le due
count(*)che li alimentavano a ogni navigazione. Testo e icone in bianco; icone nuove per Dashboard, Assegnazione e Configurazione. - **La scheda Gallerie si ripulisce**: via la heat-grid dei quadratini (resta la barra con la percentuale), via la nota «senza numero di posto» — non più vera — e via la card «Inseriti da te, senza posto», il cui caso non nasce più ora che l'inserimento manuale non ammette Ospiti. Dall'esito del batch cade la riga «N inseriti da te non sono stati toccati», che conterebbe sempre zero.
- **I controlli di avvio non si attendono più al ricaricamento della configurazione**. Fra essi c'è una chiamata di rete — la discovery OIDC verso Keycloak — e attenderla lì dentro allungava il salvataggio di un parametro: la modifica entrava in vigore solo dopo il round-trip, che con la rete lenta o assente si misura in secondi. La configurazione è già validata; questi sono diagnostica, e la diagnostica non sta sulla strada del lavoro. Restano non fatali e ora girano in background, con l'errore a log.
Corretto
- **Il posto ♿ occupato era inamovibile.** Nel markup i rami erano ♿ libero → blocchi invalicabili → assegnato, e un ♿ *occupato* — che ha
blockReason = 'accessibile'— cadeva fra i bloccati: reso come uno<span>non cliccabile, con l'occupante impossibile da spostare. Il commento accanto dichiarava l'esclusione, la condizione no; il dominio lo consentiva già. Ora è un assegnato come gli altri, stesso verde, icona ♿ nera, popover «Sposta» (RF-BO-032c). - **Un percorso non controllato spezzava i nuclei.** La guardia sui posti del nucleo viveva nella sola finestra di assegnazione, ma il deep-link «Assegna posto» della scheda non ci passa: arma la persona e il clic assegna. Con un referente che porta minori il risultato era il padre su un posto isolato e i figli senza niente. La guardia è stata spostata **nel dominio** (
assignPlateaSeat→party_needs_seats): finché restano due o più membri da collocare, nessuno si assegna da solo, da qualunque percorso; con uno solo rimasto tace, altrimenti non ci sarebbe modo di finire il lavoro o di rimediare a una collocazione storta. In parallelo il percorso armato apre la proposta invece di assegnare, perché un rifiuto dopo il clic è una porta sbattuta in faccia, non una guida. - **Gli helper e2e scrivevano su un database diverso da quello del server sotto test.** Usavano
process.env.DATABASE_URL ?? '…@localhost:5432/app', ma quella variabile non è esportata quando si lanciapnpm test:e2e: il server la legge da.envvia dotenvx, il processo di Playwright no. Ora la fonte è la stessa del server.
Rimosso
- **Lo spostamento di una persona fra G1 e G2** (RF-BO-029, ritirato). È un requisito canonico, ma nessun documento diceva a quale bisogno rispondesse — né la tabella dei requisiti, né UC13, né l'analisi funzionale: tutti descrivono cosa fa, nessuno perché. E il motivo non è ovvio, perché muovere qualcuno fra due gallerie non migliorava la sua sistemazione: cambiava una parola sul biglietto e bruciava un progressivo. Ritirato dall'interfaccia **col dominio lasciato pronto** (
moveToGallerye i suoi test restano, senza punto d'ingresso) e la domanda messa nero su bianco indocs/domande-coordinatore.md: se emerge un caso reale si riaccende, se non emerge si cancella. Sparisce con esso la fonte principale dei buchi nella numerazione dei posti di galleria. - **La Panoramica dell'Assegnazione**: era una schermata che si attraversava per arrivare al lavoro vero, la mappa. Restano **Platea** e **Gallerie**, e senza
?tab=si atterra sulla Platea; i vecchi link a?tab=panoramicaci ricadono invece di dare errore. Esce di scena con lei la striscia «Saturazione aree»: RF-BO-003 resta soddisfatto ma **diviso** fra le due sottoschede, e il colpo d'occhio sulle tre aree insieme non c'è più.AssignmentOvervieweCapacityStriprestano nel codice, raggiungibili solo da Storybook. - **Il filtro per professione** dalla finestra di assegnazione (RF-BO-046): è testo libero del form pubblico, quindi la tendina elencava le grafie che la gente scrive — «Matematica» e « matematica » erano due voci — invece di raggruppare persone. Restano categoria e accessibilità; la professione si vede sulla card e si cerca dalla ricerca libera. Rimossi con esso il campo dal modello dei filtri e
distinctProfessions, coi loro test. - **La tendina «Stato» e le due sotto-viste a tab** (Elenco / Non confermati) della Dashboard, sostituite dalle card-filtro: la tendina diceva la stessa cosa con meno informazione. Via anche la vecchia card «Registrazioni totali» — a confondere non era il totale ma il nome, che sembrava parlare dei soli
registratoseduti lì accanto — e il sottotitolo sotto il titolo.
Database
- **Nessuna modifica strutturale**:
src/lib/server/db/schema.tsedrizzle/**sono invariati dalla 0.9.0. - Aggiunto **
scripts/apply-notes-migration.ts**, che applica la migrationdrizzle/20260902124535_note-interne(tabellaregistration_notes) agli ambienti in cui non era mai passata. Il DB di dev nasce dadrizzle-kit push, quindi non ha la tabella di bookkeepingdrizzle.__drizzle_migrationssu cuidb:migratesi appoggia; senzaregistration_notesilloaddella scheda partecipante falliva e il drawer rispondeva 500. Idempotente — gli oggetti già presenti si saltano — e riusabile sugli altri ambienti nella stessa condizione.
- **Collocazione di un nucleo dalla mappa: i minori 3–17 nei posti accanto** (RF-BO-046). Un minore 3–17 è una registrazione a sé, quindi si collocava da solo, tre giri di finestra, scoprendo solo dopo il primo posto se accanto ce n'erano altri. Ora la card dichiara il legame nei due versi — «Con 2 minori 3–17 da sedere accanto» sul referente, «siede con Mario Rossi» sul figlio — e scegliere il referente non assegna: apre la **proposta dei posti accanto**, che una conferma sola colloca insieme. «Accanto» non è
- v0.9.0 2 settembre 2026
Aggiunto
- **Spostamento di un nucleo dalla galleria alla platea** (UC16, RF-BO-029b/029c). L'Ospite che ha segnalato un'esigenza di accessibilità viene collocato in galleria dal batch come tutti; quando scrive all'indirizzo dedicato, il coordinatore lo sposta in platea **con tutto il suo nucleo** in un atto solo: i posti si scelgono tutti prima e restano «in attesa di conferma» — finché non si conferma, in banca dati non è cambiato nulla — poi una conferma sola li muove insieme. Se un posto risulta occupato alla conferma **non si muove nessuno**. Vale nei due versi e gestisce nello stesso atto chi va spostato e chi riceve la **prima** assegnazione, perché un nucleo con un membro liberato a mano sarebbe altrimenti impossibile da collocare.
- **Note interne sulla scheda partecipante** (RF-BO-015b): elenco in aggiunta con **autore e momento**, non un campo sovrascrivibile — serve ricostruire *quando* è stato concordato *cosa*. Cancellabili (con la cancellazione in audit, che conserva il testo), **solo backoffice**, mai nell'export CSV, **nessun dato sanitario**: un testo libero nato per l'accessibilità è il punto in cui patologie e diagnosi rientrerebbero dalla porta di servizio. Sono l'unico posto dove può vivere il legame fra un accompagnatore adulto e la persona che assiste, che nessun campo modella.
- **Assegnazione di una singola persona in galleria** (RF-BO-028c) e pannello **«Inseriti da te, senza posto»**: chi il coordinatore inserisce a mano non entra più nel batch, quindi deve essere visibile — un inserimento non collocato resta senza posto e non può ricevere l'Email 2.
- **Segnalazione di accessibilità nell'inserimento manuale** (RF-BO-019), che il requisito prevedeva e il form non raccoglieva. Serve all'accompagnatore inserito a mano.
- **Guardia sull'invio dell'Email 2** a chi ha segnalato un'esigenza ed è ancora in galleria (RF-BO-037b): la conferma che seguirebbe **cristallizza** quel posto, e correggere dopo costa un reinvio biglietto con revoca del QR. Dalla scheda è un avviso che si supera deliberatamente; nell'invio di massa quei destinatari sono **saltati e contati a parte**, con il rimedio giusto a schermo. La proroga eredita la guardia, perché è lo stesso invio.
- **Area e posto di ogni minore** nella sezione «Famiglia» della scheda: per un vincolo il cui punto è «non lasciarne indietro nessuno», vedere dove sono seduti i figli guardando la scheda del padre è il dato principale della schermata.
Modificato
- **Il batch gallerie colloca nuclei interi**, non persone (RF-BO-028b). Un nucleo che non entra nello spazio residuo di G1 va **intero in G2**, e quei posti restano ai nuclei più piccoli che seguono. Prezzo accettato e messo per iscritto: l'ordine di registrazione non è più rispettato in modo stretto, e l'area è un dato che comunichiamo al partecipante. L'esito distingue i motivi di mancata collocazione — gallerie piene, nucleo non capiente, galleria del referente piena — perché un overflow dichiarato mentre a video ci sono posti liberi si legge come un difetto.
- **Il batch prende solo le registrazioni da form pubblico** (RF-BO-028c): ciò che il coordinatore inserisce a mano lo colloca a mano. Nei nuclei misti decide l'origine del referente.
- **Lo spostamento G1↔G2 muove il nucleo** quando c'è un nucleo (RF-BO-029): l'azione resta per persona, ma un adulto solo si sposta da sé e un referente con minori porta con sé la famiglia. «Stessa area» vale alla grana esatta: G1 e G2 sono aree diverse, e lasciare indietro un minore reintrodurrebbe la famiglia spezzata che il batch per nuclei esiste per evitare.
- **I posti ♿ sono sempre assegnabili dal coordinatore** (RF-BO-032b). Restano fuori da ogni automatismo, ma al clic si comportano come posti liberi: supera la formulazione «non assegnabili in qualsiasi circostanza, anche in caso di sold-out», che impediva di registrare a sistema proprio la sistemazione concordata via email. Sulla mappa hanno un aspetto proprio — bordino rosa, fondo grigio scuro, icona bianca — e restano riassegnabili anche da occupati.
- **La mappa platea si semplifica.** Via la coda laterale «Da assegnare in platea» (ricerca e filtri vivono nella finestra che si apre cliccando il posto), il selettore «Prima il posto / Prima la persona» col suo form fila/numero, le quattro fasce di colore dei posti liberi, i focus di settore e la scelta «Nome intero / Sole iniziali». La mappa occupa tutta la larghezza e si apre **una volta e mezza più grande** del solo adattamento allo schermo: a fit, su 30 file, vinceva l'altezza e i posti restavano minuti. I contatori salgono in cima alla pagina.
- **L'icona ♿ è un glifo monocromatico** e la stessa in tutta l'app: il carattere è un emoji, che i sistemi disegnano come badge blu col simbolo dentro.
- **L'inserimento manuale resta agli adulti soli** (RF-BO-016, RF-BO-019 ridotto): qualunque minore al seguito richiede la dichiarazione di responsabilità, e qui non si raccoglie alcun consenso digitale. Un adulto che porta minori passa dal form pubblico.
Rimosso
- **La liberazione dei posti, singola e per fila.** Il vocabolario delle operazioni si regge su tre azioni che non la richiedono: *cambio posto* → sposta, *non viene più* → annulla, *ho sbagliato adesso* → «Annulla assegnazione» dell'avviso di successo. Liberare **senza destinazione** era rimasto l'unico modo di spezzare un nucleo e di riesporre un Ospite al batch; e per la fila intera la motivazione scritta — le ondate dopo le scadenze — è già coperta dall'automatismo, che alla scadenza libera i posti da sé. Se la fila intera servisse davvero va rifatta sapendo che spezza i nuclei in blocco: è una domanda aperta col cliente (punto B16), e l'operazione di dominio resta dormiente.
Corretto
- **Il posto ♿ non era cliccabile** fuori dal flusso del nucleo, e da occupato cadeva nel ramo dei bloccati: l'occupante non si vedeva e il posto risultava bloccato invece che riassegnabile.
- **La suite e2e delle registrazioni era rossa dal 31/08**: l'helper cercava la casella «posto accessibile», etichetta cambiata in «Ho un'esigenza di accessibilità» col rename di RF-FORM-021. Corretti anche due locator troppo larghi (
Applica,Azioni) che pescavano il selettore di paginazione e l'intestazione delle spunte. - **Un test flaky** sull'audit delle note: confrontava la sequenza degli eventi con una query senza
order by.
Database
- Aggiunta migrazione
drizzle/20260902124535_note-interne: nuova tabellaregistration_notes(id,registration_id→registrations,body,author,author_name,created_at,deleted_at,deleted_by) con indice suregistration_id. - Aggiornato
src/lib/server/db/schema.tscon la tabella e i tipiRegistrationNote/NewRegistrationNote. - **Non breaking**: solo aggiunta: nessuna colonna, vincolo o enum esistente è stato modificato. Va comunque applicata prima del deploy, perché la scheda partecipante legge le note a ogni apertura.
- v0.8.0 2 settembre 2026
Aggiunto
- **Paginazione delle tabelle di backoffice.**
src/lib/design/pagination.tsè il vocabolario condiviso — query param (page,per), taglie offerte (10/20/50), aritmetica della finestra di pagine e costruzione degli URL — usato sia daiload(che tagliano la query conlimit/offset) sia daPagination.svelte, che disegna barra, selettore «Righe per pagina» e link. Puro e coperto dapagination.spec.ts: nessuna regola di dominio, solo pagine e URL. Un URL manomesso (per=7,page=-1,page=99) ricade sui valori di partenza o rientra nei limiti, non dà errore. - Barra di paginazione su **Registrazioni** e sulla **coda Non confermati**, con storia Storybook (
Pagination.stories.svelte) e caso UAT dedicato (uat/use-cases/paginazione-elenco-registrazioni.md). - **Annullamento del singolo minore dalla scheda del referente**: nell'elenco «Famiglia» del drawer ogni minore non ancora annullato ha il suo grilletto con conferma a due passi. Se l'adulto non se lo porta più dietro si annulla il minore da solo, senza toccare il referente — la cascata vale in un verso solo. Storia Storybook per lo stato in conferma.
- Colonna **«Minori 3–17»** nell'elenco Registrazioni, con
countMinorsByReferent: una query sull'insieme delle righe a schermo, non una per riga. Conta i minori *indicati*, qualunque sia il loro stato.
Modificato
- **L'elenco Registrazioni serve una pagina alla volta** (finding V7 della verifica del 31/08/2026: 208 righe erano 426 KB di HTML, ~3,3 MB proiettati a regime).
listRegistrationRowsprende una fetta facoltativa ecountRegistrationRowsconta il risultato filtrato: la stessa query serve la pagina a schermo e l'**export CSV, che resta intero** — si scarica quel che i filtri selezionano, non quel che si vede. - La coda Non confermati ordina ora per scadenza **e id**: senza un ordine totale, a parità di scadenza la stessa registrazione poteva comparire su due pagine o su nessuna.
- «Seleziona tutto» è la **pagina corrente**, non l'intero risultato. Gli id restano selezionati al variare di filtri e pagina, ma contano e si inviano solo quando tornano visibili. Chiudendo la scheda dalla pagina 3 si torna alla pagina 3.
- **Annullamento di massa rimosso** dalla bulkbar (
?/cancelBulk,cancelRegistrations, relative chiavi di traduzione): è un'operazione terminale che si porta dietro i minori collegati senza dirlo. Si annulla una registrazione alla volta, dalla sua scheda. Alla bulkbar resta la sola «Invia Email 2». - **Colonne dell'elenco riviste**: via «Professione» e «Data registrazione» — ci sono nella scheda e nell'export, non guidano il lavoro del coordinatore — e la colonna «Minore <3 e accessibilità» si divide nelle due che era, perché sono due domande diverse. Via anche la colonna «Azioni»: le azioni di riga vivono nella scheda.
- **Caselle di spunta e radio disegnati dall'app**, in
src/routes/layout.csse quindi validi in ogni form, tabella o pannello: ilborder-radiussui controlli nativi è ignorato da ogni browser, e il plugin forms di Tailwind porta un disegno suo fuori dai token. Bordo da 1,5px sul fondo della card, riempimento d'accento e segno in--accent-ink; il trattino della selezione parziale («seleziona tutto» delle tabelle) è disegnato perché il segno nativo non esiste più. Sottoforced-colorstorna il controllo nativo, l'unico che il sistema sappia disegnare. - Stato d'errore delle caselle: dall'anello esterno a bordo rosso più riempimento tinto, la stessa lingua dei campi di testo, ora che la casella ha un bordo suo.
- **Testata del form pubblico a due righe con il marchio a destra**: la testata smette di essere centrata — un titolo centrato accanto a un marchio allineato a destra non ha un asse condiviso — e il marchio prende un raggio di 10px, che trasforma il suo fondo bianco in una targa. Le due righe sono due messaggi (
registration_masthead_line_1/_2);registration_titleresta intero per il<title>. - **Fascia pride da sei bande nette a gradiente continuo**, interpolato in oklab perché in sRGB il tratto verde-blu passa da un teal spento. Stessi sei colori della bandiera, un solo valore per entrambi i temi: la fascia è un segno, non una superficie tematizzata.
Corretto
- **WCAG 1.4.3 (contrasto del testo)**: nove riempimenti d'accento dipingevano il testo di bianco fisso — selettore di categoria, pulsanti pericolo pieni, badge «Entrato» pieno, pulsante dello spettro, i due avatar, i pulsantini pericolo del drawer. Sul tema scuro quei riempimenti sono le tinte chiare, dove il bianco stava a 2,2–2,8:1 contro il 4,5:1 che il testo da 14px/600 richiede. Tutti passano a
--accent-ink, il cui contrasto su ogni tinta è già sotto contratto intokens.spec.ts. Il tema chiaro non cambia: lì l'inchiostro è bianco.
Database
- Nessuna modifica: né migrazioni in
drizzle/**né variazioni asrc/lib/server/db/schema.ts.
- **Paginazione delle tabelle di backoffice.**
- v0.7.0 1 settembre 2026
Aggiunto
src/lib/styles/tokens.spec.ts: contratto di contrasto verificato da 47 asserzioni — ogni tinta dello spettro e di categoria è controllata a ≥4.5:1 sulla superficie del proprio tema, sia come primo piano (testo, pallino, bordo) sia come riempimento con l'inchiostro del tema sopra; verifica anche che--cat-*e--cat-*-accentrestino identici in ogni tema, invariante su cui si appoggiadesign/status.ts.- Casi UAT per percorsi finora scoperti:
registrazione-con-minori-e-accessibilita.md,conferma-partecipazione-link.md,rinuncia-partecipante.md. - Casi d'uso **UC11–UC15** in
docs/casi-uso.md(invio Email 2, reinvio biglietto con revoca del QR, gallerie G1/G2, elenco/filtri/export, configurazione Fase 0): percorsi già realizzati che l'analisi funzionale trattava come righe del §9. I dieci casi esistenti passano da flusso lineare a flusso + varianti + eccezioni, con il comportamento del gruppo famiglia su conferma, proroga e rinuncia.
Modificato
- **Ogni tinta esiste ora in due versioni, una per tema.** Prima ne esisteva una sola: le tinte dello spettro erano tarate sul fondo scuro del backoffice e sul chiaro cadevano a 1.8–3.0:1, mentre quelle di categoria erano tarate sul bianco del form e sullo scuro cadevano a 1.9–2.9:1. Introdotto
--accent-ink— bianco sul tema chiaro, quasi-nero sullo scuro — che permette a una sola tinta per tema di fare sia da testo sia da riempimento, ecolor-schemeesplicito su entrambi i temi. - Sparita la ragion d'essere delle varianti
--cat-*-accent: con l'inchiostro che segue il tema coincidono con la tinta base. I due nomi restano allineati e il valore è ripetuto anziché aliasato, perché un alias dichiarato su:rootresterebbe chiaro dentro il sottoalbero.theme-darkdella shell di backoffice. - **Anello di fuoco pieno al posto di quello traslucido**: da
box-shadowal 25–55% dell'accento aoutline: 2px solid var(--accent)con stacco di 2px, su chip dei filtri, card candidato, pulsanti della mappa di platea, controlli di zoom e submit. Sui posti della griglia resta unbox-shadow(ora pieno): lì lo stacco esterno invaderebbe i posti vicini. - Stato d'errore: l'etichetta non si colora più di rosso in
Field.svelteeCheckboxField.svelte— l'etichetta dice *quale* campo è, non come sta. Restano rossi il bordo e il messaggio. - La nota con l'indirizzo per l'accessibilità è **sempre visibile**, non più condizionata alla spunta: chi ha un'esigenza diversa da un posto — un cane guida, l'ingresso senza gradini — deve trovare il canale prima di decidere se la casella lo riguarda, e la nota stessa dice di spuntarla.
- Riga del consenso al regolamento: il link «Regolamento di Sala» è ora inline dentro la frase (nuove chiavi
registration_room_rules_before/_after, rimossaregistration_room_rules_label). - Righe dei minori 3–17 impilate anziché affiancate: nella card da 460px le etichette numerate («Cognome del minore 1») spingevano il riquadro oltre i propri bordi. Dal secondo minore in poi una riga di stacco tratteggiata.
- Rimossa la nota «Obbligatoria per gli Sponsor.» dal campo Azienda ed esplicitato il testo d'aiuto del minore sotto i 3 anni («un solo minore sotto i 3 anni per ogni adulto che si registra»).
- Documentazione canonica riallineata al costruito: planimetria schematica ed export CSV dichiarati **in v1** (erano ancora
[DA CONFERMARE]e «fuori scope v1»), login Staff Ingresso segnato come risolto, §14 riscritto sui punti aperti effettivamente aperti (B2, B4, B14, E1).
Corretto
- **WCAG 2.2 SC 2.5.8 (area di tocco 24×24)**: caselle di spunta da 18×18 a 24×24 nel form pubblico e da 16×16 a 24×24 nelle tabelle di backoffice; le etichette, che commutano la casella e sono quindi target a loro volta, portate a
line-height/min-heightdi 24px. Una di queste caselle è un consenso obbligatorio. - **WCAG 1.4.11 (contrasto dei componenti non testuali)**: bordo del pulsante «aggiungi minore» e delle chip di focus della mappa da 30–45% a 70% dell'accento — stavano a 2.3–2.9:1, sotto la soglia di 3:1, ed è l'unica cosa che disegna il pulsante; il caso peggiore fra le tre categorie e i due temi è ora 3.34:1.
- Tabelle di
registrazionienon-confermati:overflow-x: autoal posto dioverflow: hidden. Su un portatile da 1440px la tabella è più larga della viewport e le ultime colonne (data, azioni di riga) erano **irraggiungibili**, non solo tagliate.
Database
- Nessuna modifica: né migrazioni in
drizzle/**né variazioni asrc/lib/server/db/schema.ts.
- v0.6.0 31 agosto 2026
Aggiunto
- Shell dello scanner d'ingresso della serata (
/ingresso) con ruolo dedicatostaff-ingressoe guardie di rotta (wayfinder «Ingresso della sera», ticket 04), e script idempotente per creare ruolo e account operatori su Keycloak (pnpm kc:staff-ingresso, ticket 08). - Azione «libera fila» dalla mappa della platea nel backoffice assegnazioni (wayfinder HiFi ticket 10).
- Toolkit UAT vendorizzato (
uat-setup,uat-author,uat-run,uat-guide), casi d'uso della registrazione e run di collaudo registrati sottouat/. - Opzione di configurazione
registration.eventDateLabel(envREGISTRATION_EVENT_DATE_LABEL): data della serata mostrata nella nota sull'età dei minori, configurabile perché ancora un'ipotesi indocs/timeline.md.
Modificato
- Form pubblico di registrazione: la sezione «Richieste speciali» è divisa in **«Minori»** e **«Accessibilità»** — la prima raccoglie dichiarazioni su chi si porta con sé, la seconda una richiesta, e «speciali» accanto alla disabilità è terminologia da evitare.
- Testi del riquadro Minori riscritti: le due caselle rispondono alle stesse domande (posto? biglietto?) con la stessa struttura, senza gergo interno («per registrazione», «adulto referente», «QR personale», «posto assegnato») e senza maschile generico — «bambino» diventa «minore», termine epiceno.
- **Confini d'età dei minori: «sotto i 3 anni» e «dai 3 ai 17 anni»** (erano «sotto i 3» e «tra 4 e 18»). Il vecchio intervallo lasciava scoperti i treenni e includeva i diciottenni, che sono maggiorenni. L'età si conta alla data della serata.
[DA CONFERMARE col Teatro Brancaccio — punto aperto B14] - La casella dell'accessibilità passa da «Richiedo un posto accessibile» a **«Ho un'esigenza di accessibilità»**, così da coprire anche ingresso senza gradini, cane guida, accompagnatore; alla spunta compare la nota con l'ordine delle operazioni e il contatto email. Di conseguenza le diciture di backoffice e assegnazione dicono «esigenza di accessibilità» e non più «richiede un posto accessibile».
- Accento della categoria **Stampa dal rosso al blu** della fascia pride: con gli asterischi e gli errori sempre rossi, in Stampa l'intero form prendeva il colore dell'allarme.
- Segnali di obbligatorietà uniformi: asterischi sempre rossi (non più tinti dalla categoria) e stato d'errore che colora bordo, etichetta e messaggio in tutti i form dell'applicazione.
- Rimosse le note «Facoltativa.» dai campi non obbligatori: il form dichiara già in apertura che i campi con
*sono obbligatori. - Backoffice: colonna «Richieste speciali» → «Minore <3 e accessibilità», tag «Minore 4–18» → «Minore 3–17» (anche nell'export CSV), scheda partecipante allineata.
- Palette di categoria di
docs/design-system.htmlriallineata al codice: via la categoria «Talent», fuori dalla v1, e nota che le Istituzioni entrano solo per inserimento manuale.
Corretto
- **Dichiarazione di responsabilità genitoriale mancante col solo minore sotto i 3 anni**: la casella viveva dentro il blocco dei minori 4–18 e la regola server contava solo quelli, quindi si poteva registrare un adulto con un bambino al seguito senza alcuna dichiarazione (RF-FORM-020).
- Righe dei minori senza validazione progressiva: nome e cognome bloccavano l'invio ma non mostravano l'errore sul campo, e il server restituiva un solo codice per l'intero blocco senza dire quale riga fosse incompleta. Gli errori sono ora per riga, anche senza JavaScript.
- Blocco al submit invisibile: quando a fermare l'invio era la validazione nativa del browser non compariva alcun riepilogo, perché era legato alla risposta del server. Ora ogni campo obbligatorio mancante si accende insieme agli altri.
- Etichette dei campi minore duplicate: le righe sono numerate («Nome del minore 1», «Nome del minore 2»), che risolve anche la lettura da screen reader con più minori.
- Pulsante «Aggiungi un minore» indistinguibile da «Rimuovi»: ora prende l'accento della categoria.
Database
- Nessuna modifica di struttura.
src/lib/server/db/schema.tsè stato toccato nei soli commenti (allineamento della dicitura «minori 4–18» → «3–17»); nessuna migrazione aggiunta o modificata indrizzle/.
- Shell dello scanner d'ingresso della serata (
- v0.5.1 23 luglio 2026
Modificato
- Aggiornata
ROADMAP.mdcon promozione delle voci completate a release0.5.0(data e versione) e riallineamento degli stati in elenco. - Aggiornato
.dockerignorecon eccezione!ROADMAP.mdper includere la roadmap nel contesto build Docker.
- Aggiornata
- v0.5.0 22 luglio 2026
Aggiunto
- Pagina Roadmap (
/roadmap) che rendeROADMAP.mdcome vista per stato di avanzamento (rilasciato / in sviluppo / da fare / da confermare / dopo la v1), con versione e data di rilascio per le feature già consegnate; nuovo virtual modulevirtual:roadmap(pluginraw-markdowngeneralizzato convirtual:changelog), parsersrc/lib/roadmap.tscon test, card e link nell'hub di sviluppo.
- Pagina Roadmap (
- v0.4.0 21 luglio 2026
Modificato
- Mappa della platea in backoffice allineata alla pianta ufficiale del Teatro Brancaccio: file dritte (rimossa la curvatura parabolica), fasce di prezzo (
Poltronissima Gold,Poltronissima,Poltrona A,Poltrona B) come tinta dei posti liberi, stacco verticale tra blocchi di 10 file, numero di fila visibile nei corridoi e legenda aggiornata (PlateaMap,platea-map-view, traduzionimessages). - Aggiornati test e story di
PlateaMapper riflettere la nuova geometria e le fasce.
- Mappa della platea in backoffice allineata alla pianta ufficiale del Teatro Brancaccio: file dritte (rimossa la curvatura parabolica), fasce di prezzo (
- v0.1.10 20 luglio 2026
Aggiunto
- Flusso di rinuncia (UC06): annullo di una registrazione tramite token sicuro, stato
rinunciatoe rilascio del posto assegnato. - Reinvio biglietto: richiesta di reinvio del biglietto via email per registrazioni confermate.
- Gestione minori 4–18: un referente adulto può dichiarare minori al seguito, con finestra di registrazione per categoria e accettazione della responsabilità genitoriale/tutoria.
- Export CSV essenziale dell'elenco registrazioni, coerente con i filtri correnti della vista backoffice (B10).
- Finestre di registrazione per categoria nel form pubblico.
- Suite di test unitari ed e2e per famiglie, finestre, rinuncia, conferma ed export CSV.
Modificato
- Aggiornati i template email
confirmation-requesteticket-deliveryper supportare reinvio e gestione referente/minori. - Rifattorizzate e arricchite le operazioni di dominio in
src/lib/server/registrations/(create,confirm,cancel,extend,renounce,resend-ticket,family,timeout,export-csv). - Interfaccia backoffice Registrazioni aggiornata con drawer partecipante, azioni di rinuncia/reinvio e pulsante di export.
Database
- Aggiunta migrazione
drizzle/20260718205511_minori-dichiarazione. - Aggiunta colonna
minor_responsibility_acceptedalla tabellaregistrationsinsrc/lib/server/db/schema.ts(defaultfalse, NOT NULL); obbligatoria per i referenti che dichiarano minori 4–18.
- Flusso di rinuncia (UC06): annullo di una registrazione tramite token sicuro, stato
- v0.1.9 17 luglio 2026
Modificato
- Routine patch release; no functional changes.
- v0.1.8 17 luglio 2026
Aggiunto
- Favicon e apple-touch-icon del portale prese dal sito Rainbow Awards (
https://www.rainbowawards.it/wp-content/uploads/2023/11/favicon-300x300.png); asset servito dastatic/favicon.pnge link insrc/app.html.
Modificato
- Aggiornamento dipendenze di sviluppo e runtime (Biome 2.5.4, SvelteKit 2.69.3, Svelte 5.56.6, TypeScript 6.0.3, TailwindCSS 4.3.3, Storybook 10.5.2, ecc.) con relativo aggiornamento di
pnpm-lock.yamlepnpm-workspace.yaml.
Corretto
- Migrazione di
biome.jsonallo schema 2.5.4 per allinearsi alla versione installata di Biome.
- Favicon e apple-touch-icon del portale prese dal sito Rainbow Awards (
- v0.1.7 16 luglio 2026
Aggiunto
- Vista Gallerie (wayfinder ticket 09): nuovo
GalleryCol.sveltecon testata occupati/capienza, heat-grid decorativa, fill bar, lista assegnati e bottone di spostamento manuale G1↔G2; nuova operazione di dominiomoveToGalleryinsrc/lib/server/assignments/galleries.ts(rilascia + riassegna nella stessa transazione, capienza calcolata escludendo l'assegnazione attiva della registrazione stessa). - Layout a subtab Panoramica/Platea/Gallerie per la schermata di Assegnazione (wayfinder ticket 08):
SubTabs.svelte(tab-link deep-linkabili?tab=, roving tabindex) eAssignmentOverview.svelte(saturazione aree + CTA Platea/Gallerie). - Indicatore di versione/build (tag di release,
DEV, o short SHA) nel footer della sidebar del backoffice e nell'hub di sviluppo, tramiteresolveBuildLabele il componenteBuildLabel.
Modificato
- Rimosso
AssignedList(+ story): gli assegnati si vedono ora su mappa/gallerie/drawer. - e2e di Assegnazione serializzati (
workers: 1) per evitare contese sul batch gallerie globale.
- Vista Gallerie (wayfinder ticket 09): nuovo
- v0.1.6 16 luglio 2026
Corretto
vite.config.ts: il pluginchangelog-rawgestisce ora l'assenza diCHANGELOG.mdrestituendo un contenuto di fallback, evitando errori in fase di build.- Spostata la direttiva
/// <reference path="./src/virtual-modules.d.ts" />all'inizio divite.config.tsper rispettare la posizione corretta delle direttive del compilatore.
Modificato
vite.config.ts: reso il percorso diCHANGELOG.mduna costante top-level nel file di configurazione.
- v0.1.5 16 luglio 2026
Aggiunto
- Virtual module
virtual:changelogper servireCHANGELOG.mdcome stringa raw a build time, evitando che mdsvex lo tratti come componente Svelte nella route/changelog. - Dichiarazione di tipo
src/virtual-modules.d.tsper il modulovirtual:changelog.
Modificato
src/routes/changelog/+page.server.tsimporta oravirtual:changeloginvece diCHANGELOG.md?raw.vite.config.ts: registrato il pluginchangelogRawPluginnell'array dei plugin Vite.
- Virtual module
- v0.1.4 15 luglio 2026
Aggiunto
- Home/landing page (
/) con logo, wordmark, fascia arcobaleno e hub di navigazione verso le sezioni pubbliche, di backoffice e di sistema (strumento temporaneo di sviluppo). - Pagina Changelog (
/changelog) che rendeCHANGELOG.mdcome timeline delle versioni, coerente con il design system.
Modificato
- Pagina Account (
/account) ridisegnata: intestazione profilo con avatar e iniziali, ruoli come chip con descrizione dei permessi, scheda dettagli (nome, email, ID applicativo, identità IdP) e scorciatoia al backoffice.
- Home/landing page (
- v0.1.3 15 luglio 2026
Aggiunto
- Added Kubernetes manifests for dev deployment under
k8s/baseandk8s/overlays/dev(Deployment, Service, Secret, Kustomization, Istio Gateway/VirtualService, cert-manager Certificate, namespace transformer).
Modificato
- Updated dev overlay database URL to
postgres://rainbow_awards_dev_crud:1vW4bM8O5wylIBL.xfPWTxSr@192.168.128.50:5432/rainbow-awards-dev. - Aligned dev overlay OIDC configuration with local development settings (issuer
https://auth.iad2.click/realms/rainbow-awards, clientIdbackstage).
- Added Kubernetes manifests for dev deployment under
- v0.1.1 13 luglio 2026
Modificato
- Dockerfile: set
LOADER_THROW=falseduring build to preventyamlLoadererrors when.app.yamlis absent. - Bumped project version from
0.1.0to0.1.1inpackage.json.
- Dockerfile: set
- v0.1.0 13 luglio 2026
Aggiunto
- Added release automation skill at
.agents/skills/release/SKILL.mdfor local MINOR bump, checks, build, commit, and tag preparation.
Modificato
- Bumped project version from
0.0.0to0.1.0inpackage.json.
- Added release automation skill at