# Overdracht racket-wiki Bijgewerkt: 22 augustus 2026 ## Project in het kort `racket-wiki` is een kleine, zelfgehoste wiki met: - een Racket-backend op `web-server-lib`; - PostgreSQL als opslag voor gebruikers, sessies, pagina's, versies, bijlagen en concept maps (CMaps); - een frontend in gewone HTML, CSS en JavaScript, zonder npm- of bundlerstap; - EasyMDE/Marked voor Markdown, DOMPurify voor sanitizing, highlight.js voor code en diff2html voor versieverschillen; - lokale, tijdens setup gedownloade frontendbibliotheken, zodat normaal gebruik geen CDN nodig heeft. De ontwikkelversie is **0.2.99** (`info.rkt`). De huidige PostgreSQL-schemaversie is **12** (`private/migrations.rkt`). ## Belangrijk: huidige werkboom De branch is `main` en volgt `origin/main`. De laatste commit is: ```text 63b7ca0 cmap functions, email, architecture documentation. ``` Er staan belangrijke, nog niet gecommitte wijzigingen in de werkboom. Die vormen samen de ontwikkeling van 0.2.95 t/m 0.2.99 en moeten worden behouden. Bij de laatste inventarisatie waren gewijzigd: ```text README.md architecture/pages/data-en-versies.md architecture/pages/gedrag.md architecture/pages/testbaarheid.md info.rkt private/cmap-storage.rkt private/migrations.rkt server.rkt static/cmap/cmap-racket-wiki.js static/cmap/cmap.css static/cmap/cmap.js static/css/wiki.css static/index.html static/js/wiki.js translate.rkt ``` Nieuw en nog untracked: ```text migrate-cmap-subpages.rkt ``` Voer dus geen reset, checkout of brede formattering uit voordat deze wijzigingen zijn beoordeeld en veilig gecommitte. `wiki-data/` en `compiled/` zijn lokale/gegenereerde directories en staan in `.gitignore`. ## Snel starten Benodigd: - Racket met de dependencies uit `info.rkt` (`crypto-lib`, `db-lib`, `net-lib`, `net-cookies-lib`, `openssl-lib` en `web-server-lib`); - PostgreSQL; de database moet vooraf bestaan en de opgegeven rol moet tabellen en indexen mogen maken; - internettoegang tijdens de eerste setup om de vastgepinde browserbibliotheken te downloaden. In deze ontwikkelomgeving is Racket 9.1 gebruikt. Start vanuit de projectroot: ```sh racket main.rkt --data ./wiki-data --port 8080 ``` Open daarna `http://127.0.0.1:8080/`. Een incomplete installatie gaat automatisch naar `/setup`. Daar worden de databaseverbinding, migraties, frontendbestanden en eerste administrator geregeld. Luisteren op alle interfaces kan met: ```sh racket main.rkt --data ./wiki-data --listen '*' --port 8080 ``` Gebruik achter HTTPS altijd `--secure-cookie`. Andere relevante opties zijn `--title`, `--language en|nl` en de hersteloptie `--create-admin USER PASSWORD`. De database-instellingen, inclusief eventueel het wachtwoord, staan in `wiki-data/database.rktd`. Dit bestand hoort niet in Git of in logs. De applicatie probeert het bestand met mode `0600` aan te maken. Als alleen de browserdependencies hersteld moeten worden: ```sh racket setup-vendor.rkt --data ./wiki-data ``` ## Codekaart | Pad | Verantwoordelijkheid | | --- | --- | | `main.rkt` | CLI en programmatische entrypoints `start` en `start-wiki` | | `server.rkt` | HTTP-routering, setup/loginpagina's en alle JSON/API-handlers | | `private/config.rkt` | runtimeconfiguratie en paden onder de datadirectory | | `private/setup.rkt` | eerste websetup en herstelcontrole | | `private/database.rkt` | PostgreSQL-configuratie, verbindingen en migratiestart | | `private/migrations.rkt` | geordende, transactionele databaseschemamigraties | | `private/storage.rkt` | pagina's, historie, zoeken, todo's, bookmarks, aliassen en uploads | | `private/cmap-storage.rkt` | opslag, historie, zoeken en gebruikstellingen voor CMaps | | `private/auth.rkt` | wachtwoorden, sessies, CSRF, rollen en password-reset-tokens | | `private/mail.rkt` | SMTP-instellingen en resetmails | | `translate.rkt` | Engelse/Nederlandse server- en frontendvertalingen | | `static/index.html` | skelet van de ingelogde single-page-interface | | `static/js/wiki.js` | applicatiestatus, API-calls, pagina-editor en CMap-hostintegratie | | `static/cmap/` | lokaal onderhouden CMap-renderer, editorlaag en styling | | `architecture/` | importeerbare Nederlandse architectuurpagina's en twee CMaps | | `scrbl/racket-wiki.scrbl` | package/API-documentatie in Scribble | De browserfrontend heeft bewust geen buildstap. Wijzig bronbestanden rechtstreeks en test ze in de browser. Externe browserlibraries staan runtime onder `wiki-data/static/vendor/`; wijzig die niet als applicatiebron. ## Belangrijke invarianten - Er is geen anonieme wiki-toegang. `reader` leest, `editor` schrijft en `admin` beheert gebruikers en instellingen. - Schrijvende API-calls vereisen naast een sessie ook de CSRF-token. - Pagina's hebben een aparte `namespace` en stabiele `slug`; de combinatie is uniek. Een titelwijziging verandert de slug niet. - Elke paginasave wijzigt `pages` en schrijft in dezelfde transactie een onveranderlijke `page_versions`-rij. - Pagina-updates en CMap-updates gebruiken optimistic locking en horen bij een verouderde basisversie HTTP 409 te geven. - Pagina's en CMaps worden gearchiveerd (soft delete); histories blijven behouden. - Bijlagen staan als `BYTEA` in PostgreSQL. Alleen vertrouwde rasterformaten worden inline geserveerd; andere bestanden worden downloads. - Markdown gaat vóór invoegen in de DOM door DOMPurify. - Verhoog `current-schema-version` alleen samen met een nieuwe, opeenvolgende migratie. Een database met een nieuwer schema dan de code moet geweigerd blijven. ## Lopend werk: 0.2.95–0.2.99 De niet-gecommitte reeks bouwt vooral de persistente CMap-functionaliteit uit: - stabiele, wiki-brede `conceptId`-identiteiten en gekoppelde plaatsingen met een eigen layout; - conceptaspecten, beschrijvingspagina's, stijlpresets, afzonderlijke titel-/synopsisopmaak en een bewerkbaar kleurenpalet; - directe relaties met Alt, gelinkte copy/paste en robuust herstel bij relaties met ontbrekende eindpunten; - afgeleide, opgeslagen sub-CMapweergaven die naar de canonieke parentgraph verwijzen; - keuze van een start-CMap en per-view verborgen concepten; - autosave zonder historievervuiling, maximaal vijf handmatige saves en onbeperkte snapshots; - verwijderen van afzonderlijke handmatige CMap-history-items/snapshots; - een paneel op wikipagina's met alle gekoppelde CMap-concepten en plaatsingstellingen. Migratie 12 schoont oude CMap-autosavehistorie op en beperkt herkenbare handmatige saves tot vijf. `migrate-cmap-subpages.rkt` is een aparte contentmigratie voor oudere inline sub-CMaps; dit is geen databaseschemamigratie. Gebruik die contentmigratie altijd eerst als dry-run: ```sh racket migrate-cmap-subpages.rkt --data ./wiki-data racket migrate-cmap-subpages.rkt --data ./wiki-data --apply ``` Zonder `--apply` wordt niets gewijzigd. Met `--apply` gebeurt de omzetting in één PostgreSQL-transactie. Maak desondanks eerst een databasebackup en beoordeel de gemelde slugs. ## Testen en huidige verificatiestatus De automatische testdekking is beperkt. Op 22 augustus 2026 zijn de volgende controles succesvol uitgevoerd: ```sh raco test architecture/import.rkt # 12 tests passed raco make main.rkt server.rkt setup-vendor.rkt \ migrate-cmap-subpages.rkt architecture/import.rkt node --check static/js/wiki.js node --check static/js/combobox.js node --check static/cmap/cmap.js node --check static/cmap/cmap-racket-wiki.js ``` Er is nog geen geautomatiseerde backendintegratietest tegen PostgreSQL en geen browsertestsuite. De huidige 0.2.95–0.2.99-werkboom is dus wel compileerbaar en syntactisch geldig, maar nog niet in deze overdracht end-to-end gevalideerd. Voer vóór commit/release minimaal deze smoke tests uit op een kopie of aparte testdatabase: 1. Verse `/setup`, login/logout en de drie rollen. 2. Pagina maken, wijzigen, hernoemen, history bekijken, conflict (409), namespace-link en upload. 3. CMap maken, autosave, expliciet opslaan, snapshot maken/verwijderen en historylimiet controleren. 4. Een concept meerdere keren en in meerdere CMaps plaatsen; controleer tellingen en het paneel op de gekoppelde wikipagina. 5. Een inline sub-CMap met de dry-run en daarna `--apply` migreren; controleer parent, derived view en oude histories. 6. Start-CMap, verborgen concepten, linked copy/paste, undo/redo en beschadigde relatie zonder endpoint controleren. 7. Zoekresultaten, bookmarks, todo's, aliassen en adminoverzichten nalopen. 8. Indien mail relevant is: SMTP-test en de volledige vergeten-wachtwoordflow. ## Architectuurdocumentatie importeren Valideren en wijzigingen vooraf bekijken: ```sh racket architecture/import.rkt --data ./wiki-data --dry-run ``` Importeren: ```sh racket architecture/import.rkt --data ./wiki-data --author "Naam ontwikkelaar" ``` De import is herhaalbaar en gebruikt source hashes. Lokaal aangepaste geïmporteerde pagina's/CMaps worden standaard overgeslagen. Gebruik `--overwrite-modified` alleen na controle van hun histories. ## Mailconfiguratie Password-resetmail kan via de admininterface/database of via omgevingsvariabelen worden ingesteld. Ondersteund zijn: ```text RACKET_WIKI_PUBLIC_URL RACKET_WIKI_SMTP_HOST RACKET_WIKI_SMTP_PORT RACKET_WIKI_SMTP_FROM RACKET_WIKI_SMTP_USER RACKET_WIKI_SMTP_PASSWORD RACKET_WIKI_SMTP_TLS RACKET_WIKI_SMTP_ACCEPT_UNTRUSTED_CERTIFICATES RACKET_WIKI_RESET_LIMIT ``` Accepteer onbetrouwbare certificaten alleen bewust voor een vertrouwde lokale SMTP-server. Zet secrets nooit in documentatie, commits of testoutput. ## Aanbevolen eerstvolgende stap Maak eerst een databasebackup en test de volledige niet-gecommitte 0.2.95–0.2.99-reeks met bovenstaande smoke tests. Beoordeel daarna de diff als één samenhangende CMap-wijziging, werk zo nodig `README.md`, Scribble-documentatie en architectuurpagina's gelijk bij, en commit pas wanneer migratie 12 en `migrate-cmap-subpages.rkt` op representatieve data zijn geverifieerd. Voor functionele details en releasehistorie is `README.md` de uitgebreidste bron. De bestanden onder `architecture/pages/` beschrijven ontwerpbeslissingen en kwaliteitsafspraken; `architecture/pages/code-regels.md` is de beste start voor projectconventies.