Skip to main content

Oefenmodules en modulepayloads

22.1 Doel

OefenHub ondersteunt technische oefenmodules. Een oefenmodule levert modulespecifieke logica voor configuratie, vraaggeneratie, antwoordcontrole en vraagweergave.

Dit hoofdstuk beschrijft de functionele grenzen tussen:

  • de generieke OefenHub-engine;
  • technische oefenmodules;
  • administratieve modulemetadata;
  • concrete docent-oefeningen;
  • configuratiepayloads;
  • runpayloads;
  • vraagvoortgangspayloads;
  • modulebeheer;
  • modulemigratie;
  • historische runreconstructie.

Het FO beschrijft hier de samenhang en afbakening. De detailvelden van individuele modules blijven bronhoudend in de moduledocumentatie en de bijbehorende schermdocumentatie.

22.2 Kernprincipe

De technische module bepaalt de inhoudelijke oefenlogica.

De generieke OefenHub-engine blijft verantwoordelijk voor:

  • rol- en objectautorisatie;
  • selectie van niveau, categorie en oefening;
  • aanmaken van concrete oefeningen;
  • oefenrun-lifecycle;
  • server-side voortgang;
  • opslag;
  • audit;
  • geschiedenis;
  • resultaten;
  • PDF-export;
  • delen;
  • live meekijken;
  • beheergrenzen;
  • historische reconstructie.

Een module mag generieke platformverantwoordelijkheden niet zelf dupliceren of omzeilen.

22.3 Domeinafbakening

OnderdeelBinnen scope van dit hoofdstukBuiten scope van dit hoofdstuk
Technische moduleFunctionele rol van modulecode, configuratie, vraaggeneratie en antwoordcontrole.Implementatiedetails, codearchitectuur, dependency injection en interne classes.
ExerciseModulesAdministratieve modulebron, zichtbaarheid, actiefstatus, testzichtbaarheid en technische referentie.Vrij runtime ontdekken van modules uit assemblies of codepaden.
Concrete oefeningKoppeling tussen niveau/categorie, oefeningmetadata en precies één module.Volledige docentflow voor niveaus, categorieën en leerlingautorisaties.
ConfiguratiepayloadModulespecifieke configuratie van een concrete oefening.Relationeel uitsplitsen van alle modulespecifieke velden.
moduleKey en schemaVersionHerleidbaarheid binnen bestaande payloadstructuur.Een extra generieke databasekolom voor schemaherleidbaarheid.
RunpayloadModulespecifieke vraag- en antwoordstructuur binnen een oefenrun.Schermspecifieke presentatie van alle resultaatkolommen.
VraagvoortgangModulespecifieke vraagstate gecombineerd met uniforme voortgangsvelden.Volledig relationeel modelleren van iedere modulevraag.
ModulebeheerMetadata, actiefstatus, testzichtbaarheid, connectiviteitstest, migratie en history.Concrete docentconfiguraties vrij inhoudelijk bewerken vanuit centrale modulebeheerpagina.
ModulemigratieToekomstig gebruik van actieve concrete oefeningen naar een andere module begeleiden.Historische runs, resultaten, gedeelde oefeningen of PDF-contexten herschrijven.

22.4 Bronpositie

Oefenmodules raken meerdere bronlagen.

BronlaagBetekenis
FOBeschrijft de functionele scheiding tussen generieke engine, modules, payloads en beheer.
ModuledocumentatieBeschrijft per technische module de configuratievelden, validatie, vraagweergave en payloadbetekenis.
Usecases docentBeschrijven hoe een docent een module kiest, configureert, activeert en test.
Usecases beheerderBeschrijven hoe beheerders modulemetadata, status, testzichtbaarheid, connectiviteit en migratie beheren.
Database-informatieBeschrijft bronrecords, payloadvelden, runvelden, voortgangsvelden, history en migratiegrenzen.
SchermdocumentatieBeschrijft zichtbare velden, schermstappen, knoppen, lege toestanden en validaties.
MockupsOndersteunen visuele interpretatie, maar zijn geen bron voor definitieve payloadstructuur of testdata.

Het FO blijft DRY: module-specifieke velddefinities worden niet volledig gekopieerd uit de moduledocumentatie.

22.5 Functionele bouwlagen

