Skip to main content

Architectuur

Dit onderdeel beschrijft de vastgelegde hoofdarchitectuur van OefenHub. De architectuurdocumentatie maakt zichtbaar hoe de applicatie op hoofdlijnen is opgebouwd, waar de systeemgrens ligt, welke externe afhankelijkheden bestaan en welke technische keuzes als uitgangspunt gelden voor verdere uitwerking.

Doel van dit onderdeel

De architectuurdocumentatie heeft drie hoofddoelen:

  • het vastleggen van de gekozen hoofdarchitectuur van OefenHub;
  • het zichtbaar maken van de systeemgrens, externe systemen, containers en belangrijkste componentgroepen;
  • het bieden van een stabiele basis voor het latere Technisch Ontwerp.

De architectuurdocumentatie vervangt het Functioneel Ontwerp, de Software Requirements Specification of de database-informatielaag niet. Zij beschrijft de technische structuur en samenhang waarmee de functionele baseline en requirements technisch kunnen worden geplaatst.

Inhoudsopgave

Opbouw

De architectuurdocumentatie gebruikt het C4-model als ordeningsprincipe:

  • C4 niveau 1 beschrijft de systeemcontext van OefenHub.
  • C4 niveau 2 beschrijft de hoofdcontainers en externe technische afhankelijkheden.
  • C4 niveau 3 beschrijft de belangrijkste componentgroepen binnen de OefenHub-webapplicatie.
  • C4 niveau 4 beschrijft interne bouwblokken op hoog-over niveau, zonder code-implementatie of klassendiagrammen als normatieve bron te maken.

Diagrammen worden in de documentatie tekstueel en/of via DSL-bronnen beschreven. Gerenderde afbeeldingen kunnen als apart publicatie-artefact worden beheerd en zijn niet de primaire bron van architectuurwaarheid.

Scope en afbakening

De architectuurdocumentatie beschrijft de structuur, systeemgrenzen, technische hoofdkeuzes en onderlinge samenhang van OefenHub. De volgende afbakening geldt:

  • Het Functioneel Ontwerp is leidend voor functioneel gedrag, rollen, domeinregels, flows en schermcontext.
  • De Software Requirements Specification is leidend voor centrale requirements, prioriteiten, acceptatiecriteria en traceability.
  • De database-informatielaag beschrijft de relationele gegevensstructuur en vormt input voor het Technisch Ontwerp.
  • Het Technisch Ontwerp werkt later implementatiedetails uit, zoals services, queries, indexes, caching, background jobs, deployment, monitoring en technische teststrategie.
  • Deze architectuurdocumentatie bevat geen volledige ERD, geen database-DDL, geen uitgewerkte API-specificatie en geen codeontwerp op class-niveau.

Brondocumenten

  • Functioneel Ontwerp: functionele baseline, domeinregels, rollen, lifecycle en schermcontext.
  • Software Requirements Specification: centrale requirements, acceptatiecriteria, prioriteiten en traceability.
  • Database-informatielaag: gegevensstructuur, tabellen, relaties, enums en technische datagrondslag.
  • Oefenmodule-documentatie: moduleplatform, modulecontract en concrete module-eisen.

Architectuuruitgangspunten

  • OefenHub wordt als middel-zware modulaire monoliet opgezet.
  • Authenticatie, registratie, sessies en credential-lifecycle liggen bij Keycloak als externe identity provider.
  • OefenHub gebruikt een eigen interne identiteit naast een externe identity-koppelsleutel.
  • Desktop en tablet zijn leidend; smartphonegebruik is geen primair ondersteund gebruiksscenario.
  • De database is niet internet-facing en wordt alleen via de backend/webserver benaderd.
  • Er is geen publieke functionele API-laag voor externe clients of mobiele apps; primaire interactie verloopt via de webapp.
  • MudBlazor is de gekozen componentenbibliotheek voor de interactieve Blazor Web UI, maar OefenHub hanteert een eigen herbruikbare componenten- en themelaag bovenop MudBlazor.
  • Realtime communicatie verloopt centraal via SignalR.
  • Background jobs, cleanup en tijdsafhankelijke afhandeling verlopen binnen de modulaire monoliet via TickerQ.
  • Gestructureerde logging verloopt via Serilog; Seq wordt ingezet als centrale logviewer.
  • QuestPDF is de gekozen oplossing voor document- en PDF-generatie.
  • Oefenmodules worden via een strategy/plugin-achtig model aangesloten en via beheer gecontroleerd beschikbaar gemaakt.
  • Relationele kerngegevens worden gecombineerd met modulespecifieke JSON/base64-payloads voor oefenconfiguratie, vragen en voortgang.

Betekenis van middel-zware modulaire monoliet

Met middel-zware modulaire monoliet wordt bedoeld dat OefenHub als één deploybare .NET/Blazor-webapplicatie wordt gebouwd, maar intern niet als één ongestructureerd codeblok wordt georganiseerd. Functionele domeinen zoals identiteit, autorisatie, relaties, catalogus, oefenen, communicatie, support, live meekijken, beheer, rapportage en scheduling krijgen duidelijke project- en modulegrenzen.

