TO-BE funzionale e modello dati
Modello concettuale
Ogni tabella di dominio deve contenere organization_id, direttamente o tramite una relazione la cui coerenza sia garantita dal database. Per le entità usate frequentemente nelle query è preferibile lo scope diretto, con chiavi esterne composite o controlli equivalenti che impediscano relazioni cross-tenant.
Organizzazione, società e risorse
- Organization: tenant applicativo preso da
backbone_auth.organization; è il confine di sicurezza e condivisione. - Legal entity / società: sotto-azienda appartenente al tenant, mostrata in UI e storicizzabile se una risorsa cambia società.
- Sede: anagrafica tenant-owned con almeno codice, nome, città, indirizzo opzionale e stato attivo; è gestita da una pagina dedicata.
- Employee/resource: persona gestita nel verticale, distinta dall'account di login.
- Platform user link: collegamento opzionale e univoco tra dipendente e utente di piattaforma della stessa organizzazione.
- Resource type: almeno
EMPLOYEEeFREELANCER; predisporre il modello a ulteriori tipi senza duplicare l'anagrafica.
Per i collaboratori P. IVA il sistema mantiene la stessa esperienza anagrafica dei dipendenti, ma usa ore contrattuali garantite per progetto e non esegue la normale stima di capacità/consuntivo. Questa eccezione deve essere una strategia di dominio esplicita, non una serie di if sparsi.
Ruoli, livelli e catena di reporting
Separare:
- ruolo professionale: catalogo organizzativo (es. Software Engineer, Project Manager);
- macro-livello: classificazione economica
IMPIEGATO,QUADRO,DIRIGENTE, usata dalle tariffe degli enti; - job level: livello interno configurabile;
- manager: relazione temporale dipendente → manager, con validazione anti-ciclo e stessa organizzazione;
- tipo posizione:
INDIVIDUAL_CONTRIBUTOR,MANAGERo entrambi, derivabile dalle relazioni ma memorizzabile solo se serve una regola di business.
Ruoli, società, sede di assegnazione, manager e rapporto di lavoro devono avere valid_from/valid_to quando incidono su calcoli o audit storici. Lo storico employee_site_assignment non ammette intervalli sovrapposti per lo stesso dipendente.
Ferie e disponibilità
Entità minime:
leave_balance: anno, ore/giorni totali, residuo e unità;leave_plan_entry: intervallo o giornata, quantità, stato (DRAFT,SUBMITTED,APPROVED,REJECTED,CANCELLED), origine e audit;- calendario lavorativo/chiusure aziendali per società o organizzazione;
- policy di conversione giorni → ore basata sull'orario valido della risorsa.
Il dipendente collegato a un account può leggere i propri dati essenziali e gestire il proprio piano ferie. HR/manager possono operare secondo permessi espliciti; l'applicazione non deve inferire privilegi dal solo fatto di essere manager.
Costi e finanziatori
Costo reale
employee_cost_rate deve contenere dipendente, importo orario, valuta, validità e provenienza. Gli intervalli non possono sovrapporsi. current_hourly_cost_eur diventa un dato derivato/cache oppure viene rimosso dopo la migrazione.
Costo standard
funding_body_rate deve contenere:
- ente finanziatore;
- macro-livello;
- tariffa oraria e valuta;
valid_fromevalid_tosenza sovrapposizioni per la stessa combinazione;- riferimento/versione del regolamento e note.
Il progetto seleziona REAL o STANDARD. Nel primo caso si usa la tariffa del dipendente valida nel mese/giorno; nel secondo quella dell'ente e del macro-livello valida nello stesso periodo. Assenza o ambiguità di tariffa blocca il calcolo con errore esplicito.
Progetti e ore
Ogni progetto ha:
- ente finanziatore obbligatorio quando applicabile;
- modalità costo reale/standard;
max_hours_per_resource, default 1720, modificabile;- periodo, budget e stato;
- sede opzionale: se il progetto è legato a una sede, deve riferirsi a una sede attiva della stessa organizzazione;
- associazioni risorsa-progetto temporalmente valide;
- per freelancer, ore contrattuali precise per associazione/periodo.
Vincolo geografico progetto-risorsa
- Un progetto senza sede può ricevere risorse indipendentemente dalla loro sede di assegnazione.
- Se il progetto ha una sede, ogni risorsa associata deve avere, per tutto il periodo dell'associazione, una sede valida nella stessa città della sede del progetto.
- Il confronto usa una città normalizzata e non il testo libero: maiuscole, accenti e spazi non devono produrre falsi mismatch.
- La regola si applica server-side alla creazione/modifica dell'associazione e quando cambiano sede del progetto, sede della risorsa o intervalli temporali.
- Una modifica che renda incompatibile un'associazione esistente viene rifiutata indicando le associazioni coinvolte, oppure passa da un workflow esplicito di riallineamento; non sono ammesse inconsistenze silenziose.
Due cursori temporali
| Cursore | Significato | Effetto |
|---|---|---|
actual_through_month | Ultimo mese con ore effettive caricate/elaborate | Separa consuntivo e forecast; può avanzare o arretrare in una correzione controllata |
delivered_through_month | Ultimo mese formalmente consegnato | Tutto ciò che è precedente o uguale è immutabile salvo procedura amministrativa eccezionale e auditata |
Una correzione retroattiva dopo mese X marca come “dirty” X e tutti i mesi successivi interessati, ricostruisce consuntivo/forecast in ordine cronologico e conserva le versioni precedenti. Se X è consegnato, la richiesta viene rifiutata con conflitto di dominio.
Import/export estendibili
Pipeline target:
Ogni adapter dichiara codice formato, versioni supportate, detection, mapping, validazioni, esempi e capacità import/export. Parser e writer non devono contenere regole di persistenza o forecasting. La pipeline deve essere idempotente tramite hash file + tenant + versione + chiavi naturali.