Skip to main content

Oefencatalogus, niveaus, categorieën, oefeningen en modules

8.1 Intentie

Dit hoofdstuk beschrijft de technische realisatie van de oefencatalogus binnen OefenHub. De oefencatalogus omvat niveaus, centrale categorieën, concrete oefeningen, catalogusmetadata van technische oefenmodules, moduleconfiguratie, statusbeheer, kopiëren, migraties en catalogushistorie.

De oefencatalogus is het domein waarin wordt bepaald welke oefeninhoud bestaat, binnen welke niveau- en categoriecontext deze beschikbaar kan zijn en welke technische module voor een oefening gebruikt wordt. De daadwerkelijke uitvoering van een oefening, voortgang, antwoorden, resultaten en geschiedenis horen niet bij de catalogus, maar bij het practice-domein.

8.2 Afbakening

De oefencatalogus beschrijft technische implementatiekeuzes voor bestaande functionele en datamodelafspraken. Nieuwe functionele eisen ontstaan niet in dit hoofdstuk. Wanneer implementatie aantoont dat een functionele regel ontbreekt of wijzigt, moet de wijziging worden teruggelegd naar Functioneel Ontwerp, Software Requirements Specification, schermdocumentatie, usecases en database-informatie voordat het Technisch Ontwerp daarop wordt aangepast.

OnderwerpHoort in dit hoofdstukHoort niet in dit hoofdstuk
NiveausTechnische opslag, eigenaarschap, zichtbaarheid en collaborator-koppeling vanuit catalogusperspectiefVolledige docent-leerlingautorisatieflow
CategorieënCentrale categorie-identiteit, koppeling aan niveaus, status, historie en migratieLeerlingresultaten per categorie
OefeningenConcrete oefeningmetadata, status, modulekeuze, configuratiepayload en historieRunvoortgang, antwoorden en scoreberekening
ExerciseModulesCatalogusregistratie van beschikbare technische modulesImplementatie van modulelogica zelf
ModuleconfiguratieOpslag, validatie-aanroep en versiecontextDe interne module-DTechnisch Ontwerp als catalogusdatabaseontwerp
MigratiesCategorie- en modulemigratie als beheeractie met auditHerschrijven van historische exercise runs
HistorieCatalogusgerichte historyrecordsCentrale generieke auditmodule

8.3 Belangrijke inputbronnen

De detaildefinities van tabellen, kolommen, relaties en enumwaarden blijven primair onderdeel van de database-informatie. Dit hoofdstuk beschrijft hoe die informatie technisch wordt toegepast in de modulaire monoliet.

8.4 Project, DbContext en schema

De oefencatalogus wordt technisch ondergebracht in het moduleproject OefenHub.Catalog.

Technisch onderdeelKeuze
ProjectOefenHub.Catalog
DbContextCatalogDbContext
Databaseschemacatalog
Schema-naamgevingkleine letters
Tabellen en kolommenPascalCase
MigrationsOefenHub.Catalog/Data/Migrations
EF-configuratiesOefenHub.Catalog/Data/Configurations
Entitiesstandaard internal
Publieke ingangContracts

De regel blijft: één moduleproject heeft maximaal één eigen DbContext en daarmee één primair databaseschema. Voor de catalogus betekent dit dat catalogustabellen in het schema catalog staan. Verwijzingen naar andere modules worden standaard niet als harde cross-module foreign key gemodelleerd, tenzij daarvoor via een expliciet gemotiveerde uitzondering wordt vastgelegd.

8.5 Verantwoordelijkheid van OefenHub.Catalog

OefenHub.Catalog is eigenaar van de technische catalogusbrondata. De module publiceert alleen de contracten die andere modules nodig hebben om cataloguscontext te lezen, catalogusacties uit te voeren of modulemetadata op te vragen.

VerantwoordelijkheidUitwerking
Niveaus beherenAanmaken, wijzigen, zichtbaarheid, eigenaarcontext en collaboratorcontext vanuit catalogusinhoud
Categorieën beherenCentrale categorie-identiteit, koppeling aan niveaus, gebruiksimpact, status en historie
Oefeningen beherenMetadata, status, modulekeuze, configuratiepayload, parentrelatie en history
Modulecatalogus beherenBeschikbare technische modulemetadata en beschikbaarheidsstatus
Configuratie validerenVia OefenHub.ExerciseModuleHost en OefenHub.Modules.Abstractions
Migraties ondersteunenCategorie- en modulemigraties als expliciete beheeracties
Catalogusreaders aanbiedenPublieke query-services voor Web, Practice, Reporting en beheerflows