Deze keuze betekent concreet:

  • er is één applicatieproces en één primaire relationele database in de eerste baseline;
  • modulegrenzen worden afgedwongen via projectstructuur, publieke contracten, internal implementaties, architecture tests en module-eigen DbContexts/schema's;
  • domeinmodules gebruiken elkaars interne entities, DbContexts en implementatieclasses niet rechtstreeks;
  • cross-module gegevensverwijzingen gebruiken standaard publieke contracten, queryservices, soft links of snapshots;
  • de architectuur vermijdt de operationele complexiteit van microservices, maar houdt de codebase voorbereid op onderhoud, testbaarheid en latere afsplitsing wanneer dat ooit nodig wordt.

De term monoliet beschrijft dus deployment en runtime. De term modulair beschrijft de interne structuur en eigenaarschapgrenzen.

Beslissingenregister

IDBeslissingRedenNiet gekozen alternatief
ADR-001Middel-zware modulaire monoliet in de eerste productfaseBeperkte operationele complexiteit, één team/context, expliciete interne modulegrenzen en geen harde schaal- of beschikbaarheidseis voor microservices.Microservices of één ongestructureerde monoliet
ADR-002Keycloak als externe identity providerAuth, registratie, sessies en credentialbeheer buiten OefenHub houden.Eigen auth-systeem in OefenHub
ADR-003Geen smartphonegerichte ondersteuning als primair gebruiksscenarioDesktop en tablet zijn leidend; mobiele weergave is functioneel niet geschikt voor de primaire oefenervaring.Volledige mobiele optimalisatie
ADR-004Directe anonimisatie bij accountverwijderingDataminimalisatie, consistente lifecycle en behoud van domeinhistorie.Tussenstatus 'verwijderd maar nog niet geanonimiseerd'
ADR-005Database niet internet-facingKleiner aanvalsoppervlak en duidelijke infrastructuurscheiding.Directe publieke databaseblootstelling
ADR-006Geen publieke functionele API-laagDe primaire interactie loopt via de webapp; dit houdt de systeemgrens en integratiestrategie bewust compact.Publieke functionele API voor externe clients of mobiele app
ADR-007Hybride persistentiestijl voor oefeningen en runsUniforme, querybare metadata blijven relationeel; modulespecifieke configuratie en toestand blijven flexibel in JSON/base64.Volledig relationeel model of volledig blob-only opslagmodel
ADR-008Technische oefenmodules via strategy/plugin-achtig model en databasegestuurd vrijgevenHoudt generieke platformlogica gescheiden van modulespecifieke implementaties en maakt gecontroleerde modulevrijgave mogelijk.Hardcoded oefenlogica of automatische runtime-discovery zonder beheervrijgave
ADR-009SignalR als centrale realtime-mechaniekOndersteunt live meekijken, online-status en directe voortgangsupdates via één consistent realtimekanaal.Polling of versnipperde realtime-oplossingen per domein
ADR-010TickerQ voor background jobs en cleanupMaakt tijdsafhankelijke afhandeling, retries en opschoning beheersbaar binnen de modulaire monolithische webapp.Ad-hoc timers, handmatige cleanup of losse scheduler zonder centrale governancelaag
ADR-011Frontend-context runtime samengesteld en layout codegedrevenMulti-role context, frontpage-opbouw en schermkeuze blijven in code beheersbaar; inhoud is wel databasegestuurd.Persistent contextmodel per rolcombinatie of vrije pagebuilder/CMS-opbouw
ADR-012Browserlokale client-state waar passendOndersteunt pre-login toegankelijkheid en once-per-browser notificatiegedrag zonder onnodig server-side readmodel.Alles gebruikersgebonden server-side opslaan
ADR-013Communicatiedomeinen expliciet gescheidenMailboxgerichte systeemberichten, site-notificaties, privéberichten en tickets volgen verschillende lifecycle- en deliverypatronen.Eén generiek communicatiemodel voor alle berichtsoorten
ADR-014UTC intern, lokale tijd in presentatieVoorkomt inconsistentie in schedulerlogica, historie, meldingen en audit.Lokale tijd opslaan of vergelijken in backendlogica
ADR-015Blazor Web App als gekozen webmodelSluit aan op de gekozen modulaire monoliet-aanpak en de gewenste rijke, maar gecontroleerde interactielaag.Klassieke server-rendered webapp als primair model
ADR-016Serilog + Seq voor gestructureerde loggingVergroot herleidbaarheid en vereenvoudigt troubleshooting door structurele logging en centrale inzage.Ongestructureerde logging of uitsluitend lokale/logfile-gebaseerde inzage
ADR-017QuestPDF voor document- en PDF-generatieBiedt een vaste, programmeerbare en reproduceerbare route voor PDF-uitvoer vanuit historisch consistente brondata.Browser print/HTML-export of losse documentgeneratie zonder vaste library
ADR-018Profielavatars via vaste setBeperkt moderatie- en beveiligingslast en houdt profielweergave uniform.Vrije uploads van profielafbeeldingen
ADR-019Live-view audit sessiegebaseerdLegt meekijken herleidbaar vast met beheersbaar datavolume en duidelijke start/eindsemantiek.Per realtime event volledig auditen
ADR-020Docent-testruns tijdelijk en opschoonbaarHoudt testgedrag gescheiden van reguliere leerlinghistorie en beperkt blijvende vervuiling van domeindata.Permanente opslag in dezelfde lifecycle als reguliere runs
ADR-021Aspire in development voor config/secrets-pariteitVerkleint verschillen tussen development en productie door uniforme configuratie- en secretsafhandeling.Losse, afwijkende developmentconfiguratie zonder centrale uniformering
ADR-022MudBlazor als gecontroleerde UI-componentbasisVersnelt realisatie van consistente Blazor UI-patronen, terwijl OefenHub via eigen thema, wrappercomponenten en componentencatalogus visueel en technisch herbruikbaar blijft.Volledig custom UI-framework of per pagina zelfstandig opgebouwde HTML/CSS zonder herbruikbare componenten