LaagHoofdobject / bronFunctionele betekenis
ModulemetadataExerciseModulesAdministratieve registratie van beschikbare technische modules.
Concrete oefeningExercisesDoor docent geconfigureerde oefening binnen een niveau-/categoriecontext.
ModuleconfiguratieConfiguratiepayload op concrete oefeningModulespecifieke instellingen waarmee vragen later gegenereerd worden.
OefenrunExerciseRunsEén unieke uitvoering voor één gebruiker, gekoppeld aan historische context.
RunvraagdataExerciseRuns.QuestionDataJsonBase64Modulespecifieke vraag-, antwoord- en runpayload.
VraagvoortgangExerciseRunProgressOperationele voortgang per vraag met uniforme velden en modulespecifieke vraagstate.
Historische uitlezingrunvelden, voortgang, payload en modulecontextBron voor resultaat, geschiedenis, PDF-export en live/meekijkreconstructie.
Modulebeheerhistorymodulehistory, ExerciseModuleMigrations, ExerciseHistoryHerleidbaarheid van modulebeheer en migraties.

Deze lagen mogen niet door elkaar worden gebruikt als alternatieve bron van waarheid.

22.6 Scheiding tussen platform en module

OnderdeelGenerieke OefenHub-engineTechnische module
ModulebeschikbaarheidBepaalt zichtbaarheid op basis van ExerciseModules, IsActive, IsVisibleForTesting en rolcontext.Levert beschrijving en configuratiecomponent wanneer gekozen.
ModulekeuzeValideert dat de module selecteerbaar is binnen de actuele docentcontext.Levert herkenbare module-informatie en entrypoints.
Oefening aanmakenMaakt concrete oefening aan binnen niveau/categorie en koppelt aan precies één module.Valideert en serialiseert modulespecifieke configuratie.
OefeningstatusBeheert In onderhoud / Actief op concrete oefening.Mag die status niet zelfstandig omzeilen.
VraaggeneratieStart run, legt uniforme runmetadata vast en biedt generatiecontext.Genereert modulespecifieke vraagdata.
VraagweergaveBiedt generieke oefenplayer, voortgang, navigatie en anti-afleidingsgedrag.Rendert modulespecifieke opgave, antwoordvelden en feedbackstate.
AntwoordcontroleVerwerkt voortgang, totalen, timing, history en live-informatie.Bepaalt inhoudelijk of het antwoord goed/fout is en levert bijgewerkte vraagstate.
HervattenBepaalt of de run hervatbaar is binnen actuele context.Kan vraagstate opnieuw renderen op basis van opgeslagen payload.
ResultaatLeest uniforme runvelden, voortgang en historische payload.Kan detailrepresentatie leveren voor module-specifieke notatie.
PDF-exportGebruikt historische runcontext en uniforme exportregels.Kan renderhulp leveren voor complexe moduleweergave.
Live meekijkenGebruikt server-side opgeslagen voortgang als bron.Maakt renderbare actuele vraagstate mogelijk.

22.7 Administratieve modulebron

Beschikbare technische modules worden administratief beheerd via ExerciseModules.

ExerciseModules is de functionele koppellaag tussen:

  • leesbare modulenaam;
  • technische CodeReference;
  • moduleversie;
  • reguliere beschikbaarheid;
  • testzichtbaarheid;
  • connectiviteit met modulecode;
  • beheerhistory;
  • migratie-impact.

De technische implementatie wordt niet vrij runtime ontdekt. OefenHub gebruikt de administratieve moduleverwijzing en een technische module-interface of strategy-koppeling om de juiste modulecomponent aan te spreken wanneer dat nodig is.

22.8 Modulevelden en eigenaarschap

Veld / gegevenFunctionele regel
DisplayNameBeheerbare leesbare naam van de technische module.
CodeReferenceTechnische sleutel naar modulecode; read-only in beheer- en docentinterfaces.
VersionTechnisch beheerde versiereferentie; geen vrije oefeningnaam.
IsActiveBepaalt reguliere inzetbaarheid voor docentflows en nieuwe/actieve oefeningconfiguraties.
IsVisibleForTestingBepaalt zichtbaarheid voor geldige testcontexten, los van reguliere beschikbaarheid.
ExerciseModuleId op oefeningKoppelt één concrete oefening aan precies één module-record.
ExerciseModuleId op runLegt historische modulecontext van de uitvoering vast.
ImpactwaardenAfgeleide readmodelwaarden; geen bron van waarheid.
ModulehistoryLegt beheerwijzigingen en migratiehandelingen auditbaar vast.

Een docent wijzigt geen centrale modulemetadata. Een beheerder wijzigt geen modulespecifieke docentconfiguratie via de centrale modulebeheerpagina.

22.9 Modulebeschikbaarheid

Voor normale docentflows geldt:

  • alleen actieve modules zijn selecteerbaar;
  • de modulekeuze wordt server-side gevalideerd;
  • een oude clientselectie mag geen inmiddels inactieve module afdwingen;
  • CodeReference is nooit docentinput;
  • modulekeuze slaat op zichzelf nog geen concrete oefening op;
  • definitieve koppeling ontstaat pas bij opslag van de concrete oefening.

