Tutorial — aggiungere un campo a edu.courses
Esempio edu-specific del pattern generale di estensione CRUD. Per i
passi comuni (sync DB, MCP generator, rigenerazione) vedi
Aggiungere un campo su inv.invoices.
Questa pagina mostra le specificità del dominio edu.
🎯 Cosa fa
Esempio: aggiungere un campo prerequisiteText (descrizione testuale
dei prerequisiti del corso) alla tabella edu.courses.
⚠️ Prerequisiti
Stessi del tutorial inv/reg:
- Ambiente sviluppo con
TrainingHub.Database - DB locale sync
- MCP
3sd-generator - Branch dedicato
👣 Passi
1. Modifica edu.courses
File: TrainingHub.Database/edu/Tables/courses.sql
CREATE TABLE [edu].[courses] (
[id] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[trainingVariantId] UNIQUEIDENTIFIER NOT NULL,
[organizerSlug] NVARCHAR (128) NOT NULL,
[code] NVARCHAR (128) NOT NULL,
[label] NVARCHAR (512) NOT NULL,
[description] NVARCHAR (MAX) NULL,
[prerequisiteText] NVARCHAR (MAX) NULL,
-- ... altri campi esistenti ...
);
GO
EXECUTE sp_addextendedproperty @name = N'MS_Description',
@value = N'Descrizione testuale dei prerequisiti di partecipazione al corso',
@level0type = N'SCHEMA', @level0name = N'edu',
@level1type = N'TABLE', @level1name = N'courses',
@level2type = N'COLUMN', @level2name = N'prerequisiteText';
GO
Considerazioni edu-specifiche:
- Posiziona il nuovo campo dopo
descriptionper coerenza visiva nel form. - Non violare le CHECK constraint esistenti (
CK_courses_maxPeople,CK_courses_extraInstructorThreshold).
2. Sincronizza il DB e rigenera
Uguale a inv/reg: sqlpackage + mcp__3sd-generator__generator_run per
courses.
3. conf.json — considerazioni edu
File: TrainingHub.BackOffice/Components/CRUD/edu/_conf/courses.dxgrid.conf.json
Per un campo di testo lungo come prerequisiteText:
{
"Columns": {
"prerequisiteText": {
"Visible": false,
"FormInsertVisibility": "editable",
"FormUpdateVisibility": "editable",
"EditorType": "TextArea"
}
},
"FormOrder": [
// ... altri campi ...
"description",
"prerequisiteText",
"maxPeople"
]
}
Note:
- EditorType
TextAreaper testo multilinea (se supportato dalla generazione; altrimenti sarà singolo textbox). - Nascondi in grid di default (campo lungo).
4. Impatto sulle viste analitiche
Il dominio edu ha viste cross-dominio custom (es. ActiveWorker.razor)
che caricano elenchi corsi. Un nuovo campo non è automaticamente
incluso: se rilevante, aggiornare esplicitamente i code-behind di
queste viste.
5. Impatto sulla vista calendario
Se il campo va mostrato nel pannello dettaglio del calendario,
modifica Pages/AppointmentsCalendar/AppointmentDetailPanel.razor
(rendering laterale) o eventualmente la query in
AppointmentsCalendarService.GetAppointmentsAsync /
GetSessionContextAsync se il campo serve a livello di scheda
sessione. La vista è scritta a mano, non CRUD-generata.
6. Impatto su ITrainingExpirationService
Se il campo influenza la compliance (es. un prerequisito impatta
expiring vs ok), aggiornare la logica del service. Nel caso di
prerequisiteText puramente descrittivo, nessun impatto.
7. Build, test, commit
dotnet build TrainingHub.sln
dotnet test TrainingHub.Tests
git add TrainingHub.Database/edu/Tables/courses.sql
git commit -m "feat(db): add prerequisiteText to edu.courses"
git add TrainingHub.BackOffice/Components/CRUD/edu/_conf/courses.dxgrid.conf.json
git commit -m "feat(edu): show prerequisiteText in course form"
git add TrainingHub.BackOffice/Components/CRUD/edu/Course.razor \
TrainingHub.BackOffice/Components/CRUD/edu/Course.razor.tt.cs \
TrainingHub.BackOffice/Components/CRUD/edu/Forms/CourseForm.razor \
TrainingHub.BackOffice/Components/CRUD/edu/Forms/CourseForm.razor.tt.cs
git commit -m "regen edu.courses"
⚡ Casi particolari edu
- Campo che richiede cascade variante normativa. Se il nuovo
campo deve essere pre-popolato al cambio di
trainingVariantId, estendere il metodo cascade inCourseForm.razor.cs. - Campo calcolato da altri (es. durata totale). I computed column
(come
teachers.label = firstName + ' ' + lastName) sono sintassi SQL specifica. Seguire pattern esistente: dichiarareAS (expression)nella CREATE TABLE. - Campo con impatto su
workerCompletionsCache. Se il campo cambia la logica di calcolo compliance (es. influenza scadenza), serve refresh del cache dopo update. Aggiungere hook in un QueryModifier dedicato. - Campo visualizzato in vista calendario. Il pannello
Pages/AppointmentsCalendar/AppointmentDetailPanel.razore le query del data providerAppointmentsCalendarServicevanno aggiornati esplicitamente. - Nuova lookup table. Se il campo è FK verso una nuova tabella, crea anche il CRUD completo per la nuova entità (genera in cascata il combobox nel form courses).
⚠️ Domande aperte
- Rigenerazione parziale. Il generatore rigenera tutta
l'entità: se il form ha markup custom inline nel
conf.json(rare in edu), verificare che non si rompa. - Impatto su 38 tabelle. Aggiungere un campo a una tabella
centrale (es.
courses) può richiedere aggiornamenti in più punti: form, viste analitiche, cache. Checklist standard da stilare. - Testing post-regen. Nessun test UI automatico: modifiche come questa vanno validate manualmente.
🔗 Vedi anche
- Aggiungere un campo
inv— tutorial base - Aggiungere un campo
reg— esempio sucompanies - Panoramica dominio
- Schema DB
- Componenti UI
- Logica applicativa