Dominio reg β Panoramica sviluppatore
π― Cosa faβ
Il dominio reg (registry) contiene l'anagrafica aziende clienti e
fornitori: Γ¨ base dati referenziata da quasi tutti gli altri domini
(inv, edu, job, iso, bi). Questa pagina copre tutte le 15
tabelle del dominio raggruppate per area funzionale.
πΊοΈ Mappa moduliβ
Database β TrainingHub.Database/reg/β
Core anagrafica (4):
| File | Ruolo |
|---|---|
Tables/companies.sql | Anagrafica aziende (cliente / fornitore) |
Tables/companyContacts.sql | Canali di contatto azienda (email, telefono, PEC) |
Tables/companyLocations.sql | Sedi del cliente con label descrittiva e locationTag di classificazione |
Tables/headquarters.sql | Sedi TrainingHub / ente formatore β indipendente dalle aziende clienti |
Classificazione aziendale (3):
| File | Ruolo |
|---|---|
Tables/companySubcategories.sql | Sottocategorie custom per raggruppare aziende |
Tables/companyTags.sql | N:N azienda β tag di classificazione |
Tables/companiesPreferences.sql | Preferenze configurabili per azienda (flag booleani via tag) |
Ruoli esterni (4):
| File | Ruolo |
|---|---|
Tables/externalRspps.sql | Anagrafica RSPP esterni (consulenti compliance) |
Tables/companiesExternalRspps.sql | Incarichi azienda β RSPP con periodo validitΓ |
Tables/territorialReferents.sql | Anagrafica RLS territoriali β Rappresentanti dei Lavoratori per la Sicurezza designati a livello territoriale (art. 48 D.Lgs. 81/08) |
Tables/companiesTerritorialReferents.sql | Incarichi azienda β RLS territoriale con periodo validitΓ |
Anagrafiche lookup (4):
| File | Ruolo |
|---|---|
Tables/organizers.sql | Enti organizzatori di corsi |
Tables/ccnl.sql | Contratti Collettivi Nazionali di Lavoro |
Tables/legalNatures.sql | Forme societarie (SRL, SPA, ditta individuale, ecc.) |
Tables/academicQualifications.sql | Titoli di studio |
Service layer β TrainingHub.BackOffice/Services/β
| File | Ruolo |
|---|---|
QueryModifiers/reg/CompaniesQueryModifier.cs | Hook su CRUD companies: dopo update cascade refresh riskLevel sui workers dell'azienda. Su UpdateSingle setta imported = false. |
Non esiste un IRegistryService dedicato: la logica di dominio Γ¨
distribuita fra:
- Il
QueryModifier(hook pre/post su CRUD standard) - I code-behind custom
.razor.csdei singoli CRUD
UI CRUD β TrainingHub.BackOffice/Components/CRUD/reg/β
15 entitΓ CRUD auto-generate. Pattern identico al dominio inv
(vedi componenti UI inv per il pattern
generale). Core di questa spec:
Company(con code-behind custom ricco di inject/servizi correlati)CompanyContactCompanyLocation(sede del cliente, classificata vialocationTag)Headquarter
Configurazione CRUD β _conf/*.dxgrid.conf.jsonβ
Un file JSON per entitΓ (15 totali). I nomi seguono la convenzione
<nomePlural>.dxgrid.conf.json (es. companies.dxgrid.conf.json).
π§ API pubblicaβ
CompaniesQueryModifierβ
public class CompaniesQueryModifier(ISimpleCRUDService simpleCRUD)
: IQueryModifier<DataLayer.reg.company>
{
public ValueTask PreExecutionQuery(QueryModifierArgs<company> args);
public ValueTask PostExecutionQuery(QueryModifierArgs<company> args, object? result);
public ValueTask ModifyEntity(QueryModifierArgs<company> args);
public ValueTask ModifyQuery(QueryModifierArgs<company> args);
}
Hook registrati in Program.cs. Il pattern IQueryModifier<T> Γ¨ di
Brighela.SimpleCRUD: consente di innestare logica pre/post sulle
operazioni CRUD standard senza override del service.
Servizi iniettati in Company.razor.csβ
[Inject] private IRiskInheritanceService RiskService { get; set; }
[Inject] private ITrainingExpirationService ExpirationService { get; set; }
[Inject] private ISimpleCRUDService SimpleCRUD { get; set; }
Quando l'utente seleziona un'azienda nella grid, il code-behind carica in parallelo: rischi aziendali, dipartimenti, stats di compliance (dettaglio in Logica applicativa).
π§© Pattern chiaveβ
Cascade riskLevel su workersβ
Quando si aggiorna un'azienda, CompaniesQueryModifier.PostExecutionQuery
invoca worker.UpdateRiskLevel(companyId) per ricalcolare il livello
di rischio dei lavoratori collegati. Questo avviene automaticamente
su ogni Update via hook del QueryModifier, senza intervento del
code-behind UI.
Il comportamento garantisce che il cambio di livello di rischio aziendale (forzato manualmente o conseguente a cambio ATECO) si propaghi ai lavoratori senza ricalcoli espliciti.
imported = false su updateβ
Il flag imported marca aziende caricate da import massivo. Alla prima
modifica manuale (UpdateSingle), il QueryModifier.PreExecutionQuery
lo resetta a false: l'azienda perde lo status di "solo importata".
Nessun service dedicatoβ
Il dominio reg non ha un IRegistryService centrale: la logica
applicativa vive in:
CompaniesQueryModifier(hook DB).razor.cscustom (per logica UI di caricamento dettagli, validazioni form)- Servizi cross-dominio invocati dai code-behind (
IRiskInheritanceService,ITrainingExpirationService)
Se la logica cresce, pattern da considerare: introdurre
ICompanyService sul modello di IInvoiceService.
π¦ Dipendenzeβ
Runtime:
Brighela.SimpleCRUDβ CRUD base +IQueryModifier<T>Oss.Filtersβ filtri su gridTabiot.Blazor.*β componenti UI (wizard, grid, popup, combo)DevExpress.Blazorβ controlli UI
Cross-dominio (dipendenze di Company.razor.cs):
IRiskInheritanceService(dominiojob)ITrainingExpirationService(dominioedu)
DB cross-dominio (FK in uscita da reg):
reg.companies.atecoCodeβjob.atecoCodes(code)reg.companies.riskLevelIdβjob.riskLevel(id)reg.companies.legalNatureCodeβreg.legalNatures(code)(fuori scope)reg.companies.ccnlIdβreg.ccnl(id)(fuori scope)reg.companies.companySubcategoryIdβreg.companySubcategories(id)(fuori scope)
π File chiaveβ
Services/QueryModifiers/reg/CompaniesQueryModifier.csComponents/CRUD/reg/Company.razor.csβ code-behind principaleComponents/CRUD/reg/Forms/CompanyForm.razor(+.razor.cs) β form con validazione VIES e propagazione ATECO β riskLevelDatabase/reg/Tables/*.sql(16)Database/reg/_conf/*.dxgrid.conf.json(16)
β οΈ Domande aperte / debito tecnicoβ
- Nessun
ICompanyService. La logica Γ¨ distribuita fra QueryModifier e code-behind. Se cresce β e conregche Γ¨ base di tutto β valutare estrazione in un service di dominio per testabilitΓ . -
imported/originalNameflag di migrazione. Entrambi contrassegnati nel DB come "da rimuovere una volta completate le importazioni iniziali". Roadmap di pulizia da concordare. Oggi i flag sono nascosti in UI. -
CompaniesQueryModifier.UpdateRiskLevelsenza entity. Nel caso diUpdateWheresenza entity, il modifier chiamaworker.UpdateRiskLevel(simpleCRUD)senza filtro per azienda specifica: ricalcola TUTTI i workers. Performance da monitorare su dataset grandi. -
headquartersglobale senza proprietario. La tabella non ha FK versoreg.companiesnΓ© verso un altro "tenant": Γ¨ effettivamente singleton del formatore. Se TrainingHub diventa multi-tenant con piΓΉ enti formatori, la tabella va estesa.
π Vedi ancheβ
- Schema DB β ER diagram, dettaglio tabelle core, tabelle fuori scope
- Componenti UI β struttura CRUD reg
- Logica applicativa β QueryModifier + hook custom
- Aggiungere un campo β tutorial su
companies - Guida utente: Panoramica aziende (docs-site-user)
- Dominio
inv: componenti UI per pattern CRUD condivisi