Voor leerlingen geldt:

  • modulebeschikbaarheid is nooit voldoende voor oefentoegang;
  • de concrete oefening moet actief en toegankelijk zijn;
  • de niveau-, categorie-, leerling- en autorisatiecontext moeten geldig zijn;
  • start en hervatten controleren opnieuw server-side de actuele toegang.

22.10 Testzichtbaarheid

IsVisibleForTesting maakt een module zichtbaar in geldige testcontexten.

Testzichtbaarheid:

  • maakt een module niet automatisch regulier actief;
  • kent geen TestDocent-rol toe;
  • vervangt geen beheerderautorisatie;
  • maakt geen leerlingtoegang aan;
  • publiceert geen oefening voor gewone leerlingen;
  • wijzigt geen bestaande oefeningconfiguratie;
  • schrijft geen leerlinggeschiedenis.

Testmodules of testzichtbare modules zijn bedoeld voor gecontroleerde evaluatie door bevoegde rollen. Zij mogen niet via oude routeparameters of clientstate zichtbaar worden voor gewone docent- of leerlingflows.

22.11 Docentflow: module kiezen

Een docent kiest bij het aanmaken van een nieuwe oefening precies één technische module.

Voor deze stap geldt:

AspectRegel
ContextEr moet een geldige docentcontext, niveaucontext en categoriecontext zijn.
BewerkrechtDe docent is eigenaar of actieve collaborator met bewerkrecht.
ModulelijstDe lijst wordt server-side opgebouwd uit selecteerbare modules.
TestfilterTestzichtbare modules verschijnen alleen binnen geldige testcontext.
SelectieDe selectie opent de moduleconfiguratieflow.
MutatieModulekeuze alleen veroorzaakt nog geen Exercises-record.
HercontroleDe gekozen module wordt opnieuw server-side gevalideerd.

De modulekeuze is dus een stap in de aanmaakflow, geen zelfstandige domeinmutatie.

22.12 Docentflow: oefening configureren

Na geldige modulekeuze configureert de docent een concrete oefening.

De configuratie bestaat uit:

  • generieke oefeninggegevens;
  • module-specifieke configuratievelden;
  • generieke validatie;
  • modulespecifieke validatie;
  • opslag van de concrete oefening;
  • opslag van de configuratiepayload;
  • historyregistratie.

Generieke oefeninggegevens zijn bijvoorbeeld:

  • oefeningnaam;
  • icoon;
  • niveau-/categoriecontext;
  • gekoppelde module;
  • status In onderhoud / Actief.

Modulespecifieke configuratievelden horen in de payload en worden door de gekozen module bepaald.

22.13 Configuratiepayload

Een concrete oefening bevat een modulespecifieke configuratiepayload.

Deze payload:

  • wordt generiek opgeslagen;
  • bevat modulespecifieke instellingen;
  • wordt door de module gevalideerd;
  • wordt door de module geïnterpreteerd;
  • blijft gekoppeld aan één concrete oefening;
  • vormt geen generieke querybron voor alle modules;
  • mag niet worden gebruikt om generieke autorisatie of zichtbaarheid te bepalen.

Voor de eerste uitgewerkte module is zichtbaar dat de configuratiepayload onder meer deze velden bevat:

{
"moduleKey": "OptellenAftrekken_Simple_v1",
"schemaVersion": "0.9"
}

Deze velden horen in de bestaande payloadstructuur.

22.14 Gebruik van moduleKey en schemaVersion

VeldFunctionele betekenis
moduleKeyIdentificeert de modulefamilie of modulevariant waarvoor de payload bedoeld is.
schemaVersionIdentificeert de structuur van de modulespecifieke configuratiepayload.

moduleKey en schemaVersion ondersteunen:

  • veilige interpretatie van bestaande configuraties;
  • backwards-compatible lezen van oudere payloads;
  • module-specifieke validatie;
  • gecontroleerde schema-evolutie;
  • foutafhandeling wanneer payload en module niet meer passen;
  • reconstructie van historische modulecontext naast ExerciseModuleId.

Deze velden vervangen niet de relationele modulekoppeling. Een concrete oefening en een run blijven ook relationeel gekoppeld aan ExerciseModuleId.

22.15 Geen extra generieke databasekolom voor schemaherleidbaarheid

Voor module- en schemaherleidbaarheid wordt geen extra generieke databasekolom geïntroduceerd zoals ConfigSchemaVersion.

De reden is functioneel:

  • configuratiestructuren verschillen per module;
  • schema-evolutie is module-specifiek;
  • de payload bevat al moduleKey en schemaVersion waar dat nodig is;
  • generieke queryscenario’s gebruiken uniforme velden buiten de payload;
  • backwards compatibility hoort bij module-interpretatie en gecontroleerde migratie;
  • extra generieke kolommen zouden een schijnzekerheid geven voor modules met verschillende interne schema’s.

