UC-LLN-HIS-002 — Geschiedenis filteren en pagineren
1. Kerngegevens
| Veld | Waarde |
|---|---|
| Usecase-ID | UC-LLN-HIS-002 |
| Naam | Geschiedenis filteren en pagineren |
| Domein | Leerling / Resultaten, statistieken, geschiedenis en PDF-export |
| Primaire actor | Leerling |
| Secundaire actor(en) | OefenHub frontend, OefenHub backend, database, technische oefenmodule |
| Rolcontext | Ingelogde leerling met een geldige leerlingcontext en toegang tot de eigen resultaat- of geschiedenisgegevens. |
| Betrokken schermen | Oefeninggeschiedenispagina, filterregel, paginering, geschiedenistabel, lege filterstaat. |
| Gerelateerde usecases | UC-LLN-HIS-001 — Oefeninggeschiedenis bekijken; UC-LLN-HIS-003 — Resultaatdetail vanuit geschiedenis openen; UC-LLN-HIS-004 — Geschiedenis alles bekijken |
| Primaire entiteiten | ExerciseRuns als gefilterd readmodel |
| Secundaire entiteiten / events | Filterparameters, pagineringsparameters, geschiedenisreadmodel |
| Gerelateerde popups | Niet van toepassing |
| Popupregister | Niet van toepassing; deze flow gebruikt routeguard-, leegstaat- of componentgedrag. |
| MoSCoW | Must |
2. Omschrijving
Deze usecase beschrijft hoe een leerling de oefeninggebonden geschiedenis filtert en door pagina's navigeert. De filter- en pagineringsinteractie werkt altijd binnen de reeds geautoriseerde geschiedenisdataset. Filters mogen de dataset beperken, maar nooit uitbreiden naar andere leerlingen, niet-toegankelijke niveaus of ongeautoriseerde oefeningcontexten. Paginering bepaalt uitsluitend welk deel van de geautoriseerde resultaten wordt getoond.
De usecase raakt geen brondata van exercise runs. Filterkeuzes, paginagrootte en pagina-index zijn presentatie- en queryparameters. Wanneer een filter geen resultaten oplevert, toont het systeem een normale lege staat.
Deze usecase is onderdeel van het leerlingdomein Resultaten, statistieken, geschiedenis en PDF-export. De flow gebruikt bestaande exercise-rungegevens, historische niveau-, categorie- en oefeningcontext en de uniforme resultaatvelden die tijdens oefenen en afronden zijn opgeslagen.
DRY-afbakening: deze usecase is niet de bron voor oefeninggeneratie, antwoordcontrole, statistiekberekening, autorisatiebeheer door docenten, relatievorming, profielbeheer of PDF-layoutregels buiten de eigen context. Waar die onderwerpen relevant zijn, verwijst de usecase naar de bestaande bronflows en centrale ontwerpbronnen.
3. Scope
Deze usecase omvat wel:
- wijzigen van periodefilter binnen oefeninggeschiedenis
- toepassen van filters binnen de geautoriseerde dataset
- kiezen van paginagrootte
- navigeren naar vorige, volgende of specifieke pagina
- tonen van actuele reeks en totaal aantal resultaten
- herladen van het gefilterde readmodel
- veilig afhandelen van lege filteruitkomsten
- veilig afhandelen van pagina's buiten bereik
- behouden van server-side autorisatie bij elke filterrequest
- terugkeren naar de lijst zonder domeinmutatie
Deze usecase omvat niet:
- initieel openen van de geschiedenispagina
- resultaatdetail openen
- PDF exporteren
- wijzigen van exercise-runbrondata
- aanmaken van gebruikersvoorkeuren voor filters
- docent- of ouderfilters
- zoeken over alle geschiedenis wanneer de usecase oefeninggebonden is
- verwijderen van geschiedenis
- toegang verlenen tot andere niveaus
- herberekenen van statistieken
4. Pre-condities
| ID | Voorwaarde |
|---|---|
| PRE-001 | De gebruiker is ingelogd als leerling. |
| PRE-002 | De server-side sessiecontext bevat een geldig intern Users.Id. |
| PRE-003 | De leerlingcontext is geldig en niet geblokkeerd door account- of routeguardafhandeling. |
| PRE-004 | De relevante run-, oefening-, categorie- of niveaugegevens bestaan of kunnen veilig als leeg resultaat worden afgehandeld. |
| PRE-005 | De backend kan de benodigde autorisatiecontrole uitvoeren op basis van de huidige gebruiker en historische runcontext. |
| PRE-006 | De betreffende feature voor geschiedenis/resultaatweergave is beschikbaar binnen de applicatie. |
| PRE-007 | De frontendroute is een geldige leerlingroute of wordt door routeguard geblokkeerd. |
| PRE-008 | Er is geen client-side identifier die zonder server-side validatie als autorisatiebron wordt gebruikt. |
5. Post-condities
| ID | Resultaat |
|---|---|
| POST-001 | De leerling krijgt uitsluitend geautoriseerde resultaat- of geschiedenisgegevens te zien. |
| POST-002 | De weergegeven dataset is server-side gefilterd op de ingelogde leerling en de toegestane context. |
| POST-003 | Er ontstaan geen nieuwe relaties, rollen, meldingen, privéberichten of systeemnotificaties. |
| POST-004 | Niet-toegankelijke of ontbrekende gegevens worden veilig geblokkeerd of als lege staat getoond. |
| POST-005 | Zoeken, filteren, openen of bekijken wijzigt geen brondata van de exercise run. |
| POST-006 | Navigatie naar resultaat, oefening of PDF verloopt via vervolgusecases. |
| POST-007 | De schermweergave gebruikt functioneel begrijpelijke labels en geen technische GUID's als primaire herkenning. |
| POST-008 | De zichtbare gegevens blijven consistent met de opgeslagen historische runcontext. |
6. Trigger
De usecase start wanneer de leerling op de oefeninggeschiedenispagina een periodefilter, paginagrootte of paginanavigatie kiest.
7. Normale processtroom
| Stap | Actor | Scherm / component | Actie | Systeemrespons | Data / regel |
|---|---|---|---|---|---|
| 1 | Leerling | Filterregel | Kiest een periodefilter. | Frontend markeert de filterkeuze als actief. | Afgelopen week, huidige maand, vorige maand, huidige jaar of alles. |
| 2 | OefenHub frontend | Geschiedenisroute | Stuurt filterparameter naar backend. | Backend start opnieuw autorisatie en query. | Filter is queryparameter. |
| 3 | OefenHub backend | Routeguard | Controleert sessie en leerlingcontext. | Alleen geldige leerlingcontext gaat door. | Server-side. |
| 4 | OefenHub backend | Geschiedenisservice | Herstelt de basale oefeningcontext. | Filter wordt toegepast binnen dezelfde context. | ExerciseId, CategoryId, LevelId. |
| 5 | OefenHub backend | Autorisatieservice | Controleert opnieuw inzagerecht. | Clientfilter kan geen toegang uitbreiden. | DRY met UC-LLN-HIS-001. |
| 6 | OefenHub backend | Querybuilder | Past periodefilter toe. | Alleen runs binnen gekozen periode blijven over. | CompletedAtUtc. |
| 7 | OefenHub backend | Querybuilder | Past vaste uitsluitingen toe. | Niet-afgeronde runs en testruns blijven uitgesloten. | Runstatus. |
| 8 | OefenHub backend | Paginering | Berekent totaal aantal gefilterde resultaten. | Frontend kan reeks tonen. | Count query. |
| 9 | OefenHub backend | Paginering | Bepaalt geldige pagina-index. | Pagina buiten bereik wordt gecorrigeerd of leeg getoond. | Bounds check. |
| 10 | OefenHub backend | Paginering | Past paginagrootte toe. | Alleen gevraagde pagina wordt opgehaald. | 20, 40, 60 of Alles waar toegestaan. |
| 11 | OefenHub backend | Geschiedenisservice | Laadt uniforme runvelden voor de pagina. | Tabelregels worden voorbereid. | Geen herberekening. |
| 12 | OefenHub backend | API response | Stuurt gefilterd readmodel terug. | Frontend ontvangt regels, totaal en paginering. | Readmodel. |
| 13 | OefenHub frontend | Filterregel | Toont actieve filter als actief en niet-klikbaar. | Leerling ziet gekozen filter. | UI-gedrag. |
| 14 | OefenHub frontend | Geschiedenistabel | Ververs de zichtbare regels. | Lijst sluit aan op gekozen filter. | Geen bronmutatie. |
| 15 | OefenHub frontend | Paginering | Toont actuele reeks. | Bijvoorbeeld 1-20 van 43. | Afgeleid totaal. |
| 16 | Leerling | Paginering | Kiest volgende pagina. | Frontend vraagt volgende pagina op. | Pagina-index. |
| 17 | OefenHub backend | Paginering | Herhaalt autorisatie en query voor pagina. | Dataset blijft begrensd. | Server-side. |
| 18 | OefenHub frontend | Geschiedenistabel | Toont nieuwe pagina. | Leerling ziet volgende reeks. | Geen mutatie. |
| 19 | Leerling | Paginagrootte | Kiest andere paginagrootte. | Frontend reset of corrigeert pagina-index. | Paginagrootte. |
| 20 | OefenHub backend | Paginering | Past nieuwe paginagrootte toe. | Nieuwe pagina-indeling wordt geleverd. | Querylimiet. |
| 21 | OefenHub frontend | Leegstaat | Toont lege filterstaat wanneer geen resultaten bestaan. | Geen foutmelding nodig. | Normale toestand. |
| 22 | Leerling | Geschiedenisoverzicht | Bekijkt de gefilterde lijst. | Er wordt niets opgeslagen in domeinbronnen. | Read-only. |
| 23 | OefenHub backend | Resultaat-/geschiedenisservice | Voert aanvullende consistentiecontrole 23 uit. | Alleen bruikbare gegevens gaan door naar de frontend. | Server-side afleiding. |
| 24 | OefenHub backend | Resultaat-/geschiedenisservice | Voert aanvullende consistentiecontrole 24 uit. | Alleen bruikbare gegevens gaan door naar de frontend. | Server-side afleiding. |
8. Alternatieve en exceptionele processtromen
| ID | Vanaf stap | Situatie | Systeemgedrag | Popup / melding | Datamutatie |
|---|---|---|---|---|---|
| ALT-001 | 2 | Onbekende filterwaarde | Backend negeert of weigert de waarde en gebruikt een veilige default. | Niet van toepassing | Geen |
| ALT-002 | 5 | Autorisatie vervallen tijdens filteren | Backend levert geen dataset meer terug. | Niet van toepassing | Geen |
| ALT-003 | 6 | Filter levert geen resultaten op | Frontend toont lege staat binnen dezelfde geschiedeniscontext. | Niet van toepassing | Geen |
| ALT-004 | 9 | Pagina-index buiten bereik | Backend corrigeert naar een geldige pagina of levert lege pagina met totaal. | Niet van toepassing | Geen |
| ALT-005 | 10 | Paginagrootte Alles bij zeer grote dataset | Systeem mag limiet of waarschuwing toepassen volgens centrale performanceregels. | Niet van toepassing | Geen |
| ALT-006 | 10 | Ongeldige paginagrootte | Backend valt terug op standaardwaarde. | Niet van toepassing | Geen |
| ALT-007 | 11 | Sortering ontbreekt | Backend gebruikt standaard sortering aflopend op afrondmoment. | Niet van toepassing | Geen |
| ALT-008 | 12 | Gelijktijdige datasetwijziging door technische opschoning | Totaal en pagina worden opnieuw berekend zonder fout voor de leerling. | Niet van toepassing | Geen |
| ALT-009 | 17 | Browser terugknop toont oude filterstand | Frontend herlaadt of valideert de stand opnieuw via backend. | Niet van toepassing | Geen |
| ALT-010 | 21 | Leegstaat na paginawissel | Frontend toont lege staat en blijft binnen veilige context. | Niet van toepassing | Geen |
9. Business rules
| ID | Regel |
|---|---|
| BR-001 | Geschiedenis toont alleen exercise runs waarvoor de ingelogde leerling server-side inzagerecht heeft. |
| BR-002 | Afgeronde leerlingruns blijven zichtbaar in geschiedenis, ook wanneer actuele oefening- of niveauautorisatie later wijzigt. |
| BR-003 | Niet-afgeronde runs verschijnen niet als afgeronde geschiedenisregel. |
| BR-004 | Docent-testruns worden niet als permanente leerlinggeschiedenis getoond. |
| BR-005 | Uniforme totalen en statistieken worden gelezen uit opgeslagen runvelden en niet telkens opnieuw uit de modulepayload berekend. |
| BR-006 | Technische identifiers zoals GUID's worden niet als herkenningsmiddel aan de leerling getoond. |
| BR-007 | Zoeken, filteren en pagineren wijzigen geen domeindata. |
| BR-008 | Een resultaatdetail mag alleen worden geopend voor een run die binnen de geautoriseerde leerlingcontext valt. |
| BR-009 | Historische niveau-, categorie- en oefeningcontext blijft leidend voor geschiedenisweergave. |
| BR-010 | PDF-download gebruikt dezelfde historisch opgeslagen runcontext als de resultaatweergave. |
| BR-011 | UC-LLN-HIS-002 gebruikt bestaande resultaat- en geschiedenisbronnen en maakt geen alternatieve bron van waarheid aan. |
| BR-012 | Wanneer actuele toegang is vervallen, blijft eerder afgeronde geschiedenis alleen zichtbaar voor zover historie volgens de bestaande regels bewaard mag blijven. |
| BR-013 | Browsergeschiedenis, URL-manipulatie en clientcache geven geen recht op extra resultaten of geschiedenis. |
| BR-014 | De frontend mag de dataset niet uitbreiden buiten de door backend geleverde geautoriseerde selectie. |
10. Datavalidatie
| Veld / object | Validatie |
|---|---|
| Periodefilter | Alleen ondersteunde filterwaarden worden geaccepteerd. |
| Paginagrootte | Alleen toegestane paginagroottes of Alles volgens centrale regels zijn geldig. |
| Pagina-index | Negatieve of niet-numerieke pagina-indexen worden geweigerd of gecorrigeerd. |
| Oefeningcontext | De filterquery blijft altijd gekoppeld aan dezelfde geautoriseerde oefeningcontext. |
| Leerlingcontext | De backend bepaalt de leerling vanuit sessiecontext. |
| Afrondmoment | Periodefilters gebruiken het opgeslagen afrondmoment van de run. |
| Testruns | Testruns blijven uitgesloten bij elk filter. |
| Niet-afgeronde runs | Niet-afgeronde runs blijven uitgesloten bij elk filter. |
| Totaal | Totaal aantal resultaten wordt afgeleid uit dezelfde gefilterde query. |
| Clientstate | Clientstate mag alleen queryparameters voorstellen en is geen autorisatiebron. |
11. Datamutaties en events
| Stap | Type | Entiteit / gegevensbron | Mutatie |
|---|---|---|---|
| 1 | Presentatie | Filterkeuze | De leerling kiest een filterwaarde binnen de bestaande dataset. |
| 2 | Read | Filterparameters | De backend ontvangt en valideert filter- en pagineringsparameters. |
| 6 | Read | ExerciseRuns | De gefilterde lijst van afgeronde eigen runs wordt gelezen. |
| 8 | Readmodel | Resultaattelling | Het aantal gefilterde resultaten wordt afgeleid. |
| 10 | Readmodel | Resultaatpagina | De gevraagde pagina met resultaten wordt opgebouwd. |
| 21 | Presentatie | Leegstaat | Een lege filteruitkomst wordt getoond zonder domeinmutatie. |
Filteren en pagineren zijn readmodelgedrag. Er worden geen functionele domeinevents geregistreerd en er wordt geen blijvende filtervoorkeur opgeslagen.
12. Geen datamutaties
| Entiteit | Reden |
|---|---|
ExerciseRuns | Filteren leest bestaande runs en wijzigt deze niet. |
UserSettings | Filterkeuze wordt in deze usecase niet als blijvende voorkeur opgeslagen. |
ExerciseRunProgress | Vraagvoortgang wordt niet gewijzigd. |
SystemMessages | Filteren veroorzaakt geen bericht. |
Tickets | Filteren veroorzaakt geen melding. |
UserRelationships | Relaties worden niet gewijzigd. |
TeacherStudentLevelAccess | Autorisaties worden niet gewijzigd. |
| PDF-bestand | Er wordt geen PDF aangemaakt. |
PrivateMessageThreads | Er wordt geen privébericht aangemaakt. |
| Frontendcache | Tijdelijke frontendcache is geen domeinbron. |
13. State diagram
Niet van toepassing als zelfstandig statusmodel. Deze usecase wijzigt geen persistent statusobject. De zichtbaarheid van geschiedenis en resultaten wordt afgeleid uit bestaande runvelden, accountcontext, autorisatiecontext en historische data.
14. Decision flow
15. Data lifecycle diagram
16. Sequence diagrammen
16.1 Hoofdroute
17. Popupverwijzingen
| PopupKey | Moment | Doel |
|---|---|---|
| Niet van toepassing | Filteren en pagineren | Ongeldige of lege filteruitkomsten worden in de pagina afgehandeld. |
18. Afleiding naar Functioneel Ontwerp / Technisch Ontwerp / Software Requirements Specification
| Doeldocument | Afleiding |
|---|---|
| Functioneel Ontwerp | Functioneel Ontwerp beschrijft geschiedenis, filters, resultaatdetail, statistieken, opnieuw maken en PDF-download vanuit leerlingcontext. |
| Technisch Ontwerp | Technisch Ontwerp: oefenruns en resultaten, PDF-export, readmodels en tellers, frontend-resultaatweergave en privacy/retentie beschrijft de technische afbakening, server-side brondata, autorisatie en UI-compositie voor deze usecase. |
| Software Requirements Specification | Software Requirements Specification bevat centrale eisen en acceptatiecriteria voor resultaten, geschiedenis, statistieken, PDF-export en autorisatie op historische data. |
| Database-informatie | Database-informatie blijft bron voor runresultaten, voortgangsrecords, snapshots en exportbrondata; normale PDF-downloads introduceren geen permanente PDF-tabel. |
| Ontwerpbronnen | Ontwerpbronnen bevatten aanvullende businessregels voor resultaatweergave, geschiedenis, statistieken en exportrepresentatie. |
19. SRS-trace
Deze usecase bevat geen normatieve requirementtekst. De centrale eis en acceptatiecriteria staan in de SRS; onderstaande tabel koppelt de usecase-afleiding alleen aan centrale SRS-*- en AC-*-items.
| Usecase-afleiding | Dekt | Usecasecontext |
|---|---|---|
REQ-UC-LLN-HIS-002-001 | SRS-RDM-001 SRS-RDM-006 SRS-LRN-010 SRS-NFR-AUD-001 AC-RDM-001 AC-RDM-006 AC-LRN-010 AC-NFR-AUD-001 | Geschiedenis kunnen filteren op ondersteunde periodefilters |
REQ-UC-LLN-HIS-002-002 | SRS-AUTH-001 SRS-RDM-001 SRS-LRN-009 AC-AUTH-001 AC-RDM-001 AC-LRN-009 | Filteren altijd server-side binnen de geautoriseerde dataset uitvoeren |
REQ-UC-LLN-HIS-002-003 | SRS-RDM-001 SRS-RDM-009 SRS-LRN-009 SRS-NFR-SEC-001 AC-RDM-001 AC-RDM-009 AC-LRN-009 AC-NFR-SEC-001 | Ongeldige filterwaarden veilig afhandelen |
REQ-UC-LLN-HIS-002-004 | SRS-RDM-001 SRS-RDM-006 SRS-LRN-010 SRS-NFR-AUD-001 SRS-NFR-PER-001 AC-RDM-001 AC-RDM-006 AC-LRN-010 AC-NFR-AUD-001 AC-NFR-PER-001 | Paginering ondersteunen voor geschiedenisresultaten |
REQ-UC-LLN-HIS-002-005 | SRS-RDM-001 SRS-RDM-002 SRS-LRN-009 AC-RDM-001 AC-RDM-002 AC-LRN-009 | De actuele reeks en het totaal aantal gefilterde resultaten kunnen tonen |
REQ-UC-LLN-HIS-002-006 | SRS-RDM-001 SRS-LRN-009 AC-RDM-001 AC-LRN-009 | Lege filteruitkomsten als normale lege staat tonen |
REQ-UC-LLN-HIS-002-007 | SRS-AUTH-001 SRS-RDM-001 SRS-RDM-005 SRS-LRN-009 AC-AUTH-001 AC-RDM-001 AC-RDM-005 AC-LRN-009 | Filteren en pagineren niet gebruiken om de autorisatiecontext uit te breiden |
REQ-UC-LLN-HIS-002-008 | SRS-RDM-001 SRS-RDM-006 SRS-LRN-008 AC-RDM-001 AC-RDM-006 AC-LRN-008 | Niet-afgeronde runs en testruns bij elk filter uitgesloten houden |
REQ-UC-LLN-HIS-002-009 | SRS-AUTH-001 SRS-RDM-001 SRS-RDM-009 SRS-LRN-009 SRS-NFR-SEC-001 AC-AUTH-001 AC-RDM-001 AC-RDM-009 AC-LRN-009 AC-NFR-SEC-001 | Pagina's buiten bereik veilig corrigeren of blokkeren |
REQ-UC-LLN-HIS-002-010 | SRS-RDM-001 SRS-RDM-006 SRS-LRN-009 AC-RDM-001 AC-RDM-006 AC-LRN-009 | Bij filteren en pagineren geen exercise-rundata wijzigen |