Struttura Dati
In questa sezione è presente la struttura dati del database per il modulo Shared - Anagrafiche. Sono presenti le entità principali e le loro relazioni.
🗂️ Diagrammi ER
Utenti, Profili e Ruoli
Il sistema utilizza un'architettura basata su Profiles (profili) separati dagli utenti. Gli Users contengono solo i dati di autenticazione (email, password, telefono), mentre i Profiles contengono tutti i dati anagrafici, professionali, ruoli e contesto lavorativo. Un utente può avere più profili, ma uno è sempre marcato come is_default.
Il sistema di gestione ruoli utilizza Spatie Laravel-Permission. I ruoli sono assegnati ai Profiles, non direttamente agli Users. Ogni profile ha esattamente un ruolo.
Il sistema utilizza un modello a profili separati:
- Users: Contengono solo dati di autenticazione (email, password, telefono). Un utente può esistere senza profili (utente inattivo).
- Profiles: Contengono tutti i dati anagrafici, professionali, ruoli e contesto lavorativo. Un profile può esistere senza user (
user_id = NULL) per rappresentare lavoratori senza accesso alla piattaforma. - Invoice Data: Dati fiscali e bancari separati in una tabella polimorfica. Può essere associata a Profile o Company.
- Referrals: Codici referral polimorfici. Possono riferirsi a Profile (consulenti) o PartnerBranch.
Relazioni chiave:
- Un User può avere più Profiles (es: stesso utente con ruoli diversi in aziende diverse)
- Un Profile ha esattamente un ruolo (Spatie Laravel-Permission)
- Un Profile può avere un InvoiceData (dati fiscali/bancari)
- Un Profile può avere un Referral (codice referral per consulenti)
- Il campo
is_defaultidentifica il profilo principale dell'utente
Aziende (Companies)
Le aziende possono avere uno o più tipi (company, supplier, designer) gestiti tramite la tabella relazionale company_has_types. Inoltre supportano relazioni condizionali basate sul tipo e sul ruolo nei subcontratti.
Una company deve avere almeno un tipo. La relazione è gestita tramite la tabella company_has_types con un vincolo unique che previene duplicati. I tipi vengono sempre caricati automaticamente (eager loading) per evitare N+1 query.
Le companies hanno una relazione 1:N con profiles (non più direttamente con users). I profili associati a una company rappresentano i lavoratori/membri dell'azienda. Il profilo con is_main_manager = true è il manager principale dell'azienda.
I dati fiscali e bancari della company sono gestiti tramite la relazione polimorfica invoice_data.
La tabella company_subcontracts gestisce le relazioni tra aziende appaltatrici e subappaltatrici. Ogni record rappresenta un invito da parte di un'azienda principale (company_id) a una azienda subappaltatrice (subcontractor_company_id).
Vincoli e regole:
- Non è possibile un'auto-riferimento (check constraint previene
company_id = subcontractor_company_id) - La company subappaltatrice deve essere di tipo
company(validazione applicata) - Lo status può essere:
pending,accepted, orejected - Il timestamp
status_changed_atviene aggiornato quando cambia lo status - Non esiste vincolo unique, permettendo di riproporre un subcontratto dopo un rifiuto
Le relazioni delle company sono condizionali in base al tipo e al ruolo:
Sempre obbligatorie:
- provinces (min: 1): Tutte le company devono avere almeno una provincia di competenza
Condizionali al tipo:
- subcontractRole: Obbligatorio se il tipo include
company - merchandiseCategories (min: 1): Obbligatorio se il tipo include
supplier
Condizionali al subcontractRole:
- assignees (min: 1): Obbligatorio se
subcontractRole=MAINoBOTH - subAssignees (min: 1): Obbligatorio se
subcontractRole=SUBCONTRACTORoBOTH
Distinzione ruoli assignee:
La tabella company_has_assignee_types include un campo role (AssigneeRoleEnum) che permette di distinguere tra:
- Assignee types per il ruolo di appaltatore principale (
MAIN) - Assignee types per il ruolo di subappaltatore (
SUBCONTRACTOR)
Questo permette alla stessa azienda con subcontractRole = BOTH di avere diversi assignee types in base al ruolo che ricopre. Ad esempio:
- Come MAIN: può avere assignee types [1, 2, 3]
- Come SUBCONTRACTOR: può avere assignee types [3, 4, 5]
Notare che l'assignee type 3 è presente in entrambi i ruoli grazie al vincolo unique composto (company_id, assignee_type_id, role).
Province e Paesi
Tabelle di supporto per la gestione di province italiane e paesi internazionali.
Partner e Filiali Partner
Il sistema di gestione dei partner supporta diversi tipi (banche, CAF, CRECO, altro) e una struttura gerarchica di filiali.
La tabella partner_branches supporta una struttura gerarchica tramite il campo parent_branch_id:
- Filiali principali: hanno
parent_branch_id = NULL - Sotto-filiali: hanno
parent_branch_idvalorizzato con l'ID della filiale genitore
Ogni filiale può avere:
- Dati anagrafici (indirizzo, contatti)
- Dati fiscali completi (P.IVA, CF, PEC, SDI, regime fiscale)
- Dati bancari (IBAN, banca, beneficiario)
- Profili associati tramite
profiles.partner_branch_id(consulenti partner) - Un proprio codice referral (referral polimorfico)
I consulenti partner (profili con ruolo partner_manager o partner_operator) sono associati a una filiale e possono avere un proprio codice referral personale.
Il referral code delle filiali è di 4 caratteri, mentre quello del partner principale è di 3 caratteri.