OefenHub blijft wel relationele velden gebruiken voor gegevens die platformbreed nodig zijn, zoals oefeningstatus, modulekoppeling, runstatus, totalen, timing, statistieken en autorisatiecontext.

22.16 Payloadlagen

OefenHub kent meerdere payloadlagen. Deze mogen niet met elkaar verward worden.

PayloadlaagLocatieDoelBron van waarheid voor
ConfiguratiepayloadConcrete oefeningInstellingen waarmee nieuwe vragen gegenereerd worden.Toekomstige runaanmaak vanuit die oefening.
RunvraagdataExerciseRuns.QuestionDataJsonBase64Set gegenereerde vragen, antwoorden en moduledata voor één run.Historische vraaginhoud van die run.
VraagvoortgangspayloadExerciseRunProgress.QuestionStateJsonBase64Vraaggebonden toestand, invoerstructuur en lokale voortgang.Actuele en historische state van één vraag.
Uniforme runveldenExerciseRunsTotalen, status, timing, statistieken en context.Geschiedenis, resultaten, PDF, readmodels en live-overzicht.
Uniforme voortgangsveldenExerciseRunProgressVolgorde, timing, correctheid, Geen idee en vraagafronding.Hervatten, live meekijken en resultaatdetail.

Modulespecifieke data blijft flexibel in JSON/base64. Uniforme gegevens blijven relationeel beschikbaar wanneer zij platformbreed nodig zijn.

22.17 Configuratiepayload versus runpayload

De configuratiepayload van een oefening en de runpayload van een concrete uitvoering hebben verschillende functies.

AspectConfiguratiepayloadRunpayload
MomentVastgelegd bij aanmaken of bewerken van concrete oefening.Vastgelegd bij genereren van een run.
ScopeEén oefeningconfiguratie.Eén uitvoering door één gebruiker.
InhoudRegels, grenzen en opties voor vraaggeneratie.Gegenereerde vragen, antwoorddata en modulespecifieke vraagcontext.
MutatieWijzigt bij bewerken van oefening.Blijft historisch bij de run horen.
GebruikNieuwe runs genereren.Resultaat, geschiedenis, PDF en reconstructie van die run.
HistorieVastgelegd via oefeninghistory.Bewaard als onderdeel van runhistorie.

Een wijziging aan de configuratiepayload van een oefening mag bestaande afgeronde runs niet herschrijven.

22.18 Vraagvoortgangspayload versus uniforme voortgang

Vraagvoortgang bevat zowel module-specifieke als uniforme gegevens.

GegevenPlaatsReden
Vraagparameters en module-stateQuestionStateJsonBase64Verschilt per module en hoeft niet generiek querybaar te zijn.
VolgnummerUniform voortgangsveldNodig voor player, resultaatdetail en live meekijken.
Eerste toonmomentUniform voortgangsveldNodig voor timing en statistiek.
BeantwoordmomentUniform voortgangsveldNodig voor voortgang, geschiedenis en live meekijken.
Correct / foutUniform voortgangsveldNodig voor totalen en resultaatweergave.
Geen ideeUniform voortgangsveldNodig voor uniforme telling en resultaatweergave.
Vraag afgerondUniform voortgangsveldNodig om vraagniveau en runniveau te onderscheiden.

Deze hybride aanpak voorkomt dat alle modules relationeel uitgesplitst moeten worden, terwijl veelgebruikte voortgangsdata wel betrouwbaar uitleesbaar blijft.

22.19 Vraaggeneratie

Vraaggeneratie gebeurt pas bij het starten van een run.

De generieke engine:

  • controleert leerling- of testcontext;
  • valideert oefeningtoegang;
  • bepaalt aantal vragen binnen geldige grenzen;
  • maakt het runrecord aan;
  • koppelt run aan gebruiker, niveau, categorie, oefening en module;
  • biedt de module de relevante generatiecontext;
  • slaat gegenereerde vraagdata historisch op.

De module:

  • leest de configuratiepayload;
  • valideert dat de configuratie bruikbaar is;
  • genereert modulespecifieke vraagdata;
  • bepaalt de juiste antwoorden of antwoordstructuur;
  • levert de payload terug voor opslag in de runstructuur.

Een run is dus geen live verwijzing naar de actuele configuratiepayload; zij bevat de historische vraaginhoud die bij genereren is ontstaan.

22.20 Antwoordcontrole