OefenHub.Catalog is niet eigenaar van leerlingvoortgang, resultaten, live-meekijken, PDF-generatie, relatiebeheer of autorisatiebesluiten. Die domeinen gebruiken catalogusinformatie via publieke contracts en snapshots.

8.6 Relatie met andere modules

Andere moduleRelatie met catalogusTechnische grens
OefenHub.WebToont catalogusoverzichten, configuratieschermen en beheeractiesWeb gebruikt publieke cataloguscontracts, geen CatalogDbContext
OefenHub.AuthorizationBepaalt of gebruiker catalogusobjecten mag zien of muterenAutorisatiebesluit buiten catalogus, objectcontext via contract
OefenHub.RelationshipsLevert relatiecontext voor docent/docent en docent/leerling afhankelijkhedenGeen directe entity access vanuit catalogus
OefenHub.PracticeGebruikt cataloguscontext bij starten van runs en snapshotsSoft links en snapshots, geen directe catalogusentity in runlogica
OefenHub.ExerciseModuleHostValideert en resolved technische modulecontractenCatalogus bewaart modulekeuze en config; host voert modulelogica uit
OefenHub.ReportingLeest historische of actuele cataloguscontext voor exportsVia query-service of snapshotdata, geen directe DbContext-toegang
OefenHub.AdminStart zware beheeracties zoals migraties of centrale correctiesVia cataloguscommandservices
OefenHub.SchedulingKan catalogusgerelateerde jobs triggerenAlleen via publieke catalogusjobcontracts

8.7 Catalogusobjecten op technisch niveau

Dit hoofdstuk dupliceert niet de volledige tabeldefinities uit de database-informatie. Wel wordt vastgelegd welke technische rol de belangrijkste catalogusobjecten hebben.

ObjectTechnische rolEigenaarschap
NiveauOnderwijscontext waar categorieën en oefeningen onder vallenOefenHub.Catalog
CategorieCentrale gedeelde categorie-identiteit met naam, kleur, icoon en statusOefenHub.Catalog
Niveau-categorie-koppelingMaakt categorie beschikbaar binnen een niveaucontextOefenHub.Catalog
OefeningConcrete configureerbare oefening binnen niveau/categoriecontextOefenHub.Catalog
ExerciseModuleCatalogusrecord voor een technische moduleOefenHub.Catalog voor metadata, moduleproject voor uitvoering
ExerciseHistoryHistory voor oefeningmutatiesOefenHub.Catalog
CategoryHistoryHistory voor centrale categorie-identiteitOefenHub.Catalog
CategoryMigrationRegistratie van categorieomzettingOefenHub.Catalog
ExerciseModuleMigrationRegistratie van modulemigratieOefenHub.Catalog, uitvoering via modulehost waar nodig

8.8 Niveaus

Een niveau is een cataloguscontext waarbinnen categorieën en oefeningen beheerd en aangeboden kunnen worden. Technisch hoort het niveau bij het catalog schema. De eigenaar van een niveau wordt vastgelegd als verwijzing naar een gebruiker, maar de gebruikersentiteit zelf blijft eigendom van OefenHub.Identity.

8.8.1 Technische regels voor niveaus

RegelTechnische uitwerking
Niveau heeft een eigenaarOpslag als gebruikers-id soft link naar identitycontext, aangevuld met relevante snapshotvelden waar nodig
Niveau heeft zichtbaarheidWaarde zoals open of privé volgens database-informatie en Functioneel Ontwerp en Software Requirements Specification
Niveau kan collaborators hebbenCollaboratorrecords horen bij catalogus als zij inhoudsbewerking op niveau mogelijk maken
Niveau-autorisatie voor leerlingenNiet bronhoudend in catalogus wanneer het om leerlingtoegang gaat; autorisatie-/relatiecontext bepaalt toegang
Historische runs blijven leesbaarPractice legt runcontext en snapshots vast; cataloguswijzigingen herschrijven runs niet

