1. Moduleplatform en contract
1.1 Doel van dit hoofdstuk
Dit hoofdstuk beschrijft de generieke uitgangspunten voor technische oefenmodules binnen OefenHub. De afzonderlijke moduledossiers, zoals Optellen & Aftrekken (simpel), beschrijven daarna alleen nog de module-specifieke configuratie, leerlingweergave, states en JSON-invulling.
Technische modules zijn uitbreidbare oefencomponenten. Zij leveren de inhoudelijke logica voor een oefening, terwijl de generieke OefenHub-engine verantwoordelijk blijft voor autorisatie, opslag, navigatie, voortgang, geschiedenis, resultaten, PDF-export en live meekijken.
Dit hoofdstuk voorkomt dat dezelfde basisregels per module opnieuw worden uitgewerkt.
1.2 Afbakening
Een technische module is niet hetzelfde als een concrete oefening.
| Begrip | Betekenis |
|---|---|
| Technische module | Herbruikbare codecomponent/library die configuratie, vraaggeneratie, validatie en rendering levert. |
| Concrete oefening | Door een docent aangemaakte oefening op basis van precies één technische module. |
| Practice / exercise run | Eén door een leerling of docent gestarte uitvoering van een concrete oefening. |
| Configuratiepayload | Module-specifieke instellingen van een concrete oefening, generiek opgeslagen bij de oefening. |
| Vraagpayload | Module-specifieke vraag- en antwoorddata binnen een exercise run. |
1.3 Generieke uitgangspunten
Voor alle technische modules gelden de volgende uitgangspunten:
- Een concrete oefening verwijst altijd naar precies één
ExerciseModules-record. - Beschikbare modules worden administratief beheerd via
ExerciseModules. - De modulelijst in de docentflow is databasegedreven.
- De modulebeschrijving, configuratiecomponent en modulespecifieke leerlingweergave komen runtime uit de technische module/library.
- De generieke applicatie slaat configuratie en vraagdata op als payload, zonder alle modulevelden relationeel uit te splitsen.
- Modules leveren inhoudelijke validatie; de generieke engine verzorgt opslag, voortgang, navigatie en autorisatie.
- Een nieuw aangemaakte oefening start standaard in status In onderhoud.
- Moduleconfiguraties moeten versieerbaar zijn, zodat latere migratie of backwards compatibility mogelijk blijft.
1.4 Relatie met docentflow Nieuwe oefening
De docentflow Nieuwe oefening toevoegen bestaat generiek uit twee stappen:
-
Module kiezen
De docent kiest een technische module uit de databasegedreven lijst met beschikbare modules. -
Module configureren
De generieke container opent de configuratiecomponent van de gekozen module. De inhoud van deze configuratie is module-specifiek, maar opslaan verloopt via dezelfde generieke opslagactie.
Deze opzet betekent dat de generieke docentflow niet aangepast hoeft te worden voor iedere nieuwe oefenmodule, zolang de module voldoet aan het centrale modulecontract.
1.5 Verantwoordelijkheden
1.5.1 Verantwoordelijkheid technische module
Een technische module levert minimaal:
- een stabiele technische sleutel;
- een configuratieschemaversie;
- een beschrijvingscomponent voor de modulekeuze;
- een docentconfiguratiecomponent;
- een configuratie-DTO of schema;
- validatie van de configuratie;
- vraaggeneratie op basis van configuratie;
- antwoordvalidatie;
- leerling-rendering voor de vraag;
- feedbackstate voor correct en fout;
- optioneel renderhulp voor resultaatweergave, history en PDF-export.
1.5.2 Verantwoordelijkheid generieke OefenHub-engine
De generieke engine levert minimaal:
- ophalen van beschikbare modules uit
ExerciseModules; - openen van de juiste modulecomponent via strategy/factory;
- centrale opslag van
Exercises; - koppeling van oefening aan niveau/categorie;
- opslag van configuratiepayload;
- starten en hervatten van
ExerciseRuns; - opslag van vraagvoortgang na iedere bevestigde stap;
- berekening en opslag van uniforme runstatistieken;
- geschiedenis, resultaatweergave, PDF-export en live meekijken;
- autorisatiecontrole voor docent, collaborator, leerling en meekijker.
1.6 Modulecontract
Elke technische module moet functioneel voldoen aan een generiek contract. De exacte technische interface kan later in code worden uitgewerkt, maar functioneel moet minimaal onderstaande informatie beschikbaar zijn.
| Onderdeel | Verantwoordelijke laag | Doel |
|---|---|---|
| Module metadata | Module + ExerciseModules | Module herkenbaar en selecteerbaar maken. |
| Beschrijving | Module | Docent informeren vóór configuratie. |
| Configuratie UI | Module | Docent laat module-specifieke instellingen invullen. |
| Configuratievalidatie | Module | Controleren of instellingen inhoudelijk uitvoerbaar zijn. |
| Configuratieopslag | Engine | Payload opslaan bij concrete oefening. |
| Vraaggeneratie | Module | Vragen maken op basis van configuratie. |
| Vraagopslag | Engine | Gegenereerde vraagdata bewaren in runpayload. |
| Antwoordvalidatie | Module | Antwoord beoordelen als goed, fout of eventueel geen idee. |
| Voortgang | Engine | Vraagstatus, runstatus en totalen bijwerken. |
| Feedbackrendering | Module + Engine | State correct/fout tonen binnen generieke player. |
| Resultaat/history | Engine + optionele module renderhulp | Historische resultaten reproduceerbaar tonen. |
1.7 Strategy pattern en runtime laden
OefenHub gebruikt functioneel een strategy/factory-achtige opzet om technische modules dynamisch te laden.
De database bepaalt welke module beschikbaar is en welke technische sleutel daarbij hoort. De module-library bepaalt hoe die module zich gedraagt.
Minimale flow:
- De docent kiest een record uit
ExerciseModules. - De generieke engine gebruikt de technische referentie om de juiste module-strategy te vinden.
- De module levert de beschrijving en configuratiecomponent.
- Bij opslaan valideert de module de configuratie.
- De engine slaat de concrete oefening en configuratiepayload op.
- Bij starten van een run laadt de engine opnieuw de module-strategy.
- De module genereert vragen en valideert antwoorden.
- De engine bewaart voortgang en uniforme totalen.
Modules mogen de generieke autorisatie-, opslag- en navigatieregels niet omzeilen.
1.8 Configuratiepayload
Modulespecifieke configuratie wordt generiek opgeslagen als payload bij de concrete oefening. Deze payload moet versieerbaar en uitbreidbaar zijn.
Minimale structuur:
{
"moduleKey": "VoorbeeldModule_v1",
"schemaVersion": "1.0",
"display": {
"exerciseName": "Voorbeeld oefening",
"icon": "example"
},
"configuration": {},
"runtimeOptions": {
"allowMarkAsDunno": true,
"showAnswerAfterSubmit": true
}
}
De exacte inhoud van configuration is eigendom van de technische module. De generieke engine hoeft deze inhoud niet relationeel te begrijpen, maar moet de payload wel kunnen opslaan, teruggeven, historisch bewaren en aan de juiste module aanbieden.
1.9 Leerling runtime model
De leerlingweergave van modules werkt state-based. Alternatieve weergaven zoals input, correct antwoord en fout antwoord zijn states binnen dezelfde view en geen aparte schermroutes.
Minimale states:
| State | Betekenis |
|---|---|
| Input | Vraag wordt getoond en leerling kan antwoord invullen. |
| Correct | Antwoord is bevestigd en goed beoordeeld. |
| Incorrect | Antwoord is bevestigd en fout beoordeeld. |
| Dunno | Leerling gebruikt Geen idee, wanneer toegestaan. |
| Completed | Laatste vraag is afgerond en resultaat kan worden geopend. |
De generieke player regelt de overgang tussen states, maar de module levert de inhoudelijke vraagweergave en validatie.
1.10 Opslag en voortgang
Na iedere bevestigde antwoordstap moet de voortgang server-side worden opgeslagen. Dit is nodig voor:
- hervatten van onderbroken oefeningen;
- geschiedenis;
- resultaatweergave;
- PDF-export;
- live meekijken;
- betrouwbare runstatistieken.
De uniforme runvelden blijven leidend voor snelle uitlezing. Modulepayloads blijven beschikbaar voor detailweergave, reconstructie en module-specifieke rendering.
1.11 UI-elementen en velddefinities
| Element-ID | Type | GUI-verwijzing | Omschrijving | Zichtbaar label | Opmerking | Technische naam |
|---|---|---|---|---|---|---|
| SCH-MOD-00-01-S01 | S | Modulekeuze | Generieke sectie waarin beschikbare technische modules worden getoond. | Beschikbare modules | Databasegedreven lijst. | ModuleSelectionSection |
| SCH-MOD-00-01-T01 | T | Modulekeuze | Tabel/lijst met selecteerbare modules. | Beschikbare modules | Gebaseerd op ExerciseModules. | AvailableModulesList |
| SCH-MOD-00-01-F01 | F | Modulelijst | Technische referentie van module. | Technische referentie | Read-only. | ModuleCodeReference |
| SCH-MOD-00-01-F02 | F | Modulelijst | Functionele weergavenaam. | Weergavenaam | Read-only. | ModuleDisplayName |
| SCH-MOD-00-01-A01 | A | Modulelijst | Selecteert module. | Module selecteren | Runtime selectie. | SelectModuleAction |
| SCH-MOD-00-01-S02 | S | Moduledetail | Beschrijving van geselecteerde module. | Detailoverzicht geselecteerde module | Komt uit module-library. | ModuleDescriptionSection |
| SCH-MOD-00-01-B01 | B | Moduledetail | Opent configuratiecontainer. | Selecteer en configureer | Alleen actief na modulekeuze. | OpenModuleConfigurationButton |
| SCH-MOD-00-01-MOD01 | MOD | Configuratiecontainer | Generieke container waarin moduleconfiguratie wordt geladen. | Module configureren | Inhoud is module-specifiek. | ModuleConfigurationContainer |
| SCH-MOD-00-01-FORM01 | FORM | Configuratiecontainer | Module-specifieke configuratiecontext. | n.v.t. | Wordt geleverd door module. | ModuleConfigurationForm |
| SCH-MOD-00-01-B02 | B | Configuratiecontainer | Terug naar moduleoverzicht. | Terug naar overzicht | Sluit zonder opslaan. | BackToModuleOverviewButton |
| SCH-MOD-00-01-B03 | B | Configuratiecontainer | Slaat oefening op. | Opslaan en toevoegen | Centrale opslagactie. | SaveExerciseButton |
| SCH-MOD-00-01-S03 | S | Leerlingplayer | Generieke oefencontainer voor leerling. | Oefening | Enginecontainer. | StudentExercisePlayer |
| SCH-MOD-00-01-F03 | F | Leerlingplayer | Modulevraagweergave. | Module-afhankelijk | Komt uit module. | ModuleQuestionRenderOutput |
| SCH-MOD-00-01-F04 | F | Leerlingplayer | Antwoordinvoer. | Module-afhankelijk | Komt uit module of generieke inputcomponent. | StudentAnswerInput |
| SCH-MOD-00-01-M01 | M | Leerlingplayer | Feedback na beantwoording. | Goed / fout / geen idee | State-afhankelijk. | AnswerFeedbackMessage |
| SCH-MOD-00-01-B04 | B | Leerlingplayer | Bevestigt antwoord of navigeert verder. | Volgende vraag / Toon antwoord / Bekijk resultaat | Tekst afhankelijk van runstate. | NextStepButton |
1.12 Waardelagen
| Element-ID | GUI-verwijzing | Zichtbaar label | Technische naam | Databron | Waardebron | Datatype | Bewerkbaar | Validatie / regel |
|---|---|---|---|---|---|---|---|---|
| SCH-MOD-00-01-T01 | Modulekeuze | Beschikbare modules | AvailableModulesList | ExerciseModules | Query op actieve/beschikbare technische modules | Collectie | Nee, selectie wel | Alleen modules die functioneel beschikbaar zijn mogen worden getoond. |
| SCH-MOD-00-01-F01 | Modulelijst | Technische referentie | ModuleCodeReference | ExerciseModules.CodeReference | Databasewaarde | String | Nee | Moet uniek genoeg zijn voor strategy-resolutie. |
| SCH-MOD-00-01-F02 | Modulelijst | Weergavenaam | ModuleDisplayName | ExerciseModules.DisplayName | Databasewaarde | String | Nee | Functionele naam voor docent. |
| SCH-MOD-00-01-S02 | Moduledetail | Detailoverzicht geselecteerde module | ModuleDescriptionSection | Geen primaire databasebron | Runtime output van module-library / strategy | Component-output | Nee | Moet passen bij gekozen module. |
| SCH-MOD-00-01-MOD01 | Configuratiecontainer | Module configureren | ModuleConfigurationContainer | Geen zelfstandige persistente bron | Runtime state op basis van geselecteerde module | UI-state | Nee | Mag pas openen na geldige modulekeuze. |
| SCH-MOD-00-01-FORM01 | Configuratiecontainer | n.v.t. | ModuleConfigurationForm | Exercises.ConfigurationPayload | Modulecomponent + directe docent-invoer | Form object / payload | Ja | Moet door module gevalideerd worden. |
| SCH-MOD-00-01-B03 | Configuratiecontainer | Opslaan en toevoegen | SaveExerciseButton | Exercises, TeacherLevelCategoryExercises, ExerciseHistory | Centrale submitactie | Command | Ja | Maakt concrete oefening aan en koppelt deze aan huidige categoriecontext. |
| SCH-MOD-00-01-S03 | Leerlingplayer | Oefening | StudentExercisePlayer | ExerciseRuns | Runtime runcontext | UI-container | Nee | Alleen toegankelijk bij geldige leerlingautorisatie. |
| SCH-MOD-00-01-F03 | Leerlingplayer | Module-afhankelijk | ModuleQuestionRenderOutput | ExerciseRuns vraagpayload | Door module gegenereerde vraagdata | Component-output | Nee | Vraagdata moet historisch reproduceerbaar blijven. |
| SCH-MOD-00-01-F04 | Leerlingplayer | Module-afhankelijk | StudentAnswerInput | ExerciseRuns voortgangspayload | Leerlinginvoer | Module-afhankelijk | Ja | Antwoord moet door module gevalideerd kunnen worden. |
| SCH-MOD-00-01-M01 | Leerlingplayer | Goed / fout / geen idee | AnswerFeedbackMessage | Geen zelfstandige primaire bron | Validatieresultaat module + runstate | Informatiemelding | Nee | Alleen zichtbaar wanneer feedbackstate actief is. |
| SCH-MOD-00-01-B04 | Leerlingplayer | Volgende vraag / Toon antwoord / Bekijk resultaat | NextStepButton | ExerciseRuns voortgang | Command op huidige vraagstate | Action | Ja | Slaat voortgang op na iedere bevestigde stap. |
1.13 Moduleplatform-eisen en SRS-koppeling
Deze tabel bevat bijzondere module-eisen voor het generieke moduleplatform. Zij zijn geen gewone schermrequirements en ook geen extra centrale SRS-*-requirements. De eisen beschrijven het generieke moduleplatform en het contract waaraan iedere technische oefenmodule moet voldoen. De centrale dekking staat in het oefenmodule-eisenregister.
| Module-eis | Classificatie | Omschrijving |
|---|---|---|
| REQ-SCH-MOD-00-01 | Moduleplatform-eis | Het systeem moet technische modules administratief kunnen registreren in ExerciseModules. |
| REQ-SCH-MOD-00-02 | Moduleplatform-eis | Het systeem moet een databasegedreven lijst van beschikbare modules kunnen tonen in de docentflow. |
| REQ-SCH-MOD-00-03 | Moduleplatform-eis | Per module moeten minimaal technische referentie en functionele weergavenaam beschikbaar zijn. |
| REQ-SCH-MOD-00-04 | Moduleplatform-eis | Het systeem moet op basis van een gekozen module de juiste strategy/library kunnen laden. |
| REQ-SCH-MOD-00-05 | Modulecontract-eis | Een technische module moet een beschrijvingscomponent kunnen leveren voor de modulekeuze. |
| REQ-SCH-MOD-00-06 | Modulecontract-eis | Een technische module moet een docentconfiguratiecomponent kunnen leveren. |
| REQ-SCH-MOD-00-07 | Modulecontract-eis | Een technische module moet een configuratieschema of configuratie-DTO kunnen leveren. |
| REQ-SCH-MOD-00-08 | Modulecontract-eis | Een technische module moet module-specifieke configuratie kunnen valideren. |
| REQ-SCH-MOD-00-09 | Moduleplatform-eis | De generieke engine moet gevalideerde configuratie als payload kunnen opslaan bij Exercises. |
| REQ-SCH-MOD-00-10 | Moduleplatform-eis | Een concrete oefening moet altijd verwijzen naar precies één ExerciseModules-record. |
| REQ-SCH-MOD-00-11 | Moduleplatform-eis | Een nieuwe oefening moet na opslaan gekoppeld worden aan de actuele niveau-/categoriecontext. |
| REQ-SCH-MOD-00-12 | Moduleplatform-eis | Een nieuw aangemaakte oefening moet standaard starten in status In onderhoud. |
| REQ-SCH-MOD-00-13 | Modulecontract-eis | Een technische module moet vragen kunnen genereren op basis van de opgeslagen configuratiepayload. |
| REQ-SCH-MOD-00-14 | Modulecontract-eis | De generieke engine moet gegenereerde vraagdata kunnen opslaan binnen een exercise run. |
| REQ-SCH-MOD-00-15 | Modulecontract-eis | Een technische module moet leerlingantwoorden kunnen valideren. |
| REQ-SCH-MOD-00-16 | Modulecontract-eis | De leerlingplayer moet input-, correct-, fout- en eventuele geen-idee-states kunnen ondersteunen. |
| REQ-SCH-MOD-00-17 | Moduleplatform-eis | De generieke engine moet voortgang server-side opslaan na iedere bevestigde antwoordstap. |
| REQ-SCH-MOD-00-18 | Moduleplatform-eis | Het systeem moet onderbroken exercise runs kunnen hervatten op basis van opgeslagen voortgang. |
| REQ-SCH-MOD-00-19 | Modulecontract-eis | Modulepayloads moeten historisch beschikbaar blijven voor resultaten, geschiedenis en PDF-export. |
| REQ-SCH-MOD-00-20 | Moduleplatform-eis | Modules mogen de generieke autorisatie-, opslag- en navigatieregels niet omzeilen. |
| REQ-SCH-MOD-00-21 | Modulecontract-eis | Het modulecontract moet schemaVersion ondersteunen voor backwards compatibility en migratie. |
| REQ-SCH-MOD-00-22 | Moduleplatform-eis | Live meekijken moet kunnen steunen op server-side opgeslagen voortgang, niet op uitsluitend clientstate. |
| REQ-SCH-MOD-00-23 | Moduleplatform-eis | De generieke engine moet uniforme runstatistieken kunnen opslaan onafhankelijk van de modulepayload. |
| REQ-SCH-MOD-00-24 | Modulecontract-eis | Module-specifieke rendering mag optioneel ondersteuning leveren voor resultaatweergave en PDF-export. |