Bij beantwoording geldt:

  • de generieke engine ontvangt de bevestigde invoer;
  • de module interpreteert de invoer en bepaalt inhoudelijke correctheid;
  • de generieke engine verwerkt timing, correct/fout, Geen idee, totalen en voortgang;
  • de bijgewerkte vraagstate wordt server-side opgeslagen;
  • live-meekijkreadmodels kunnen op basis van server-side voortgang worden bijgewerkt.

De module bepaalt dus niet zelfstandig of een run afgerond is, of een leerling toegang heeft, of een resultaat zichtbaar mag zijn. Dat blijft generieke applicatielogica.

22.21 Hervatten en onderbreken

Hervatten gebruikt de opgeslagen run en voortgang.

Voor hervatten geldt:

  • de run moet niet afgerond zijn;
  • de gebruiker moet opnieuw server-side toegang hebben tot de juiste context;
  • de runcontext moet passen bij de oefening en het actieve niveau;
  • de module moet de opgeslagen vraagstate kunnen renderen;
  • ontbreken of corruptie van payload leidt tot veilige foutafhandeling.

Onderbreken door navigeren, logout of verbindingsverlies rondt de run niet af. De opgeslagen voortgang blijft leidend.

22.22 Resultaten, geschiedenis en PDF-export

Resultaatweergave, geschiedenis en PDF-export gebruiken de historische runcontext.

Leidend zijn:

  • opgeslagen runcontext;
  • uniforme runvelden;
  • uniforme voortgangsvelden;
  • historische modulepayloads;
  • vraag- en antwoorddata zoals opgeslagen bij de run;
  • module-specifieke renderhulp waar nodig.

Latere wijzigingen aan:

  • modulemetadata;
  • modulecode;
  • centrale categorieën;
  • oefeningnaam;
  • oefeningconfiguratie;
  • modulebeschikbaarheid;
  • modulemigratie;

mogen bestaande historische resultaten, geschiedenisregels en PDF-exportcontexten niet stilzwijgend herschrijven.

22.23 Live meekijken

Live meekijken gebruikt server-side opgeslagen voortgang als bron.

SignalR of een vergelijkbaar realtime transport is alleen transport.

De module kan renderinformatie leveren voor de actuele vraagstate, maar:

  • maakt geen aparte live-bron van waarheid;
  • mag voortgang niet buiten de generieke engine opslaan;
  • mag autorisatie voor meekijken niet bepalen;
  • mag geen antwoordmutaties door meekijkers toestaan.

Een modulepayload moet daarom voldoende informatie bevatten om de actuele vraag veilig te tonen of te reconstrueren binnen de generieke live-meekijkcontext.

22.24 Docenttesten

Docenten mogen oefeningen testen binnen de daarvoor bedoelde testflow.

Voor docenttesten geldt:

OnderwerpRegel
DoelControleren of configuratie, vraaggeneratie en weergave werken.
ActorBevoegde docent of collaborator binnen geldige context.
RunsoortTestrun, niet reguliere leerlingrun.
GeschiedenisKomt niet in normale leerlinggeschiedenis of docentresultaten.
OpslagMag tijdelijk voortgang opslaan zolang de test actief is.
CleanupAchtergebleven testruns worden periodiek opgeruimd volgens de geldende cleanupregels.
AutorisatieTesten vervangt geen leerlingtoegang en publiceert de oefening niet.
ModuleModule wordt via dezelfde module-interface aangesproken als bij normale runs.

Testresultaten zijn dus functioneel controle-informatie, geen onderwijsresultaat.

22.25 Modulebeheer

Modulebeheer is een centrale beheerfunctie voor technische modulemetadata en onderhoudsacties.

Binnen modulebeheer vallen:

  • moduleoverzicht bekijken;
  • modulebeheer-detail openen;
  • toegestane modulemetadata wijzigen;
  • actiefstatus wijzigen;
  • testzichtbaarheid wijzigen;
  • moduleconnectiviteit testen;
  • proefmigratie uitvoeren;
  • docentgerichte modulemigratie uitvoeren;
  • globale modulemigratie uitvoeren;
  • modulegeschiedenis bekijken.

Buiten modulebeheer vallen:

  • technische modulecode implementeren;
  • nieuwe modules vrij via GUI aanmaken;
  • concrete docent-oefenconfiguraties inhoudelijk bewerken;
  • leerlingruns herschrijven;
  • resultaten corrigeren;
  • geschiedenis of PDF’s aanpassen;
  • rollen zoals TestDocent toekennen;
  • docent-leerlingrelaties of niveauautorisaties wijzigen.

22.26 Actiefstatus van modules

IsActive bepaalt reguliere inzetbaarheid van een module.