Verdere technische uitwerking

De volgende onderwerpen zijn bewust niet volledig uitgewerkt in de architectuurbaseline en horen in het Technisch Ontwerp of beheerbeleid:

  • concrete deploymentinrichting en hostingtopologie;
  • operationele observability rond Serilog, Seq, monitoring en alerting;
  • concrete mailprovider en technische mailinrichting;
  • database-DDL, indexes, queryvormen en migratiestrategie;
  • caching, materialisatie en readmodel-implementatie;
  • loadtestopzet, performanceprofielen en technische teststrategie;
  • eventuele deploymentdiagrammen, sequence diagrams of security views;
  • detailinrichting van de OefenHub-componentencatalogus, themetokens en componenttestaanpak bovenop MudBlazor;
  • verdere technische detaillering van C4 niveau 4 waar implementatie-inzichten dat nodig maken.

Begrippenlijst

BegripBetekenis
Middel-zware modulaire monolietEén deploybare applicatie met één primaire database, maar intern georganiseerd in duidelijke moduleprojecten met eigen verantwoordelijkheden, contracten, boundaries, DbContexts/schema's waar persistentie nodig is en architecture tests voor dependencyregels.
C4-modelManier om softwarearchitectuur op vier niveaus te beschrijven: context, containers, componenten en code.
System ContextNiveau 1 van het C4-model; toont het systeem in zijn omgeving.
ContainerEen zelfstandig uitvoerbaar of opslaand hoofdonderdeel, zoals een webapplicatie, database of extern platform.
ComponentEen logisch onderdeel binnen een container, zoals een service, module of subdomein.
Identity providerExtern systeem dat authenticatie en credentialbeheer uitvoert, in dit geval Keycloak.
CollaboratorDocent met expliciet niveau-bewerkrecht op een niveau dat eigendom heeft van een andere docent.
Exercise runEen concrete, unieke uitvoering van een oefening door een gebruiker.
Container DiagramNiveau 2 van het C4-model; toont de belangrijkste containers binnen het systeem en hun onderlinge relaties.
WebappDe primaire OefenHub webapplicatiecontainer waarin gebruikersinteractie, businesslogica en integraties samenkomen.
Component DiagramNiveau 3 van het C4-model; toont de belangrijkste logische componenten binnen één gekozen container en hun onderlinge samenhang.
SignalRDe in OefenHub gekozen realtime-mechaniek voor live meekijken, presence en directe updates tussen browser en webapp.
TickerQDe gekozen scheduler-/jobtechnologie voor background jobs, cleanup en tijdsafhankelijke afhandeling binnen de monoliet.
SystemMessageMailboxgericht systeembericht binnen OefenHub, gescheiden van site-notificaties en privéberichten.
SiteNotificationDoelgroepgerichte UI-notificatie die in de webapp wordt getoond en browserlokaal once-per-browser gedrag kan hebben.
Hybride persistentiestijlOpslagprincipe waarbij relationele kerngegevens worden gecombineerd met modulespecifieke JSON/base64-payloads.
MudBlazorDe gekozen Blazor-componentenbibliotheek voor generieke interactieve UI-primitives binnen OefenHub.Web; MudBlazor is geen bron voor domeinlogica, requirements of visuele OefenHub-identiteit.
OefenHub-componentenlaagHerbruikbare set OefenHub-wrappercomponenten, layoutcomponenten, themetokens en UI-patronen die MudBlazor gecontroleerd toepast en schermen technisch consistent opbouwt.
HTML-mockupBespreek- en toetsartefact voor schermopbouw, navigatie, informatiestructuur en visuele richting; geen implementatieskelet en geen bron voor productie-HTML/CSS/JavaScript.
OefenmoduleTechnische module die specifieke oefenlogica, configuratievalidatie, rendering en vraag-/antwoordverwerking levert binnen het generieke OefenHub-platform.