8.8.2 Eigenaarschap en collaborators

Eigenaarschap en collaboratorrechten worden technisch behandeld als catalogusrechten op onderwijsinhoud. Zij geven geen automatische toegang tot leerlingresultaten, geschiedenis of live-meekijken. Die grenzen worden in autorisatie-, relatie- en practiceflows opnieuw server-side gecontroleerd.

Voorbeeld:

Docent A is eigenaar van niveau Groep 6 Rekenen.
Docent B is actieve collaborator op dat niveau.
Docent B mag oefeningen binnen dat niveau aanpassen.
Docent B ziet daardoor niet automatisch resultaten van leerlingen van docent A.

De catalogusmodule mag daarom wel vastleggen wie eigenaar/collaborator is voor inhoudsbeheer, maar mag deze relatie niet hergebruiken als resultaat- of live-meekijkautorisatie.

8.9 Centrale categorieën

Categorieën zijn centrale, gedeelde catalogusobjecten. Een categorie zoals Rekenen of Taal heeft één centrale identiteit. Docenten maken geen privé-categorievariant met eigen verborgen betekenis.

8.9.1 Technische regels voor categorieën

RegelTechnische uitwerking
Categorie-identiteit is centraalNaam, kleur en icoon staan op de centrale categorie
Categorieën zijn herbruikbaarKoppeling aan meerdere niveaus/docentcontexten via cataloguskoppeltabellen
Docenten kunnen bestaande categorie koppelenVia commandservice met autorisatiecontrole
Docenten kunnen nieuwe centrale categorie voorstellen/aanmakenBinnen toegestane flow, met history en waarschuwing over gedeelde identiteit
Naam/kleur/icoon wijzigen is beheeractie wanneer categorie in gebruik isVia cataloguscommand met reden en history
Deactiveren/uitfaseren vereist impactcontroleActieve koppelingen en oefeningen bepalen of dit mag

8.9.2 Categoriezichtbaarheid voor leerlingen

De zichtbaarheid van een categorie in leerlingnavigatie wordt niet handmatig als losse leerlingvlag beheerd. Zij wordt afgeleid uit:

  • actuele niveaucontext;
  • actieve categorie-niveaukoppeling;
  • minimaal één actieve, toegankelijke oefening binnen die categorie;
  • server-side autorisatiecontext van de leerling.

Voor performance mag een afgeleide status of readmodel worden gebruikt, maar de bron blijft de catalogus- en autorisatiecontext. Een cache of readmodel mag autorisatie nooit verruimen.

8.10 Niveau-categorie-koppelingen

Een centrale categorie wordt pas bruikbaar in een niveau wanneer zij aan dat niveau is gekoppeld. Deze koppeling hoort technisch bij OefenHub.Catalog.

AspectTechnische keuze
BroncategorieHard FK binnen catalog, omdat categorie en koppeling dezelfde module delen
BronniveauHard FK binnen catalog, omdat niveau en koppeling dezelfde module delen
StatusActieve/inactieve koppeling volgens datamodelregels
DuplicatenUnieke constraint op relevante combinatie van niveau en categorie
HistorieVia categorie-/catalogushistory waar functioneel relevant

Binnen het catalogusdomein zijn harde foreign keys dus juist gewenst. De soft-link-regel geldt vooral over modulegrenzen heen.

8.11 Concrete oefeningen

Een oefening is een concrete configureerbare catalogusdefinitie binnen een niveau- en categoriecontext. De oefening bevat generieke metadata en een verwijzing naar precies één technisch modulecatalogusrecord.

8.11.1 Technische regels voor oefeningen

RegelTechnische uitwerking
Oefening hoort bij niveau/categoriecontextHard FK binnen catalog naar de relevante catalogusobjecten
Oefening verwijst naar één ExerciseModule-recordHard FK binnen catalog, omdat ExerciseModule als catalogusmetadata in hetzelfde schema staat
Oefening heeft generieke metadataNaam, icoon, status en overige generieke velden volgens database-informatie
Oefening heeft moduleconfiguratieModule-specifieke configuratiepayload generiek opgeslagen
Oefeningstatus bepaalt startbaarheidIsActive of equivalente status volgens datamodel
Nieuwe oefening start in onderhoudNiet zichtbaar/startbaar voor leerlingen totdat actief gemaakt
Oefening kan afgeleid zijn van andere oefeningParentrelatie binnen catalogus wanneer bron nog catalogusobject is
Wijzigingen zijn historyplichtigExerciseHistory legt mutaties vast