Voor actiefstatus geldt:

  • actieve modules kunnen in normale docentflows beschikbaar zijn;
  • inactieve modules zijn niet selecteerbaar voor nieuwe reguliere oefeningen;
  • uitschakelen mag niet leiden tot onleesbare historische runs;
  • uitschakelen mag niet zomaar actieve concrete oefeningen breken;
  • de exacte blokkade of impactcontrole wordt server-side bepaald;
  • zichtbare togglepositie in de UI is geen autorisatiebewijs.

Een module inactief maken is een beheeractie met impact op toekomstig gebruik, niet op historische reconstructie.

22.27 Connectiviteitstest

Een moduleconnectiviteitstest controleert of de administratieve moduleverwijzing technisch aanspreekbaar is.

Deze test:

  • gebruikt de server-side modulekoppeling;
  • controleert bijvoorbeeld of CodeReference naar een bruikbare module-interface leidt;
  • toont een beheerresultaat;
  • logt technische fouten waar nodig;
  • wijzigt geen moduleconfiguraties;
  • maakt geen oefenruns;
  • wijzigt geen modulebeschikbaarheid;
  • telt niet als inhoudelijke modulemigratie.

De connectiviteitstest is dus een beheerdiagnose en geen functionele oefeningactie.

22.28 Modulemigratie

Modulemigratie is een expliciete beheerhandeling om actieve concrete oefeningen van een bronmodule naar een doelmodule te brengen.

Ondersteunde migratiescopes zijn:

ScopeBetekenisMutatiegrens
ProefuitvoeringPrecies één geselecteerde concrete oefening gecontroleerd migreren.Eén oefening, één migratieregistratie en history voor die oefening.
DocentgerichtActieve concrete oefeningen van één geselecteerde docent migreren.Alleen oefeningen binnen de gekozen docentcontext die de bronmodule gebruiken.
GlobaalAlle actieve concrete oefeningen op de bronmodule migreren.Alle actieve concrete oefeningen die server-side binnen de globale scope vallen.

Migratie beïnvloedt toekomstig gebruik van concrete oefeningen. Historische runs blijven staan.

22.29 Modulemigratie en payloadconversie

Functioneel uitgangspunt is dat modulemigratie niet automatisch historische payloads converteert.

Voor concrete oefeningen geldt:

  • ExerciseModuleId kan worden gewijzigd naar de doelmodule binnen de gekozen scope;
  • migratie wordt auditbaar vastgelegd;
  • per oefening ontstaat ExerciseHistory;
  • de beheerder geeft een reden;
  • de doelmodule moet actief en verschillend van de bronmodule zijn;
  • de scope wordt server-side bepaald;
  • gedeeltelijke onherleidbare migraties zijn niet toegestaan.

Voor configuratiepayloads geldt:

  • automatische conversie is niet vanzelfsprekend;
  • conversie mag alleen plaatsvinden wanneer dit expliciet onderdeel is van de technische migratieverwerking;
  • de functionele grens moet zichtbaar blijven in migratieaudit;
  • payloadcompatibiliteit wordt niet hard door OefenHub bewezen;
  • rollback- en downgradebewustzijn horen bij beheer en technische migratiestrategie.

Voor historische runs geldt:

  • ExerciseRuns worden niet herschreven;
  • ExerciseRunProgress wordt niet herschreven;
  • SharedExercises en snapshots worden niet herschreven;
  • bestaande resultaten en PDF-contexten blijven ongewijzigd;
  • historische modulecontext blijft reconstrueerbaar.

22.30 Backwards compatibility en schema-evolutie

Modules zijn verantwoordelijk voor gecontroleerde omgang met oudere payloadschema’s.

Backwards compatibility kan onder meer betekenen:

  • oudere configuratiepayloads blijven leesbaar;
  • oudere runpayloads blijven renderbaar voor geschiedenis en PDF;
  • oudere vraagstate blijft bruikbaar voor resultaatdetail;
  • validatie geeft een duidelijke fout wanneer een payload niet meer bruikbaar is;
  • migratiepaden zijn expliciet en auditbaar;
  • nieuwe schema’s worden niet stilzwijgend over oude payloads gelegd.

OefenHub hoeft niet hard te bewijzen dat elke moduleversie volledig uitwisselbaar is. Wel moet het platform voorkomen dat onduidelijke of gedeeltelijke mutaties historische data onherleidbaar maken.

22.31 Voorbeeldmodule: Optellen & Aftrekken simpel

De module Optellen & Aftrekken simpel is de eerste uitgewerkte referentiemodule.

Deze module laat zien dat een module:

  • modulespecifieke configuratievelden toont;
  • moduleconfiguratie valideert;
  • vragen genereert op basis van opgeslagen configuratie;
  • één vraag tegelijk binnen de generieke player toont;
  • leerlingantwoorden interpreteert;
  • feedbackstates aanlevert;
  • modulespecifieke vraag- en antwoorddata levert voor opslag;
  • moduleKey en schemaVersion in de payload kan opnemen.

