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
| Onderdeel | Binnen scope van dit hoofdstuk | Buiten scope van dit hoofdstuk |
|---|---|---|
| Technische module | Functionele rol van modulecode, configuratie, vraaggeneratie en antwoordcontrole. | Implementatiedetails, codearchitectuur, dependency injection en interne classes. |
ExerciseModules | Administratieve modulebron, zichtbaarheid, actiefstatus, testzichtbaarheid en technische referentie. | Vrij runtime ontdekken van modules uit assemblies of codepaden. |
| Concrete oefening | Koppeling tussen niveau/categorie, oefeningmetadata en precies één module. | Volledige docentflow voor niveaus, categorieën en leerlingautorisaties. |
| Configuratiepayload | Modulespecifieke configuratie van een concrete oefening. | Relationeel uitsplitsen van alle modulespecifieke velden. |
moduleKey en schemaVersion | Herleidbaarheid binnen bestaande payloadstructuur. | Een extra generieke databasekolom voor schemaherleidbaarheid. |
| Runpayload | Modulespecifieke vraag- en antwoordstructuur binnen een oefenrun. | Schermspecifieke presentatie van alle resultaatkolommen. |
| Vraagvoortgang | Modulespecifieke vraagstate gecombineerd met uniforme voortgangsvelden. | Volledig relationeel modelleren van iedere modulevraag. |
| Modulebeheer | Metadata, actiefstatus, testzichtbaarheid, connectiviteitstest, migratie en history. | Concrete docentconfiguraties vrij inhoudelijk bewerken vanuit centrale modulebeheerpagina. |
| Modulemigratie | Toekomstig 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.
| Bronlaag | Betekenis |
|---|---|
| FO | Beschrijft de functionele scheiding tussen generieke engine, modules, payloads en beheer. |
| Moduledocumentatie | Beschrijft per technische module de configuratievelden, validatie, vraagweergave en payloadbetekenis. |
| Usecases docent | Beschrijven hoe een docent een module kiest, configureert, activeert en test. |
| Usecases beheerder | Beschrijven hoe beheerders modulemetadata, status, testzichtbaarheid, connectiviteit en migratie beheren. |
| Database-informatie | Beschrijft bronrecords, payloadvelden, runvelden, voortgangsvelden, history en migratiegrenzen. |
| Schermdocumentatie | Beschrijft zichtbare velden, schermstappen, knoppen, lege toestanden en validaties. |
| Mockups | Ondersteunen 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
| Laag | Hoofdobject / bron | Functionele betekenis |
|---|---|---|
| Modulemetadata | ExerciseModules | Administratieve registratie van beschikbare technische modules. |
| Concrete oefening | Exercises | Door docent geconfigureerde oefening binnen een niveau-/categoriecontext. |
| Moduleconfiguratie | Configuratiepayload op concrete oefening | Modulespecifieke instellingen waarmee vragen later gegenereerd worden. |
| Oefenrun | ExerciseRuns | Eén unieke uitvoering voor één gebruiker, gekoppeld aan historische context. |
| Runvraagdata | ExerciseRuns.QuestionDataJsonBase64 | Modulespecifieke vraag-, antwoord- en runpayload. |
| Vraagvoortgang | ExerciseRunProgress | Operationele voortgang per vraag met uniforme velden en modulespecifieke vraagstate. |
| Historische uitlezing | runvelden, voortgang, payload en modulecontext | Bron voor resultaat, geschiedenis, PDF-export en live/meekijkreconstructie. |
| Modulebeheerhistory | modulehistory, ExerciseModuleMigrations, ExerciseHistory | Herleidbaarheid van modulebeheer en migraties. |
Deze lagen mogen niet door elkaar worden gebruikt als alternatieve bron van waarheid.
22.6 Scheiding tussen platform en module
| Onderdeel | Generieke OefenHub-engine | Technische module |
|---|---|---|
| Modulebeschikbaarheid | Bepaalt zichtbaarheid op basis van ExerciseModules, IsActive, IsVisibleForTesting en rolcontext. | Levert beschrijving en configuratiecomponent wanneer gekozen. |
| Modulekeuze | Valideert dat de module selecteerbaar is binnen de actuele docentcontext. | Levert herkenbare module-informatie en entrypoints. |
| Oefening aanmaken | Maakt concrete oefening aan binnen niveau/categorie en koppelt aan precies één module. | Valideert en serialiseert modulespecifieke configuratie. |
| Oefeningstatus | Beheert In onderhoud / Actief op concrete oefening. | Mag die status niet zelfstandig omzeilen. |
| Vraaggeneratie | Start run, legt uniforme runmetadata vast en biedt generatiecontext. | Genereert modulespecifieke vraagdata. |
| Vraagweergave | Biedt generieke oefenplayer, voortgang, navigatie en anti-afleidingsgedrag. | Rendert modulespecifieke opgave, antwoordvelden en feedbackstate. |
| Antwoordcontrole | Verwerkt voortgang, totalen, timing, history en live-informatie. | Bepaalt inhoudelijk of het antwoord goed/fout is en levert bijgewerkte vraagstate. |
| Hervatten | Bepaalt of de run hervatbaar is binnen actuele context. | Kan vraagstate opnieuw renderen op basis van opgeslagen payload. |
| Resultaat | Leest uniforme runvelden, voortgang en historische payload. | Kan detailrepresentatie leveren voor module-specifieke notatie. |
| PDF-export | Gebruikt historische runcontext en uniforme exportregels. | Kan renderhulp leveren voor complexe moduleweergave. |
| Live meekijken | Gebruikt 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 / gegeven | Functionele regel |
|---|---|
DisplayName | Beheerbare leesbare naam van de technische module. |
CodeReference | Technische sleutel naar modulecode; read-only in beheer- en docentinterfaces. |
Version | Technisch beheerde versiereferentie; geen vrije oefeningnaam. |
IsActive | Bepaalt reguliere inzetbaarheid voor docentflows en nieuwe/actieve oefeningconfiguraties. |
IsVisibleForTesting | Bepaalt zichtbaarheid voor geldige testcontexten, los van reguliere beschikbaarheid. |
ExerciseModuleId op oefening | Koppelt één concrete oefening aan precies één module-record. |
ExerciseModuleId op run | Legt historische modulecontext van de uitvoering vast. |
| Impactwaarden | Afgeleide readmodelwaarden; geen bron van waarheid. |
| Modulehistory | Legt 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;
CodeReferenceis 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:
| Aspect | Regel |
|---|---|
| Context | Er moet een geldige docentcontext, niveaucontext en categoriecontext zijn. |
| Bewerkrecht | De docent is eigenaar of actieve collaborator met bewerkrecht. |
| Modulelijst | De lijst wordt server-side opgebouwd uit selecteerbare modules. |
| Testfilter | Testzichtbare modules verschijnen alleen binnen geldige testcontext. |
| Selectie | De selectie opent de moduleconfiguratieflow. |
| Mutatie | Modulekeuze alleen veroorzaakt nog geen Exercises-record. |
| Hercontrole | De 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
| Veld | Functionele betekenis |
|---|---|
moduleKey | Identificeert de modulefamilie of modulevariant waarvoor de payload bedoeld is. |
schemaVersion | Identificeert 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
moduleKeyenschemaVersionwaar 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.
| Payloadlaag | Locatie | Doel | Bron van waarheid voor |
|---|---|---|---|
| Configuratiepayload | Concrete oefening | Instellingen waarmee nieuwe vragen gegenereerd worden. | Toekomstige runaanmaak vanuit die oefening. |
| Runvraagdata | ExerciseRuns.QuestionDataJsonBase64 | Set gegenereerde vragen, antwoorden en moduledata voor één run. | Historische vraaginhoud van die run. |
| Vraagvoortgangspayload | ExerciseRunProgress.QuestionStateJsonBase64 | Vraaggebonden toestand, invoerstructuur en lokale voortgang. | Actuele en historische state van één vraag. |
| Uniforme runvelden | ExerciseRuns | Totalen, status, timing, statistieken en context. | Geschiedenis, resultaten, PDF, readmodels en live-overzicht. |
| Uniforme voortgangsvelden | ExerciseRunProgress | Volgorde, 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.
| Aspect | Configuratiepayload | Runpayload |
|---|---|---|
| Moment | Vastgelegd bij aanmaken of bewerken van concrete oefening. | Vastgelegd bij genereren van een run. |
| Scope | Eén oefeningconfiguratie. | Eén uitvoering door één gebruiker. |
| Inhoud | Regels, grenzen en opties voor vraaggeneratie. | Gegenereerde vragen, antwoorddata en modulespecifieke vraagcontext. |
| Mutatie | Wijzigt bij bewerken van oefening. | Blijft historisch bij de run horen. |
| Gebruik | Nieuwe runs genereren. | Resultaat, geschiedenis, PDF en reconstructie van die run. |
| Historie | Vastgelegd 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.
| Gegeven | Plaats | Reden |
|---|---|---|
| Vraagparameters en module-state | QuestionStateJsonBase64 | Verschilt per module en hoeft niet generiek querybaar te zijn. |
| Volgnummer | Uniform voortgangsveld | Nodig voor player, resultaatdetail en live meekijken. |
| Eerste toonmoment | Uniform voortgangsveld | Nodig voor timing en statistiek. |
| Beantwoordmoment | Uniform voortgangsveld | Nodig voor voortgang, geschiedenis en live meekijken. |
| Correct / fout | Uniform voortgangsveld | Nodig voor totalen en resultaatweergave. |
| Geen idee | Uniform voortgangsveld | Nodig voor uniforme telling en resultaatweergave. |
| Vraag afgerond | Uniform voortgangsveld | Nodig 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:
| Onderwerp | Regel |
|---|---|
| Doel | Controleren of configuratie, vraaggeneratie en weergave werken. |
| Actor | Bevoegde docent of collaborator binnen geldige context. |
| Runsoort | Testrun, niet reguliere leerlingrun. |
| Geschiedenis | Komt niet in normale leerlinggeschiedenis of docentresultaten. |
| Opslag | Mag tijdelijk voortgang opslaan zolang de test actief is. |
| Cleanup | Achtergebleven testruns worden periodiek opgeruimd volgens de geldende cleanupregels. |
| Autorisatie | Testen vervangt geen leerlingtoegang en publiceert de oefening niet. |
| Module | Module 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
TestDocenttoekennen; - 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
CodeReferencenaar 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:
| Scope | Betekenis | Mutatiegrens |
|---|---|---|
| Proefuitvoering | Precies één geselecteerde concrete oefening gecontroleerd migreren. | Eén oefening, één migratieregistratie en history voor die oefening. |
| Docentgericht | Actieve concrete oefeningen van één geselecteerde docent migreren. | Alleen oefeningen binnen de gekozen docentcontext die de bronmodule gebruiken. |
| Globaal | Alle 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:
ExerciseModuleIdkan 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:
ExerciseRunsworden niet herschreven;ExerciseRunProgresswordt niet herschreven;SharedExercisesen 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;
moduleKeyenschemaVersionin 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:
| Mutatie | Audit / history |
|---|---|
| Modulemetadata wijzigen | Actor, tijdstip, veld, oude waarde, nieuwe waarde en reden waar vereist. |
| Actiefstatus wijzigen | Actor, tijdstip, oude status, nieuwe status, reden en impactcontrole. |
| Testzichtbaarheid wijzigen | Actor, tijdstip, oude waarde, nieuwe waarde en reden waar vereist. |
| Connectiviteitstest | Technisch resultaat en tijdstip waar beheerdiagnose dit vereist. |
| Proefmigratie | Bronmodule, doelmodule, oefening, actor, tijdstip, reden en resultaat. |
| Docentgerichte migratie | Bronmodule, doelmodule, docentcontext, geraakte oefeningen, actor, tijdstip en reden. |
| Globale migratie | Bronmodule, doelmodule, scope, geraakte oefeningen, actor, tijdstip en reden. |
| Oefeningconfiguratie | ExerciseHistory 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;
CodeReferencekan niet gekoppeld worden aan modulecode;- configuratiepayload is ongeldig;
moduleKeypast niet bij verwachte modulefamilie;schemaVersionwordt 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
| Hoofdstuk | Relatie |
|---|---|
| Oefencatalogus, niveaus, categorieën en oefeningen | Beschrijft concrete oefeningen, categorieën, niveaus en leerlingzichtbaarheid. |
| Leerling: oefenen, voortgang en resultaten | Beschrijft run-lifecycle, beantwoorden, voortgang, resultaten en geschiedenis. |
| Gedeelde oefeningen | Gebruikt historische runpayloads en snapshots wanneer oefeningen gedeeld worden. |
| Docentfunctionaliteit | Beschrijft docentbeheer van oefenaanbod, configureren, testen en activeren. |
| Beheerderfunctionaliteit | Beschrijft centrale beheercontext en ondersteuning rond modules. |
| Live meekijken | Gebruikt server-side voortgang en renderbare modulevraagstate. |
| PDF-export en resultaatpresentatie | Gebruikt historische runcontext en module-renderhulp waar nodig. |
| Schermlaag en UX-specificaties | Beschrijft schermdocumentatie, popupkeys, read-only gedrag en foutafhandeling. |
| Functionele architectuurcontext | Plaatst module-interface en generieke engine in bredere architectuurcontext. |
22.38 Gerelateerde bronverwijzingen
| Bron | Link |
|---|---|
| Technisch Ontwerp — oefenmodulecontract | Oefenmodulecontract en dynamische module-integratie |
| Technisch Ontwerp — oefencatalogus | Oefencatalogus, niveaus, categorieën, oefeningen en modules |
| Technisch Ontwerp — oefenruns en payloads | Oefenruns, voortgang, resultaten, statistieken en PDF-brondata |
| FO — Oefencatalogus, niveaus, categorieën en oefeningen | Oefencatalogus |
| FO — Leerling: oefenen, voortgang en resultaten | Leerling oefenen |
| FO — Gedeelde oefeningen | Gedeelde oefeningen |
| FO — Docentfunctionaliteit | Docentfunctionaliteit |
| FO — Beheerderfunctionaliteit | Beheerderfunctionaliteit |
| FO — Live meekijken | Live meekijken |
| FO — PDF-export en resultaatpresentatie | PDF-export en resultaatpresentatie |
| Oefenmodules — intro | Oefenmodules |
| Oefenmodules — moduleplatform en contract | Moduleplatform en contract |
| Oefenmodule — Optellen & Aftrekken simpel | Optellen & Aftrekken simpel |
| Usecases docent — oefeningen configureren en testen | Oefeningen configureren en testen |
| UC-DOC-OEF-003 — Technische module selecteren | Technische module selecteren |
| UC-DOC-OEF-004 — Oefening configureren | Oefening configureren |
| UC-DOC-OEF-008 — Oefening testen als docent | Oefening testen als docent |
| Usecases beheerder — modules beheren | Modules beheren |
| UC-BEH-MOD-003 — Modulegegevens wijzigen | Modulegegevens wijzigen |
| UC-BEH-MOD-004 — Module-actiefstatus wijzigen | Module-actiefstatus wijzigen |
| UC-BEH-MOD-005 — Test-zichtbaarheid wijzigen | Test-zichtbaarheid wijzigen |
| UC-BEH-MOD-006 — Moduleconnectiviteit testen | Moduleconnectiviteit testen |
| UC-BEH-MOD-007 — Modulemigratie docentgericht uitvoeren | Modulemigratie docentgericht uitvoeren |
| UC-BEH-MOD-008 — Modulemigratie globaal uitvoeren | Modulemigratie globaal uitvoeren |
| UC-BEH-MOD-009 — Modulemigratie-proefuitvoering controleren | Modulemigratie-proefuitvoering controleren |
| UC-BEH-MOD-010 — Modulegeschiedenis bekijken | Modulegeschiedenis bekijken |
| Schermdocumentatie docent — nieuwe oefening | Nieuwe oefening |
| Schermdocumentatie beheerder — modules | Modules |
| Database-informatie — configuratie en contentbeheer | Configuratie en contentbeheer |
| Database-informatie — oefenruns, delen en voortgang | Oefenruns, delen en voortgang |
| Ontwerpbron — autorisatiematrix | Autorisatiematrix |
| Ontwerpbron — business rules | Business rules |
| Ontwerpbron — command-register | Command-register |
| Ontwerpbron — event-register | Event-register |