8.11.2 Oefeningstatus

De technische status van een oefening bepaalt of zij zichtbaar, startbaar of alleen beheerbaar/testbaar is. De exacte enum- of booleanvorm volgt uit de database-informatie. In de applicatielaag wordt status altijd via betekenisvolle domeinlogica gebruikt en niet verspreid als losse booleancontrole in Web-components.

StatusbetekenisGedrag
In onderhoudBeheerbaar door bevoegde docent/collaborator/beheerder, niet startbaar voor leerlingen
ActiefBeschikbaar binnen autorisatie- en niveaucontext
Inactief/verwijderd indien ondersteundNiet beschikbaar voor nieuwe starts, historisch herleidbaar

Wanneer een oefening niet actief is, mag een bestaande historische run leesbaar blijven via practice/resultaten, maar de oefening mag niet als nieuwe leerlingstart worden aangeboden.

8.12 ExerciseModules als catalogusmetadata

ExerciseModules is de catalogusregistratie van technische oefenmodules. Dit is niet hetzelfde als de concrete module-implementatie in een project zoals OefenHub.Modules.Arithmetic.Addition.

OnderdeelBetekenis
CatalogusrecordMetadata over beschikbare technische module
Module keyStabiele sleutel waarmee modulehost de implementatie kan resolven
ModuleversieVersiecontext voor configuratie en backwards compatibility
BeschikbaarheidOf module selecteerbaar, testbaar of uitgefaseerd is
ImplementatieprojectConcrete code die het contract uit Modules.Abstractions implementeert

Voorbeeld:

catalog.ExerciseModules
ModuleKey = Arithmetic.Addition
DisplayName = Optellen
Version = 1

src/OefenHub.Modules.Arithmetic.Addition
Implementeert het technische modulecontract.

De catalogus bewaart dus welke module gekozen is en met welke configuratie, maar voert de oefenlogica niet zelf uit.

8.13 Moduleconfiguratiepayload

De configuratie van een oefening is module-specifiek, maar de opslag ervan blijft generiek. De catalogusmodule bewaart de payload, terwijl de technische module verantwoordelijk is voor interpretatie, validatie en eventuele migratie.

AspectTechnische regel
OpslagGenerieke configuratiepayload op oefeningrecord of gekoppeld configuratierecord
FormaatJSON/base64 of equivalent volgens database-informatie en modulecontract
ValidatieVia ExerciseModuleHost naar concrete modulevalidator
VersiePayload bevat of is gekoppeld aan module-/configuratieversie
MutatieAlleen via cataloguscommandservice, niet rechtstreeks vanuit Web
HistoryOude en nieuwe configuratie of veilige samenvatting in ExerciseHistory

8.13.1 Validatieflow

Web configuratiescherm
→ Catalog commandservice
→ autorisatiecontrole
→ ExerciseModuleHost.Resolve(ModuleKey)
→ concrete module valideert configuratie
→ Catalog slaat geldige payload op
→ Catalog schrijft ExerciseHistory

De modulevalidator mag inhoudelijke moduleconfiguratieregels afdwingen. De catalogus blijft verantwoordelijk voor generieke regels zoals eigenaarschap, status, history, concurrency en opslag.

8.14 Configuratie-UI

De catalogusmodule levert niet zelf alle module-specifieke formulierlogica. De technische module levert via het modulecontract de informatie waarmee Web een configuratie-interface kan tonen.

OnderdeelEigenaar
Generiek configuratieschermOefenHub.Web
Beschikbare modulemetadataOefenHub.Catalog en ExerciseModuleHost
Configuratieschema/veldenConcrete technische module via abstractions
Validatie van moduleveldenConcrete technische module
Opslag van payloadOefenHub.Catalog

Hiermee blijft Web generiek genoeg om meerdere modules te ondersteunen, zonder dat catalogus of Web de inhoudelijke regels van elke oefenmodule hoeft te kennen.