De module is voorbeeld en referentie. Het FO beschrijft het generieke moduleprincipe zodat toekomstige modules dezelfde functionele scheiding kunnen volgen.

22.32 Autorisatie- en veiligheidsregels

Voor oefenmodules gelden dezelfde basisregels als voor andere domeinen.

  • Zichtbare modulekaarten zijn geen autorisatiebewijs.
  • Zichtbare oefeningknoppen zijn geen autorisatiebewijs.
  • Routeparameters mogen geen module, oefening of run afdwingen.
  • Clientstate mag geen inactieve module opnieuw selecteerbaar maken.
  • Moduleconfiguratie wordt server-side gevalideerd.
  • Vraagbeantwoording wordt server-side verwerkt.
  • Modulepayloads mogen geen autorisatiedata bevatten als bron van waarheid.
  • Foutmeldingen tonen geen stacktraces, tokens, interne payloads of gevoelige data aan gewone gebruikers.
  • Beheerdercontext geeft geen vrije bypass op docent- of leerlingflows.
  • Testcontexten mogen geen reguliere leerlingresultaten opleveren.

Iedere route, detailweergave, export, mutatie en liveactie controleert server-side opnieuw de actuele context.

22.33 Readmodels en impactwaarden

Modulegerelateerde overzichten kunnen afgeleide waarden tonen.

Voorbeelden:

  • aantal concrete oefeningen op module;
  • aantal actieve concrete oefeningen;
  • aantal docenten dat een module gebruikt;
  • aantal actieve leerlingtoegangen geraakt door module;
  • testzichtbaarheid;
  • migratie-impact;
  • recente modulewijzigingen;
  • connectiviteitsteststatus.

Deze waarden zijn readmodels.

Zij:

  • wijzigen geen domeindata;
  • zijn geen autorisatiebewijs;
  • moeten server-side worden opgebouwd;
  • moeten duidelijk definiëren welke records meetellen;
  • mogen historische runs niet meetellen alsof zij actieve moduleafhankelijkheden zijn, tenzij dat expliciet als historische impact wordt gelabeld.

22.34 Audit en history

Modulegerelateerde mutaties zijn auditbaar.

Minimaal auditbaar zijn:

MutatieAudit / history
Modulemetadata wijzigenActor, tijdstip, veld, oude waarde, nieuwe waarde en reden waar vereist.
Actiefstatus wijzigenActor, tijdstip, oude status, nieuwe status, reden en impactcontrole.
Testzichtbaarheid wijzigenActor, tijdstip, oude waarde, nieuwe waarde en reden waar vereist.
ConnectiviteitstestTechnisch resultaat en tijdstip waar beheerdiagnose dit vereist.
ProefmigratieBronmodule, doelmodule, oefening, actor, tijdstip, reden en resultaat.
Docentgerichte migratieBronmodule, doelmodule, docentcontext, geraakte oefeningen, actor, tijdstip en reden.
Globale migratieBronmodule, doelmodule, scope, geraakte oefeningen, actor, tijdstip en reden.
OefeningconfiguratieExerciseHistory binnen docent- of supportcontext.

History is reconstructie-informatie. Zij vervangt geen payload, runbron of resultaatbron.

22.35 Lege toestanden

Lege toestanden zijn normaal wanneer er geen data beschikbaar is binnen een geldige context.

Voorbeelden:

  • geen selecteerbare modules voor een docent;
  • alleen testmodules beschikbaar buiten testcontext;
  • geen modules in modulebeheer;
  • geen actieve doelmodules voor migratie;
  • geen docenten die de bronmodule gebruiken;
  • geen actieve concrete oefeningen op een module;
  • geen modulehistory;
  • geen migratiegeschiedenis;
  • geen recente connectiviteitstest;
  • geen testzichtbare modules.

Een lege toestand mag informatief zijn en vervolgacties uitschakelen, maar mag geen technische details of verborgen modulekeys lekken aan onbevoegde gebruikers.

22.36 Fouttoestanden

Fouttoestanden ontstaan wanneer de modulecontext niet veilig gebruikt kan worden.

Voorbeelden:

  • gekozen module bestaat niet;
  • module is intussen inactief geworden;
  • module is niet zichtbaar binnen de actuele testcontext;
  • CodeReference kan niet gekoppeld worden aan modulecode;
  • configuratiepayload is ongeldig;
  • moduleKey past niet bij verwachte modulefamilie;
  • schemaVersion wordt niet ondersteund;
  • runpayload kan niet veilig gelezen worden;
  • vraagstate ontbreekt of is corrupt;
  • modulevalidatie faalt;
  • modulemigratie heeft geen geldige doelmodule;
  • migratie naar dezelfde module wordt geprobeerd;
  • migratiescope is intussen gewijzigd;
  • payloadconversie faalt;
  • historische resultaatweergave kan de moduleweergave niet reconstrueren.

