Codici ATECO di versioni precedenti con correspondingNewAteco FK verso atecoCodes(code). Usata in import aziende per convertire codici legacy nel codice corrente.
job.companiesRisks
Rischi per azienda
job.jobsRisks
Rischi per mansione
job.workersRisks
Rischi per lavoratore (override/esclusione)
job.workerEffectiveRisksCache
Cache materializzata di vw_workerEffectiveRisks, indice clustered su (workerId, riskId). Popolata da sp_refreshEffectiveRisksForScope; Γ¨ la sorgente letta da edu.vw_workerTrainingStatus, non la vista
L'autoritΓ sul cascade rischi: unione dei tre rami (mansione / azienda / personale) con spareggio per origine worker > job > company e gli esclusi restituiti a parte con origin = 'excluded'. Vedi logica applicativa
job.vw_workersData
Vista dati lavoratori, esposta come CRUD generato /job/vw_workersData
job.vw_jobsData
Vista dati mansioni, esposta come CRUD generato /job/vw_jobsData
job.vw_workerComplianceSummary
Rollup per-lavoratore di compliance formativa: worstStatus (expired > missing > expiring > insufficient > ok), conteggi per status β incluso insufficientCount β e minDaysRemaining. β οΈ okCount conta solo status = 'ok' AND hoursShortfall = 0. Filtra solo lavoratori con endDateWork IS NULL. Aggrega edu.vw_workerTrainingStatus per workerId. PK virtuale = workerId. Esposta come CRUD read-only WorkerComplianceSummary con FK manuali su workerId/companyId/roleId/departmentId.
Campi: notes, onlyForExposedJobs (BIT NOT NULL, default 0) β se 1 il rischio
Γ¨ d'attivitΓ : resta condizione per le mansioni con jobsRisks.onlyIfCompanyHasRisk = 1
ma non si propaga dal ramo company alle mansioni con jobs.inheritsCompanyRisks = 1.
A 0 Γ¨ un rischio diffuso e si comporta come sempre.
Campo: onlyIfCompanyHasRisk (BIT NOT NULL, default 0) β se 1, il rischio entra
nei rischi efficaci del lavoratore solo quando job.companiesRisks contiene la coppia
(azienda del lavoratore, stesso rischio). Applicato nel ramo job di
job.vw_workerEffectiveRisks, quindi ortogonale a jobs.inheritsCompanyRisks,
che governa il solo ramo company.
workers.riskLevelId materializzato β nessun test di
regressione. I test ci sono, in
TrainingHub.UnitTests/Services/QueryModifiers/:
WorkersQueryModifierTests.cs:60, JobsQueryModifierTests.cs:30,
JobsRisksQueryModifierTests.cs:23-41,
CompaniesQueryModifierTests.cs:24, piΓΉ
WorkersJobsQueryModifierTests.cs e
CompaniesRisksQueryModifierTests.cs: asseriscono lo scope del
ricalcolo.
atecoCodes.code come natural key. Performance OK, ma
modifiche al codice (es. rinomina ATECO) sono bloccate da FK. Se
serve rename, procedere via nuovo codice + migrazione.
Mansioni globali senza companyId. Condivisione fra aziende
crea accoppiamento: modifica a una mansione impatta tutti i clienti
che la usano. Valutare pattern mansione template + istanza.
Indici mancanti su FK chiave. Ci sono tutti:
IX_workerJobHistory_workerId (workerJobHistory.sql:23),
UQ_workersJobs_workerId_jobId β che copre workerId come colonna
guida β e IX_workersJobs_jobId (workersJobs.sql:9,12);
workersRisks ha la PK composita con workerId in testa.
Constraint check su riskLevelId.riskLevel ha PK INT
(1, 2, 3) ma qualsiasi intero Γ¨ accettato in FK. Valori fuori
range (es. 5) resterebbero orfani se non c'Γ¨ il record. Solo
integrity FK li blocca, ma non semantica.
workersRisks.excluded = 1 + riskLevelId != NULL. Stato
semanticamente ambiguo: lavoratore escluso con livello impostato?
Aggiungere check o validazione.