8.15 Kopiëren en afgeleide oefeningen

Wanneer een docent een bestaande open oefening of configuratie als uitgangspunt gebruikt, ontstaat een nieuwe zelfstandige catalogusoefening. De nieuwe oefening mag een parentverwijzing bevatten naar de bron, zodat afgeleide configuraties zichtbaar en analyseerbaar blijven.

RegelTechnische uitwerking
Kopie is zelfstandigNieuwe oefening krijgt eigen record en eigen configuratiepayload
Bron blijft ongewijzigdWijzigingen in kopie beïnvloeden bron niet
ParentrelatieBinnen catalogus hard te modelleren wanneer bron en kopie catalogusoefeningen zijn
HistoryAanmaak via kopie krijgt expliciete COPY_FROM_PARENT-achtige historyactie
LeerlingrunsBestaande runs blijven in practice en worden niet aangepast

Dit verschilt van Maak deze oefening opnieuw na een afgeronde run. Dat is een practice-flow die een nieuwe run maakt op basis van historische runinhoud en valt niet onder cataloguskopiëren.

8.16 Catalogushistorie

Er komt geen centrale generieke auditmodule voor cataloguswijzigingen. Historie blijft domeinspecifiek binnen OefenHub.Catalog.

HistorytypeDoel
CategoryHistoryWijzigingen in centrale categorie-identiteit, status en migratiecontext
ExerciseHistoryWijzigingen aan oefeningmetadata, modulekeuze, configuratie en status
CategoryMigrationRegistratie van broncategorie naar doelcategorie
ExerciseModuleMigrationRegistratie van migratie van concrete oefeningen naar andere modulecontext

Historyrecords moeten voldoende informatie bevatten voor beheeranalyse en reconstructie. Vrije technische payloads of persoonsgegevens worden daarbij vermeden wanneer een compacte, veilige samenvatting voldoende is.

8.17 Categoriemigratie

Een categoriemigratie is een expliciete beheeractie waarbij een broncategorie administratief wordt omgezet naar een bestaande doelcategorie. Deze actie kan meerdere niveaukoppelingen en oefeningen raken en moet daarom gecontroleerd, transactioneel en auditbaar worden uitgevoerd.

8.17.1 Technische flow

1. Beheerder opent broncategorie.
2. Catalog bepaalt gebruiksimpact.
3. Beheerder kiest bestaande actieve doelcategorie.
4. Catalog valideert dat bron en doel verschillend zijn.
5. Catalog detecteert conflictsituaties.
6. Beheerder geeft verplichte reden op.
7. Catalog voert kritieke catalogusmutaties atomair uit.
8. Catalog registreert CategoryMigration en history.
9. Eventuele communicatie/readmodels worden volgens workflowbesluit verwerkt.

8.17.2 Migratieregels

RegelTechnische uitwerking
Doelcategorie bestaat alGeen nieuwe categorie aanmaken tijdens migratie
Bron en doel verschillenValidatie in commandservice en databasebescherming waar mogelijk
Doelcategorie is actiefAlleen geldige doelstatus toegestaan
Conflicten worden expliciet afgehandeldGeen blinde dubbele records
Historische runs worden niet herschrevenPractice blijft bron voor historische uitvoering
Bron blijft herleidbaarBronrecord wordt niet hard verwijderd
Actie is auditbaarMigrationrecord + CategoryHistory

De kritieke catalogusmutaties horen in één functionele transactie. Als een conflict niet oplosbaar is of een kritieke stap faalt, wordt de migratie niet gedeeltelijk uitgevoerd.

8.18 Modulemigratie

Een modulemigratie wijzigt de technische modulecontext van bestaande concrete oefeningen. Dit is risicovoller dan een gewone configuratiewijziging, omdat modulepayloads, validatie, vraaggeneratie, rendering en PDF-output kunnen verschillen.

8.18.1 Scope van modulemigratie

ScopeBetekenis
ProefmigratieAnalyseert impact zonder definitieve wijziging
OefeningmigratieMigreert één concrete oefening
Docent-/niveaugerichte migratieMigreert geselecteerde oefeningen binnen beheercontext
Globale migratieAlleen als expliciete beheeractie met zware validatie