Bij fouttoestanden geldt:

  • geen gedeeltelijke oefeningopslag zonder herleidbaarheid;
  • geen gedeeltelijke onherleidbare migratie;
  • geen leerlingstart wanneer oefening niet veilig gegenereerd kan worden;
  • geen technische payloads aan gewone gebruikers;
  • beheer krijgt waar nodig een veilige analyse- of foutmelding;
  • technische logging mag geen gevoelige gebruikersdata onnodig vastleggen.

22.37 Relatie tot andere FO-hoofdstukken

HoofdstukRelatie
Oefencatalogus, niveaus, categorieën en oefeningenBeschrijft concrete oefeningen, categorieën, niveaus en leerlingzichtbaarheid.
Leerling: oefenen, voortgang en resultatenBeschrijft run-lifecycle, beantwoorden, voortgang, resultaten en geschiedenis.
Gedeelde oefeningenGebruikt historische runpayloads en snapshots wanneer oefeningen gedeeld worden.
DocentfunctionaliteitBeschrijft docentbeheer van oefenaanbod, configureren, testen en activeren.
BeheerderfunctionaliteitBeschrijft centrale beheercontext en ondersteuning rond modules.
Live meekijkenGebruikt server-side voortgang en renderbare modulevraagstate.
PDF-export en resultaatpresentatieGebruikt historische runcontext en module-renderhulp waar nodig.
Schermlaag en UX-specificatiesBeschrijft schermdocumentatie, popupkeys, read-only gedrag en foutafhandeling.
Functionele architectuurcontextPlaatst module-interface en generieke engine in bredere architectuurcontext.

22.38 Gerelateerde bronverwijzingen

BronLink
Technisch Ontwerp — oefenmodulecontractOefenmodulecontract en dynamische module-integratie
Technisch Ontwerp — oefencatalogusOefencatalogus, niveaus, categorieën, oefeningen en modules
Technisch Ontwerp — oefenruns en payloadsOefenruns, voortgang, resultaten, statistieken en PDF-brondata
FO — Oefencatalogus, niveaus, categorieën en oefeningenOefencatalogus
FO — Leerling: oefenen, voortgang en resultatenLeerling oefenen
FO — Gedeelde oefeningenGedeelde oefeningen
FO — DocentfunctionaliteitDocentfunctionaliteit
FO — BeheerderfunctionaliteitBeheerderfunctionaliteit
FO — Live meekijkenLive meekijken
FO — PDF-export en resultaatpresentatiePDF-export en resultaatpresentatie
Oefenmodules — introOefenmodules
Oefenmodules — moduleplatform en contractModuleplatform en contract
Oefenmodule — Optellen & Aftrekken simpelOptellen & Aftrekken simpel
Usecases docent — oefeningen configureren en testenOefeningen configureren en testen
UC-DOC-OEF-003 — Technische module selecterenTechnische module selecteren
UC-DOC-OEF-004 — Oefening configurerenOefening configureren
UC-DOC-OEF-008 — Oefening testen als docentOefening testen als docent
Usecases beheerder — modules beherenModules beheren
UC-BEH-MOD-003 — Modulegegevens wijzigenModulegegevens wijzigen
UC-BEH-MOD-004 — Module-actiefstatus wijzigenModule-actiefstatus wijzigen
UC-BEH-MOD-005 — Test-zichtbaarheid wijzigenTest-zichtbaarheid wijzigen
UC-BEH-MOD-006 — Moduleconnectiviteit testenModuleconnectiviteit testen
UC-BEH-MOD-007 — Modulemigratie docentgericht uitvoerenModulemigratie docentgericht uitvoeren
UC-BEH-MOD-008 — Modulemigratie globaal uitvoerenModulemigratie globaal uitvoeren
UC-BEH-MOD-009 — Modulemigratie-proefuitvoering controlerenModulemigratie-proefuitvoering controleren
UC-BEH-MOD-010 — Modulegeschiedenis bekijkenModulegeschiedenis bekijken
Schermdocumentatie docent — nieuwe oefeningNieuwe oefening
Schermdocumentatie beheerder — modulesModules
Database-informatie — configuratie en contentbeheerConfiguratie en contentbeheer
Database-informatie — oefenruns, delen en voortgangOefenruns, delen en voortgang
Ontwerpbron — autorisatiematrixAutorisatiematrix
Ontwerpbron — business rulesBusiness rules
Ontwerpbron — command-registerCommand-register
Ontwerpbron — event-registerEvent-register