63 lines
4.3 KiB
Markdown
63 lines
4.3 KiB
Markdown
# Modulariteit en afhankelijkheden
|
|
|
|
## Huidige modulegrenzen
|
|
|
|
De backend is functioneel opgesplitst. Configuratie, databaseverbinding, migraties, authenticatie, paginaopslag, CMap-opslag, mail, setup en vendorbeheer hebben ieder een herkenbare module. Deze modules communiceren hoofdzakelijk met gewone Racket-waarden: structs, hashes, lijsten en strings.
|
|
|
|
De belangrijkste grens is die tussen `server.rkt` en de opslagmodules. `server.rkt` hoort HTTP te begrijpen; `storage.rkt`, `cmap-storage.rkt` en `auth.rkt` horen domeinbewerkingen en database-invarianten te begrijpen. Geen opslagprocedure mag een webrequest nodig hebben.
|
|
|
|
De frontend heeft een vergelijkbare grens. `cmap-racket-wiki.js` implementeert een editorcomponent met callbacks voor openen, selectie en wijzigingen. `wiki.js` koppelt die callbacks aan routes, API's en dialoogvensters.
|
|
|
|
## Sterke punten
|
|
|
|
De volgende onderdelen zijn al goed geïsoleerd:
|
|
|
|
- `wiki-config` bundelt runtimekeuzes en voorkomt verspreide globale configuratie.
|
|
- `call-with-wiki-database` centraliseert openen en sluiten van verbindingen.
|
|
- opslagprocedures kapselen SQL en transacties in.
|
|
- de CMap-documentvorm is een expliciet JSON-contract met `schemaVersion`.
|
|
- Markdownrendering gaat via één frontendfunctie voor lezen, preview en historie.
|
|
- vertalingen hebben één effectieve bron voor backend en frontend.
|
|
- frontend-vendorbestanden worden door één module beheerd en gecontroleerd.
|
|
|
|
## Huidige concentraties
|
|
|
|
`server.rkt` bevat zowel routing als veel requestparsing en handlerlogica. `static/js/wiki.js` bevat vrijwel de hele single-page applicatie. Dat maakt zoeken eenvoudig, maar vergroot de kans dat een wijziging onverwacht een ander view- of routepad raakt.
|
|
|
|
`private/storage.rkt` combineert pagina's, historie, zoeken, bookmarks, aliases en uploads. Die onderdelen delen pagina-identiteit en transacties, maar hoeven niet onbeperkt samen te groeien.
|
|
|
|
Deze concentraties zijn technische schuld, geen automatische opdracht tot een grote opsplitsing. Een splitsing moet een concreet voordeel hebben: een kleiner contract, onafhankelijke tests of duidelijker eigenaarschap.
|
|
|
|
## Gewenste afhankelijkheidsregels
|
|
|
|
1. Een buitenste laag mag een binnenste dienst kennen; omgekeerd niet. HTTP kent opslag, opslag kent geen HTTP.
|
|
2. SQL blijft in database- en opslagmodules. JavaScript bouwt geen SQL-achtige querysemantiek na.
|
|
3. Authenticatie en autorisatie blijven server-side. UI-zichtbaarheid is alleen gebruiksgemak.
|
|
4. Cross-cutting gedrag krijgt één expliciete helper wanneer er werkelijk meerdere gebruikers zijn. Maak geen wrapper voor één triviale aanroep.
|
|
5. Een module exporteert alleen procedures en structs die een andere module werkelijk nodig heeft.
|
|
6. Gebruik geen `dynamic-require` om een heldere statische afhankelijkheid te verbergen.
|
|
7. Een nieuwe module krijgt één samenhangende reden om te wijzigen; een verzameling toevallige helpers is geen moduleontwerp.
|
|
|
|
## Waarschijnlijke toekomstige extracties
|
|
|
|
Wanneer `server.rkt` verder groeit, ligt opsplitsing per adaptergebied voor de hand: sessie/profiel, pagina's, CMaps en beheer. De centrale router kan dan dun blijven. Handlers ontvangen `config` expliciet en roepen dezelfde bestaande diensten aan.
|
|
|
|
Wanneer `wiki.js` verder groeit, zijn route/state, pagina-editor, CMap-host, graph-view en admin-views natuurlijke grenzen. Splits alleen met native ES-modules wanneer de setup- en cacheversies van alle scripts tegelijk beheerst worden.
|
|
|
|
Wanneer paginaopslag wordt aangepast, kunnen bookmarks, aliases en uploads later eigen modules krijgen. De pagina-schrijftransactie en afgeleide indices moeten daarbij als één consistente operatie behouden blijven; opsplitsing van bestanden mag geen opsplitsing van de transactie veroorzaken.
|
|
|
|
## Contracten tussen modules
|
|
|
|
Een goed contract specificeert:
|
|
|
|
- geldige invoer en normalisatie;
|
|
- welke toestand wordt gelezen of gewijzigd;
|
|
- transactiegrens en concurrencygedrag;
|
|
- resultaatvorm;
|
|
- herkenbare domeinfouten;
|
|
- maximale document- of uploadgrootte waar relevant.
|
|
|
|
De bestaande `goal / pre / post / result`-commentaren zijn hiervoor geschikt, zolang zij het niet-zichtbare contract beschrijven en niet slechts de procedurecode navertellen.
|
|
|
|
Zie [Regels bij het coderen](racket-wiki:code-regels) voor de concrete stijl en [Testbaarheid](racket-wiki:testbaarheid) voor het testen per grens.
|