8.18.2 Technische regels

RegelTechnische uitwerking
Historische runs blijven ongewijzigdPractice-runpayloads en snapshots worden niet herschreven
Configuratie wordt gevalideerdDoelmodule valideert of geconverteerde payload geldig is
Migratie is auditbaarExerciseModuleMigration + ExerciseHistory
Falen stopt kritieke mutatiesGeen halve modulewissel op catalogusoefening
Backwards compatibility blijft moduleverantwoordelijkheidZie modulecontract in hoofdstuk 09

Wanneer een modulemigratie alleen catalogusmetadata wijzigt maar bestaande payload niet kan worden geconverteerd, mag de migratie niet als geslaagd worden opgeslagen. Een beheerder moet dan een foutstatus of proefrapport krijgen, zonder dat de oefening half is omgezet.

8.19 Publieke cataloguscontracts

Andere modules mogen catalogusdata niet rechtstreeks via CatalogDbContext lezen of wijzigen. OefenHub.Catalog publiceert contracts voor de toegestane interacties.

ContracttypeVoorbeeldDoel
CommandserviceICatalogExerciseCommandServiceOefeningen aanmaken, wijzigen, status wijzigen
Query-serviceICatalogExerciseReaderOefeningcontext uitlezen voor Web of Practice
Modulemetadata-readerIExerciseModuleCatalogReaderBeschikbare modules en modulekeys raadplegen
MigrationserviceICatalogMigrationServiceCategorie- en modulemigraties uitvoeren
Authorization context readerICatalogObjectContextReaderObjectcontext leveren aan autorisatiemodule

Concrete namen zijn implementatiedetails, maar het principe is verplicht: cross-module toegang loopt via publieke cataloguscontracts.

8.20 Voorbeeld: oefening aanmaken

Web
→ ICatalogExerciseCommandService.CreateExerciseAsync
→ Authorization controleert docent/collaboratorcontext
→ Catalog controleert niveau en categorie
→ Catalog vraagt ExerciseModuleHost om modulemetadata/configuratieschema
→ Concrete module valideert configuratiepayload
→ Catalog slaat Exercise op in catalog schema
→ Catalog schrijft ExerciseHistory

De Web-laag krijgt geen Exercise entity terug, maar een contractmodel of resultaatmodel dat geschikt is voor UI-terugkoppeling.

8.21 Voorbeeld: leerling start een oefening

Web
→ Practice start-flow
→ Authorization controleert leerlingcontext
→ Practice vraagt Catalog om startbare oefeningcontext
→ Catalog retourneert contractmodel met ExerciseId, ModuleKey, configversie en snapshotwaarden
→ Practice vraagt ExerciseModuleHost om vraaggeneratie
→ Practice maakt ExerciseRun met soft links en snapshots

Catalogus blijft eigenaar van de oefendefinitie. Practice wordt eigenaar van de run, voortgang en historische snapshotcontext.

Wanneer OefenHub.Practice een run start, gebruikt zij catalogusinformatie om runcontext en snapshots vast te leggen. De run mag verwijzen naar catalogusobjecten, maar historische leesbaarheid mag niet afhankelijk zijn van actuele catalogusnamen of toekomstige migraties.

Practice-veldTechnische bedoeling
LevelIdSoft link naar catalogusniveau
CategoryIdSoft link naar cataloguscategorie of historische categoriecontext
ExerciseIdSoft link naar catalogusoefening
ExerciseModuleId/ModuleKeySoft link of snapshot naar modulecataloguscontext
LevelNameSnapshotHistorische weergavenaam
CategoryNameSnapshotHistorische weergavenaam
ExerciseNameSnapshotHistorische weergavenaam
ModuleKeySnapshotHerleidbaarheid van technische module

Exacte velden blijven onderdeel van database-informatie. Het Technisch Ontwerp-principe is dat practice niet afhankelijk mag worden van actuele catalogusrecords om historische resultaten te tonen.

8.23 Concurrency en wijzigingsconflicten

Catalogusobjecten worden door docenten, collaborators en beheerders gewijzigd. Daarom moet de catalogusmodule rekening houden met gelijktijdige wijzigingen.

