Checklist di avanzamento
Aggiornare questa pagina nello stesso commit/PR con cui un'attività viene completata. Una macro-voce si considera chiusa solo quando sono soddisfatti codice, test, migrazione e documentazione.
Decisioni e baseline
- Approvare requisiti, glossario e confini MVP/Release 1 con il committente
- Fotografare API, schema, dataset e comportamento AS-IS
- Creare regression suite del POC
- Approvare ADR-001 tenant/source of truth — approvata il 15 agosto 2026
- Approvare matrice ruoli e permessi
- Approvare ADR-002 confine del dominio — approvata il 15 agosto 2026
- Approvare ADR cursori/consegna/correzioni
- Approvare ADR forecasting e funzione obiettivo
- Approvare ADR adapter import/export
P0 — Organizzazione e sicurezza
- Identificare Italbiotec come tenant destinatario dei dati legacy in DEV, TEST e PROD
- Implementare
OrganizationContextderivato server-side - Aggiungere
organization_ida tutte le entità operative - Rendere tenant-aware foreign key, unicità e indici
- Migrare i dati legacy DEV a Consorzio Italbiotec
- Migrare i dati legacy TEST a Consorzio Italbiotec durante il deploy — è la lacuna che tiene aperta la Fase 0: PROD non esiste ancora, TEST sì
- Migrare i dati legacy PROD a Consorzio Italbiotec durante il deploy
- Rendere tenant-aware stato operativo, audit, import, export e job
- Creare profili applicativi Rendicontazione e matrice capability per ruolo
- Collegare profili, utenti e organizzazione con migrazione idempotente
- Applicare i permessi alle API server-side con comportamento deny-by-default
- Aggiungere gestione Team per inviti, profilo amministrativo e ruoli operativi
- Filtrare la navigazione UI in base alle capability effettive — le voci vengono nascoste correttamente. L'atterraggio dopo il login no: chi ha solo
selfarriva ancora su Overview e vede un errore di permessi prima di poter navigare altrove - Applicare scope a list/detail/create/update/delete/search
- Applicare scope a calcoli, report, cache ed eventi
- Rimuovere fallback/query globali
- Scopare per organizzazione il reset amministrativo datahub (niente
TRUNCATEglobale) - Rendere fail-closed il filtro tenant di datahub per i chiamanti tenant-aware
- Rendere lo schema di clean-install e la migrazione 088 eseguibili su un ambiente senza dati legacy
- Testare due utenti della stessa organizzazione
- Testare isolamento e IDOR tra due organizzazioni
- Creare lo script di verifica invarianti tenant (
db/postgres/checks/rendicontazione_tenant_invariants.sql) - Verificare zero record orfani/null/cross-tenant in DEV
- Verificare zero record orfani/null/cross-tenant in TEST
- Verificare zero record orfani/null/cross-tenant in PROD
- Allineare
backbone_identityindb/postgres/init/— verificato il 16 agosto 2026 su un database creato da zero: lo schema nasce completo (24 tabelle). Restano errori all'init su052e053, che riguardano bandi e non questo verticale - Rimuovere le tabelle placeholder
rendicontazione.organizationseorganization_members - Correggere l'attribuzione utente e impedire che l'attore sia scelto dal chiamante
- Scrivere
audit_logsu ogni mutazione, con attore, organizzazione e correlation id - Scopare per organizzazione le chiavi Redis dei job di import
- Eseguire il pilot a due utenti su DEV
- Completare la matrice permessi dei ruoli verticale
- Chiudere il gate P0 dopo la verifica su TEST e PROD
HR e risorse
- Introdurre società/sotto-aziende e storico appartenenza — schema fatto il 17 agosto 2026 con la migrazione
105, trattate come dimensione e non come confine (vedi Stato e decisioni). Il codice del verticale è ancora da scrivere - Creare catalogo sedi tenant-aware — fatto il 16 agosto 2026 con la migrazione
102:cityesort_order, codice unico per organizzazione, chiave composita daemployees. pagina Sedi dedicata (creazione, modifica, eliminazione) con la103che semina Milano - Piazzale Trivulzio 4b e vi assegna chi non aveva sede - Storicizzare la sede di assegnazione del dipendente senza intervalli sovrapposti —
employee_location_historycon vincolo di esclusione, stessa forma dello storico costi - Separare ruoli, macro-livelli e job level — fatto il 16 agosto 2026: vedi Ruolo, macro-livello e job level. Migrazione
100, applicata solo in DEV. Il catalogomacro_levelsè stato seminato dalla112— Dirigente, Quadro, Impiegato — con la regola che li ricava dal job level.job_rolesresta vuoto e senza maschera - Storicizzare reporting line e impedire cicli — migrazione
104:employee_reporting_historycon vincolo di esclusione e un trigger anti-ciclo che valuta la gerarchia alla data, non a oggi. Con l'occasione la logica degli intervalli — costo, sede, riporto — è stata unita inmodules/workforce/periodi.js - Collegare dipendente e account utente — fatto il 16 agosto 2026:
employees.email(unica a livello globale) eemployees.user_id, l'accesso nasce da solo al salvataggio o all'import, capabilityself,GET /me/employee, pagina «I miei dati». Migrazioni096,097,098, applicate solo in DEV - Consolidare storico costo e intervalli non sovrapposti — fatto il 16 agosto 2026: vedi Storico del costo orario. Migrazione
099, applicata solo in DEV. Resta fuori la decorrenza esplicita in maschera, che e' parte del punto UI - Introdurre tipo risorsa employee/freelancer — non è più un punto a sé:
freelanceè un valore della sotto-organizzazione, conis_freelancesul catalogo - Gestire ore contrattuali dei freelancer — il campo esiste già (
planned_monthly_hours); manca la regola nel motore che per un freelance lo tratti come consuntivo e non come peso - Completare tab/UI del mini gestionale HR — parziale: storici visibili e scrivibili a data scelta, gerarchia, mappa, responsabile. Restano quattro campi, due cataloghi, i tab profilo, la foto e l'audit — vedi INCOMPLETO
- [~] Aggiornare import/export dipendenti (import fatto: terza rotta, 73 persone dal file BU con sede, area, società, contratto, orario storicizzato ed email generata. L'export non è stato toccato)
Ferie e disponibilità
La sezione è stata ridimensionata dal committente il 17 agosto 2026: non si costruisce un modulo HR, ma il minimo che serve al forecast. Vedi Fase 2. L'ordine dei punti è quello deciso e va rispettato.
- Creare le due tabelle — saldo annuale e piano mensile — tenant-scoped con chiave composita verso
employees, una riga per dipendente e anno (migrazione108:employee_leave_balances,employee_monthly_leave_plan) - Decrementare i giorni goduti dall'import presenze riconoscendo
8FE(si ricalcola, non si decrementa: vedi Stato e decisioni) - Permettere ad Admin/HR di inserire i giorni previsti per dipendente e anno, distinguendo «nessun dato» da «zero giorni» (sotto-scheda Ferie in Storico; la casella vuota azzera il dato,
0è un valore) - Mostrare ferie prese e residue nella scheda dipendente (un anno per riga; senza previsti il residuo dice «non calcolabile», non zero)
- Self-service per i giorni pianificati, per mese (in «I miei dati»; prime scritture concesse a
self, con mesi futuri e tetto dei giorni imposti dal servizio) - Usare il piano mensile nel monte ore del forecast (solo le ferie pianificate:
ricalcolaTuttitoglie 8 ore per giorno pianificato, per persona e per mese. Il residuo non collocato resta fuori, e dipende dal modello di capacità della Fase 6)
Rimandati e non in Fase 2: policy, carry-over e calendari; stati e workflow di approvazione; viste manager; i permessi <n>PR; part-time e cessazioni infra-annuali. E la riserva per ferie non pianificate, che non è un problema di ferie ma dipende dal modello di capacità dipendente/progetti, ancora da sviluppare.
Enti, progetti e costi
- Completare anagrafica enti finanziatori (pagina Enti nel menu, con scheda per ente e tariffe storicizzate per fascia)
- Storicizzare tariffe ente per macro-livello (migrazione
114:funding_body_rates, quinta applicazione della forma degli intervalli) - Impedire intervalli tariffa sovrapposti (vincolo di esclusione su ente + macro-livello + intervallo: «la tariffa valida a quella data» ha una sola risposta)
- Rendere esplicita strategia costo reale/standard (
uses_standard_costesisteva già; ora è il codice a onorarla davvero) - Applicare la tariffa valida alla data (fascia → ente → tariffa del mese, in entrambi i motori; se manca la riga non nasce e un avviso dice quale delle tre cose manca)
- Aggiungere limite ore per risorsa default 1720 (migrazione
113, colonnaNOT NULLsul progetto) - Gestire override del limite per progetto (campo in maschera progetto, applicato da entrambi i motori: duro nel forecast, con avviso nel consuntivo)
- Aggiungere sede opzionale al progetto (migrazione
115, tendina con «nessuna sede» come valore, e vincolo applicato dai due motori) - Normalizzare la città e validare la compatibilità sede progetto-risorsa (confronto per città e sulla sede corrente, confermato dal committente il 18 agosto 2026: la sede storica servirà al ricalcolo del passato, non a questo vincolo)
- Gestire cambi sede senza lasciare associazioni incompatibili (salvando una sede diversa, la scheda dipendente elenca i progetti su cui quella persona non potrebbe più lavorare — avvisa, non blocca: il trasferimento è un fatto, non un errore)
- Validare associazioni e tariffe mancanti (
modules/projects/qualitaDati.js: la tariffa manca solo se qualcuno la userebbe davvero, e un progetto a costo standard senza ente è un errore, non un avviso) - Aggiungere UI e report qualità dati (
GET /rendicontazione-service/qualita-dati+ banner: sulla scheda progetto solo i suoi, su Overview e Forecast tutti — e nessun banner quando non c'è niente da dire) - Centralizzare avvisi ed errori in un catalogo unico (
modules/qualita/catalogo.js: 29 codici con livello, entità e rimedio; loswitchche interpretava gli avvisi nel frontend è sparito, e un codice fuori catalogo fa falliretest/catalogo.test.js)
Import/export
- Definire modelli canonici dipendenti, progetti, ferie e consuntivi (
modules/data-exchange/modelliCanonici.js— esistevano già senza nome dentroimportPayloads; il quarto, le assenze, mancava davvero) - Definire interfacce e registry adapter (
registroAdapter.js: cinque cose e non una di più, confidenza 0–1 invece di un booleano, e un adapter incompleto si rifiuta alla registrazione) - [~] Incapsulare formati attuali come adapter v1 (i tre lettori esistono —
progettiSheet,tariffariSheet,personaleSheet,tariffeRealiSheet— ma non passano ancora dal registro: le rotte li chiamano dritti. Il registro è scritto e provato, non collegato) - Implementare nuovi formati come adapter separati (foglio PROGETTI e foglio TARIFFARI del file nuovo, più l'anagrafica del file BU come terza rotta)
- Versionare detection, mapping e contratti
- [~] Garantire staging, diff, approvazione e rollback (progetti, tariffari ed enti passano dallo staging e compaiono nel diff; l'anagrafica personale no — è un import diretto, e ciò che crea si cancella dalle schede)
- Gestire più file di rendicontazione senza sovrascrivere (modalità
ADD_ONLY: non cancella, non sovrascrive, ed elenca campo per campo ciò che non ha importato. Le altre tre presuppongono un file solo — Sync e Revisione proporrebbero di cancellare i progetti degli altri file) - Garantire idempotenza tenant-aware (reimportare aggiorna invece di raddoppiare: dipendenti, cataloghi, enti, tariffari, intervalli di costo e legami ente-tariffario hanno tutti un test che lo fissa)
- Creare fixture anonimizzate e contract test
Consuntivo e consegna
- Implementare
actual_through_monthper organizzazione (esisteva già comeconsolidated_until_month, mosso dall'import presenze; dal 18 agosto 2026 l'import rifiuta i mesi fuori sequenza e il forecast riparte dal mese successivo al cursore invece che da oggi) - Implementare
delivered_through_month— per progetto, non per organizzazione (migrazione117: ogni progetto ha il suo cursore di consegna, deciso dal committente il 18 agosto 2026; sostituiscefreeze_config, che era un piano e non un fatto) - Implementare comando/permesso di consegna (
PUT /projects/:id/consegnacon storico inproject_delivery_events; il permesso è quello di modifica del progetto, scelta del committente il 18 agosto 2026) - Creare snapshot/hash dei periodi consegnati
- Bloccare modifiche a periodi consegnati in DB/API/UI (tre porte chiuse il 18 agosto 2026: il ricalcolo globale di un mese passato conserva i progetti già consegnati invece di rifiutare il mese, l'annullamento di un import consegnato è rifiutato, e le associazioni non si modificano nella parte consegnata — prolungarle nel futuro resta permesso)
- Implementare dirty range per correzioni retroattive
- [~] Ricalcolare tutti i periodi/progetti impattati (parziale: esiste il ricalcolo manuale per progetto dal cursore di consegna al mese consuntivato, con gli altri progetti riportati identici. Manca il dirty range automatico: nessuna modifica scatena il ricalcolo da sola)
- Conservare versioni, motivazione e confronto prima/dopo
- Rigenerare report aperti senza alterare snapshot consegnati
Forecasting
- Formalizzare domanda, capacità, priorità e copertura
- Implementare vincoli periodo/associazione/rapporto
- Integrare nel forecast il vincolo di compatibilità città progetto-risorsa (regola dura nel forecast, avviso nel consuntivo; dal 18 agosto 2026 il consuntivo usa la sede storica per giornata, non quella corrente)
- Implementare vincoli capacità e no over-allocation
- Implementare limite cumulativo risorsa-progetto
- Integrare costi reali e standard temporali
- Integrare ferie e calendario
- Implementare strategia freelancer
- Calcolare globalmente tutti i progetti dell'organizzazione
- Collegare tutti i trigger tramite outbox/job idempotenti
- Coalescere eventi e calcolare il minimo dirty range
- Versionare input, algoritmo e risultati
- Mostrare infeasibilità, ore scoperte e spiegazioni
- Validare golden dataset e UAT committente
MVP avanzato
- Completare flusso HR → progetto → forecast
- Completare flusso consuntivo → correzione → consegna
- Validare report dipendente e progetto
- Eseguire UAT end-to-end con il committente
- Risolvere finding bloccanti UAT
- Ottenere sign-off MVP avanzato
Uso LLM
- Approvare casi d'uso e funzioni esplicitamente escluse
- Definire tool tenant-aware e relativi JSON Schema
- Integrare esclusivamente tramite assistant orchestrator e
llm-gateway - Implementare “Spiega il forecast” con fonti strutturate
- Implementare spiegazione delle anomalie dati
- Implementare proposta mapping import con approvazione umana
- Creare dataset di evaluation anonimizzato e versionato
- Misurare fedeltà, accuratezza, latenza e costo
- Verificare isolamento tra organizzazioni e rispetto permessi
- Verificare assenza di modifiche autonome e numeri inventati
- Definire logging, retention, redazione e fallback
- Validare con UAT del committente
Release 1
- Eseguire performance/load/concurrency test
- Definire e misurare SLO
- Creare dashboard, alert e tracing
- Provare retry, idempotenza e recovery job
- Testare backup e restore
- Completare security/privacy review
- Definire retention e audit export
- Automatizzare onboarding nuova organizzazione
- Preparare feature flag, canary e rollback
- Completare manuali utente, amministrazione e supporto
- Eseguire go-live rehearsal
- Ottenere sign-off Release 1