SituatieTechnische aanpak
Twee gebruikers wijzigen dezelfde oefeningOptimistic concurrency of expliciete versiecontrole
Status wijzigt tijdens configuratieOpslaan faalt veilig of vereist herladen
Module wordt uitgefaseerd tijdens oefeningaanmaakCommandservice valideert modulebeschikbaarheid opnieuw
Categorie wordt gemigreerd tijdens bewerkingCommandservice valideert actuele categoriecontext opnieuw
Collaboratorrechten wijzigen tijdens bewerkingAutorisatiecontrole wordt bij opslaan opnieuw uitgevoerd

Web mag zichtbare knoppen tonen op basis van eerder opgehaalde context, maar iedere mutatie herhaalt server-side de actuele autorisatie- en objectstatuscontrole.

8.24 Delete behavior en historische leesbaarheid

Catalogusobjecten die historisch relevant zijn, worden niet hard verwijderd zolang zij door practice, reporting, history of migratieanalyse nodig kunnen zijn.

ObjectVoorkeursgedrag
Centrale categorieSoft delete/deactiveren/uitfaseren volgens domeinstatus
NiveauInactief/historisch maken wanneer nodig
OefeningInactief of verwijderd markeren, niet hard verwijderen bij historische runs
ExerciseModule-recordUitfaseren of niet-selecteerbaar maken, niet blind verwijderen
History/migrationrecordsBewaren volgens retentie- en auditbeleid

Hard delete is alleen toegestaan voor records zonder historische, juridische, audit- of functionele afhankelijkheid en moet in database-informatie en Technisch Ontwerp expliciet zijn toegestaan.

8.25 Seeddata en modulemetadata

Catalogusseeddata moet module-eigen, idempotent en niet blind overschrijvend zijn.

SeedtypeVoorbeeldGedrag
ModulemetadataBeschikbare technische modulesIdempotent op ModuleKey en versiecontext
BasiswaardelijstenStatussen of vaste codes indien in catalogus nodigIdempotent, niet afhankelijk van weergavetaal waar mogelijk
OntwikkeldataVoorbeeldniveaus/oefeningenAlleen development/testomgeving
Beheerbare contentNiet automatisch overschrijven na beheerwijzigingAlleen initieel of via expliciete migratieactie

Concrete technische moduleprojecten registreren hun descriptor via ExerciseModuleHost. De catalogus mag modulemetadata synchroniseren of valideren, maar mag module-implementaties niet hard coderen.

8.26 Beveiliging en autorisatie

Catalogusmutaties zijn autorisatiegevoelig. De catalogusmodule voert geen autorisatie uit op basis van clientstate, zichtbare knoppen of routeparameters. Iedere commandservice ontvangt een server-side bepaalde actor- en rolcontext.

ActieMinimale controle
Niveau aanmakenActieve docent- of beheercontext
Categorie koppelenRechten op het gekozen niveau
Nieuwe categorie aanmakenToegestane rolcontext en validatie op duplicaat/semantische overlap waar ondersteund
Oefening aanmaken/wijzigenEigenaar, actieve collaborator of beheercontext
Oefening activerenGeldige configuratie en bevoegde rolcontext
CategoriemigratieBeheercontext en verplichte reden
ModulemigratieBeheercontext of expliciet ondersteunde supportflow

Bij geweigerde toegang wordt geen gedeeltelijke catalogusdata teruggegeven die buiten de actuele rolcontext valt. Technische logs gebruiken correlation-id en lekken geen gevoelige payloadinhoud.

8.27 Logging en correlation

Catalogusacties moeten herleidbaar zijn, vooral bij migraties, statuswijzigingen en configuratiewijzigingen.

GebeurtenisLogging/historie
Oefening aangemaaktExerciseHistory + technische log op informatieniveau
Configuratie gewijzigdExerciseHistory met veilige oude/nieuwe waarde of samenvatting
Oefening geactiveerd/gedeactiveerdExerciseHistory
Categorie-identiteit gewijzigdCategoryHistory met reden
Categoriemigratie uitgevoerdCategoryMigration + CategoryHistory + correlation-id
Modulemigratie uitgevoerdExerciseModuleMigration + ExerciseHistory + correlation-id
Validatiefout moduleconfiguratieFunctionele foutmelding, technische log zonder volledige gevoelige payload

Cross-module acties moeten dezelfde correlation-id doorgeven aan betrokken modules en eventuele schedulingjobs.

8.28 Performance en caching

Catalogusdata wordt veel gelezen door navigatie, frontpages, oefeningstartpagina’s en beheerinterfaces. Toch mag caching autorisatie nooit vervangen.

DataCaching/readmodelbeleid
Beschikbare categorieën voor leerlingCache/readmodel toegestaan, server-side context blijft leidend
ModulemetadataCachebaar zolang invalidatie bij modulebeschikbaarheid is geregeld
BeheerimpacttellingenReadmodel of queryoptimalisatie toegestaan
OefeningconfiguratieAlleen cachebaar met versiecontrole en invalidatie
Migratie-impactBij voorkeur live of expliciet berekend vlak vóór uitvoeren

Wanneer performance-optimalisatie nodig is, wordt eerst bepaald of het gaat om brondata, readmodeldata of UI-compositie. Materialisatie hoort bij de eigenaar van de data of bij een expliciet vastgelegd readmodel.

8.29 Teststrategie voor catalogus

OefenHub.Catalog krijgt een eigen testproject onder tests.

tests/OefenHub.Catalog.Tests
TesttypeDekking
Unit testsStatusovergangen, validatie, historyregels, conflictregels
Module integration testsCatalogDbContext, migrations, constraints, seeddata
Contract testsPublieke cataloguscontracts voor Practice, Web en Admin
Migration testsCategorie- en modulemigraties inclusief rollback bij fouten
Authorization testsMutaties met eigenaar, collaborator, beheerder en geweigerde context
Concurrency testsGelijktijdige configuratie- en statuswijzigingen
Snapshot integration testsStartflow met Practice legt juiste cataloguscontext vast

Architecture tests moeten bewaken dat andere modules geen directe toegang nemen tot OefenHub.Catalog/Data/Entities of CatalogDbContext.

8.30 Implementatiechecklist

Bij implementatie of wijziging van catalogusfunctionaliteit moet minimaal gecontroleerd worden:

  • Is de wijziging bronhoudend voor catalogusdata of hoort zij bij Practice, Reporting, Web of Admin?
  • Staat de tabel in het schema catalog wanneer OefenHub.Catalog eigenaar is?
  • Is de DbContext-wijziging opgenomen in CatalogDbContext en bijbehorende migration?
  • Zijn cross-module verwijzingen soft links of gemotiveerde uitzonderingen?
  • Zijn historyrecords toegevoegd voor beheer- en configuratiewijzigingen?
  • Wordt moduleconfiguratie gevalideerd via ExerciseModuleHost?
  • Worden Web en andere modules alleen via publieke cataloguscontracts bediend?
  • Wordt bij iedere mutatie server-side autorisatie opnieuw gecontroleerd?
  • Zijn snapshotconsequenties voor Practice en Reporting beoordeeld?
  • Zijn seeddata en modulemetadata idempotent?
  • Zijn migration- en concurrencytests toegevoegd waar nodig?
  • Zijn open punten vastgelegd in het besluitenregister van het Technisch Ontwerp wanneer een keuze nog niet definitief is?

8.31 Implementatieverificaties

PuntToelichtingPlaats voor besluit
Exacte catalogusstatuswaardenBoolean IsActive of expliciete statusenum per object moet consistent blijven met database-informatiedatabase-informatie en besluitenregister van het Technisch Ontwerp
Modulemetadata-synchronisatieBepalen of modulemetadata bij startup, deployment of expliciete beheeractie wordt gesynchroniseerdHoofdstuk 09 en 21
ConfiguratiepayloadformaatDefinitief vastleggen hoe JSON/base64, versie en validatiesamenvatting worden opgeslagenHoofdstuk 07 en 09
MigratieconflictstrategieExacte conflictregels bij categoriemigratie en modulemigratie uitwerken per datamodelDatabase-informatie en schermdocumentatie
Cache/readmodelstrategieBepalen welke catalogusoverzichten materialisatie nodig hebbenHoofdstuk 17
ConcurrencymechanismeKeuze voor rowversion, concurrency token of andere EF Core-strategieHoofdstuk 07