Initial curated itworx-knowledge-hub source from 3b1751d0d9dee551aa6994eee0093704dc334817
This commit is contained in:
commit
ad8ad252a9
825 files changed
+124216
No files matched your search
@@ -0,0 +1,119 @@
|
||||
# Back-ups, herstel en beheer op Unraid
|
||||
|
||||
Deze gids beschrijft de M7-functionaliteit: back-ups maken, een back-up herstellen naar
|
||||
een schone omgeving, en de operationele controles rond een Unraid-implementatie.
|
||||
Geschreven voor beheerders/operators, niet voor eindgebruikers. Er is bewust geen
|
||||
scherm in de webapplicatie voor back-upbeheer — dit gebeurt via de API (back-up maken/
|
||||
lijst tonen) en via een aparte opdrachtregelmodus van dezelfde container-image
|
||||
(herstellen), nooit via een knop in de draaiende applicatie zelf.
|
||||
|
||||
## Een back-up maken
|
||||
|
||||
```bash
|
||||
curl -X POST https://hub.example/api/v1/admin/backups \
|
||||
-H "X-CSRF-Token: <csrf-token-van-huidige-sessie>" -b cookies.txt
|
||||
```
|
||||
|
||||
Dit maakt synchroon een volledige back-up: elke databasetabel (via een schema-
|
||||
onafhankelijke binaire kopie, geen externe `pg_dump`-tool nodig) plus elk
|
||||
content-adresseerbare bijlagebestand, met een `manifest.json` dat per bestand een
|
||||
SHA-256-hash bevat. Elk bestand wordt na het schrijven opnieuw gehasht en vergeleken
|
||||
vóór de back-up zichtbaar wordt — een back-up die deze controle niet doorstaat, wordt
|
||||
nooit gepubliceerd en vervangt dus nooit de laatst bekende goede back-up.
|
||||
|
||||
```bash
|
||||
curl https://hub.example/api/v1/admin/backups -b cookies.txt
|
||||
```
|
||||
|
||||
geeft de lijst van voltooide back-ups terug (nieuwste eerst), met alleen veilige,
|
||||
niet-herleidbare informatie (geen bestandspaden, geen connectiegegevens).
|
||||
|
||||
### Bewaarbeleid
|
||||
|
||||
Standaard worden de **14 nieuwste** voltooide back-ups bewaard (instelbaar via
|
||||
`KnowledgeHub__Backup__RetainedCount`); de allerlaatste back-up wordt nooit verwijderd,
|
||||
ook niet als dat aantal wordt overschreden. Back-ups blijven op dezelfde schijf/pool
|
||||
als de applicatie staan — kopieer ze periodiek naar een onafhankelijke opslaglocatie;
|
||||
een back-up op dezelfde schijf alleen is geen rampenherstel.
|
||||
|
||||
## Een back-up herstellen
|
||||
|
||||
Herstel is bewust **nooit** bereikbaar via de draaiende applicatie zelf — een draaiende
|
||||
applicatie die tegelijk verkeer verwerkt én haar eigen database overschrijft, is precies
|
||||
het scenario dat vermeden moet worden. In plaats daarvan draait dezelfde image in een
|
||||
aparte, kortstondige opdrachtregelmodus, gericht op een **schone doelomgeving** (nooit
|
||||
de productie-instantie).
|
||||
|
||||
### Stap 1 — doeldatabase voorbereiden (alleen migreren)
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
--network itworx-knowledge-hub_knowledge-hub-internal \
|
||||
-e KnowledgeHub__Database__Host=<doel-db-host> \
|
||||
-e KnowledgeHub__Database__Name=<doel-db> \
|
||||
-e KnowledgeHub__Database__Username=<gebruiker> \
|
||||
-e KnowledgeHub__Database__Password=<wachtwoord> \
|
||||
itworx/knowledge-hub:local \
|
||||
dotnet ItWorx.KnowledgeHub.Api.dll --migrate-only
|
||||
```
|
||||
|
||||
Gebruik hier bewust `--migrate-only`, niet een gewone opstart: een gewone opstart
|
||||
maakt als bijwerking meteen de installatierij aan (dezelfde rij die bij een eerste
|
||||
installatie hoort), waardoor de doeldatabase niet meer "leeg" is tegen de tijd dat
|
||||
herstel start. `--migrate-only` past uitsluitend het schema toe en sluit daarna direct
|
||||
af.
|
||||
|
||||
### Stap 2 — herstellen
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
--network itworx-knowledge-hub_knowledge-hub-internal \
|
||||
-v knowledge-hub-backups:/var/lib/knowledge-hub/backups:ro \
|
||||
-e KnowledgeHub__Paths__Backups=/var/lib/knowledge-hub/backups \
|
||||
-v <doel-bijlagen-volume>:/var/lib/knowledge-hub/attachments \
|
||||
itworx/knowledge-hub:local \
|
||||
dotnet ItWorx.KnowledgeHub.Api.dll \
|
||||
--restore \
|
||||
--backup-id=<back-up-id> \
|
||||
--target-connection="Host=<doel-db-host>;Port=5432;Database=<doel-db>;Username=<gebruiker>;Password=<wachtwoord>" \
|
||||
--target-attachments=/var/lib/knowledge-hub/attachments
|
||||
```
|
||||
|
||||
De doeldatabase moet **leeg** zijn — herstel weigert expliciet als er al rijen in
|
||||
staan, om nooit per ongeluk bestaande gegevens te vermengen met herstelde gegevens.
|
||||
|
||||
Het proces rapporteert per tabel het aantal herstelde versus verwachte rijen, het
|
||||
aantal herstelde bijlagen, en sluit af met `GESLAAGD` of `MISLUKT`
|
||||
(afsluitcode 0 respectievelijk 1). Een `MISLUKT`-resultaat laat expliciet zien welke
|
||||
tabel niet overeenkomt — er wordt nooit stilzwijgend een onvolledig herstel als
|
||||
geslaagd gerapporteerd.
|
||||
|
||||
## Opstartgedrag en migraties
|
||||
|
||||
Bij elke opstart:
|
||||
|
||||
1. De applicatie weigert te starten als de database al een migratie heeft toegepast
|
||||
die deze build niet kent (bijvoorbeeld na een terugzetting naar een oudere
|
||||
image-versie tegen een nieuwere database) — dit voorkomt dat de applicatie
|
||||
onbedoeld tegen een onbekende schemavorm gaat werken.
|
||||
2. Normale voorwaartse migratie (een oudere database die bijwerkt naar een nieuwere
|
||||
applicatieversie) blijft het gewone pad en gebeurt automatisch bij opstart.
|
||||
|
||||
## Statuscontroles
|
||||
|
||||
- `GET /health/live` — altijd anoniem bereikbaar; faalt nooit vanwege een tijdelijk
|
||||
onbereikbare database. Gebruik dit voor de container-gezondheidscontrole.
|
||||
- `GET /health/ready` — anoniem bereikbaar maar geeft alleen een minimale status terug
|
||||
(geen details): controleert databaseverbinding, of alle migraties zijn toegepast, en
|
||||
of alle geconfigureerde opslagpaden beschrijfbaar zijn.
|
||||
- `GET /api/v1/system/info` — vereist beheerdersaanmelding. Toont productversie,
|
||||
schemaversie, commit en uptime — gebruik dit na een herstart/upgrade om te
|
||||
bevestigen welke versie en welk schema daadwerkelijk draait.
|
||||
|
||||
## Logboeken
|
||||
|
||||
In productie schrijft de applicatie gestructureerde JSON-logregels naar stdout/stderr,
|
||||
elk met een correlatie-ID zodat alle logregels van één aanvraag samen te herleiden
|
||||
zijn. Wachtwoorden, ruwe tokens, cookies, autorisatie-headers, connectiereeksen en
|
||||
paginainhoud worden nooit gelogd. Logrotatie gebeurt op Docker/Unraid-niveau, niet
|
||||
binnen de applicatie.
|
||||
@@ -0,0 +1,82 @@
|
||||
# Bijlagen en LeafWiki-import
|
||||
|
||||
Deze gids beschrijft de M4-functionaliteit: bestanden (bijlagen) toevoegen aan
|
||||
pagina's, en het overzetten van bestaande LeafWiki-inhoud. Geschreven voor
|
||||
redacteuren (bijlagen) en de beheerder die een import uitvoert.
|
||||
|
||||
## Bijlagen toevoegen aan een pagina
|
||||
|
||||
1. Open een pagina en klap **Bijlagen** open, onderaan de pagina.
|
||||
2. Kies een bestand via **Bijlage toevoegen**.
|
||||
3. Zodra het uploaden gelukt is, verschijnt het bestand in de lijst met de
|
||||
bestandsgrootte.
|
||||
4. Klik op **Kopieer Markdown-verwijzing** en plak die tekst op de gewenste plaats in
|
||||
de inhoud van de pagina om de bijlage zichtbaar te maken (als afbeelding bij een
|
||||
afbeeldingsbestand, of als downloadlink voor andere bestanden).
|
||||
|
||||
### Wat wordt geweigerd
|
||||
|
||||
Om veiligheidsredenen worden sommige bestandstypes nooit geaccepteerd, ongeacht de
|
||||
bestandsnaam:
|
||||
|
||||
- uitvoerbare bestanden (`.exe` en gelijkaardige programma's);
|
||||
- HTML- en SVG-bestanden (deze kunnen actieve inhoud bevatten).
|
||||
|
||||
De toepassing herkent het echte bestandstype aan de inhoud zelf, niet aan de
|
||||
bestandsextensie — een bestand met een misleidende naam (bijvoorbeeld
|
||||
`factuur.pdf.exe`) wordt dus wel degelijk herkend en geweigerd.
|
||||
|
||||
### Standaardlimiet
|
||||
|
||||
Een bijlage mag standaard maximaal 100 MiB groot zijn (instelbaar door de beheerder).
|
||||
|
||||
## LeafWiki-import (alleen beheerder, alleen via API)
|
||||
|
||||
Er is nog geen importwizard in de webinterface — deze functionaliteit is voor deze
|
||||
milestone alleen via de API beschikbaar, net zoals gebruikersbeheer dat aanvankelijk
|
||||
was. De echte import van de eigenaar's LeafWiki-omgeving (M9) volgt de volledige
|
||||
procedure in `docs/17-leafwiki-migration.md`; dit is de technische samenvatting voor
|
||||
de synthetische/oefen-import die nu al mogelijk is.
|
||||
|
||||
1. **Plaats de bron.** Kopieer de LeafWiki-bronmap (nooit de originele, live map) naar
|
||||
het gemonteerde volume op het pad ingesteld via `KnowledgeHub:Paths:Imports`
|
||||
(standaard `/var/lib/knowledge-hub/imports`).
|
||||
2. **Preflight (verkenning, geen wijzigingen).**
|
||||
|
||||
```
|
||||
POST /api/v1/admin/imports/preflight
|
||||
{ "sourceRelativePath": "<pad relatief aan de imports-map>", "idempotencyKey": "<unieke sleutel>" }
|
||||
```
|
||||
|
||||
Dit levert een plan op: welke pagina's herkend worden, de voorgestelde
|
||||
hiërarchie, en eventuele conflicten — zonder dat er iets in de kennisbank
|
||||
verandert.
|
||||
3. **Uitvoeren.**
|
||||
|
||||
```
|
||||
POST /api/v1/admin/imports/{jobId}/execute?sourceRelativePath=<zelfde pad>
|
||||
```
|
||||
|
||||
Bestaande pagina's worden nooit overschreven. Een eerder geïmporteerde pagina met
|
||||
ongewijzigde inhoud wordt bij een herhaalde uitvoering overgeslagen, niet opnieuw
|
||||
aangemaakt.
|
||||
4. **Terugdraaien indien nodig.**
|
||||
|
||||
```
|
||||
POST /api/v1/admin/imports/{jobId}/rollback
|
||||
```
|
||||
|
||||
Verwijdert alleen de pagina's die deze import zelf aanmaakte én die nadien niet
|
||||
door een gebruiker bewerkt zijn. Een pagina die na de import werd bewerkt, blijft
|
||||
bestaan — bewerkte inhoud gaat nooit verloren door een rollback.
|
||||
|
||||
### Wat de import ondersteunt in deze milestone
|
||||
|
||||
- Een map met Markdown-bestanden (inclusief geneste submappen, `[[interne links]]`
|
||||
en bijlagen die door de Markdown-bestanden verwezen worden).
|
||||
- Een SQLite-database met het specifieke, in deze toepassing gedocumenteerde
|
||||
synthetische testschema (`synthetic-sqlite-v1`) — bedoeld om de
|
||||
schema-validatiemechaniek te bewijzen, niet als ondersteuning voor een echte,
|
||||
onbekende LeafWiki-databaseversie. Een database met een onherkend schema levert
|
||||
altijd een duidelijke blokkering op in de preflight-stap, nooit een gegokte
|
||||
interpretatie van de gegevens.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Documenten toevoegen via intake
|
||||
|
||||
De intake is beschikbaar zodra de beheerder de functie in de serverconfiguratie
|
||||
heeft ingeschakeld. Meld u aan als redacteur en open **Intake** in het menu.
|
||||
|
||||
1. Vul een documenttitel in en kies het documenttype.
|
||||
2. Kies een PDF-, Word-, Markdown- of tekstbestand van maximaal 100 MB.
|
||||
3. Voeg bij een PDF of Word-document liefst een korte inhoudelijke toelichting toe.
|
||||
Bij een klein tekst- of Markdownbestand kan de inhoud automatisch de
|
||||
conceptpagina vullen.
|
||||
4. Klik **Document toevoegen**. Het origineel wordt als bijlage opgeslagen en het
|
||||
voorstel verschijnt in de beoordelingswachtrij.
|
||||
5. Open **Bekijk voorstel**, controleer de bron, conceptinhoud en bestemming.
|
||||
Keur het voorstel afzonderlijk goed en bevestig daarna **Publiceren**.
|
||||
|
||||
Een mislukte upload kan in hetzelfde formulier worden hervat zonder een tweede
|
||||
voorstel aan te maken. Na een paginaverversing blijft een onafgewerkt voorstel in
|
||||
de wachtrij zichtbaar. Het oorspronkelijke bestand blijft bewaard; de toepassing
|
||||
claimt geen automatische tekstextractie uit PDF of Word en geen AI-analyse van
|
||||
handmatig toegevoegde bestanden.
|
||||
|
||||
## Later toevoegen vanuit ChatGPT
|
||||
|
||||
Dezelfde beveiligde `/api/v1/ingestion-proposals`-route is bedoeld voor een
|
||||
**aparte MCP-service**. Die service kan namens een beperkt serviceaccount een
|
||||
voorstel en bronbestanden indienen. De browsergebruiker beoordeelt en publiceert
|
||||
het resultaat in dit platform. De MCP-service, HTTPS-toegang en het bijbehorende
|
||||
serviceaccount zijn aparte installatie- en verificatiestappen; het inschakelen
|
||||
van de intake alleen maakt ChatGPT-bijlagen nog niet rechtstreeks beschikbaar.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Eerste installatie, aanmelden en wachtwoordherstel
|
||||
|
||||
Deze gids beschrijft de M1-functionaliteit: de eenmalige eerste installatie, aanmelden
|
||||
en afmelden, rolbeheer en operator-herstel van een vergeten wachtwoord. Geschreven voor
|
||||
de beheerder die de installatie uitvoert.
|
||||
|
||||
## Eerste installatie (eenmalig)
|
||||
|
||||
Wanneer de toepassing voor het eerst opstart, bestaat er nog geen beheerdersaccount.
|
||||
Elke bezoeker ziet dan het installatiescherm.
|
||||
|
||||
1. **Vul het installatieformulier in:** een naam voor de werkruimte, uw naam,
|
||||
e-mailadres en een wachtwoord van minimaal 12 tekens.
|
||||
2. Na een geslaagde installatie bent u automatisch aangemeld als beheerder en kan het
|
||||
installatiescherm nooit meer opnieuw gebruikt worden.
|
||||
|
||||
Er is geen "installatie ongedaan maken"-knop in de toepassing. Dat is opzettelijk: een
|
||||
volledige nieuwe installatie vereist een operator die de database opnieuw opzet volgens
|
||||
`docs/18-backup-restore.md` (M7).
|
||||
|
||||
## Aanmelden en afmelden
|
||||
|
||||
- Meld aan met e-mailadres en wachtwoord op het aanmeldscherm.
|
||||
- Na 5 mislukte pogingen wordt het account tijdelijk vergrendeld (15 minuten). De
|
||||
toepassing geeft dezelfde generieke foutmelding voor een onbekend account, een
|
||||
verkeerd wachtwoord én een vergrendeld account, zodat een aanvaller niet kan afleiden
|
||||
welk geval van toepassing is — behalve bij een vergrendeling, die wel expliciet als
|
||||
"te veel pogingen" wordt gemeld zodat een legitieme gebruiker weet dat hij moet
|
||||
wachten.
|
||||
- Een sessie duurt maximaal 12 uur, ongeacht activiteit.
|
||||
- "Afmelden" beëindigt de sessie onmiddellijk.
|
||||
|
||||
## Gebruikers en rollen beheren
|
||||
|
||||
Alleen een beheerder kan andere gebruikers aanmaken via `POST /api/v1/admin/users` (de
|
||||
webinterface hiervoor volgt in een latere milestone; de API is al volledig functioneel
|
||||
en getest). Beschikbare rollen:
|
||||
|
||||
| Rol | Rechten |
|
||||
|---|---|
|
||||
| Lezer | Bekijken en zoeken van toegestane inhoud. |
|
||||
| Redacteur | Lezer-rechten plus inhoud aanmaken en bewerken. |
|
||||
| Beheerder | Redacteur-rechten plus gebruikers, herstelcodes, imports en systeeminstellingen. |
|
||||
|
||||
Er moet altijd minstens één ingeschakelde beheerder overblijven: de toepassing weigert
|
||||
een wijziging die dat zou doorbreken (bijvoorbeeld de laatste beheerder degraderen of
|
||||
uitschakelen).
|
||||
|
||||
Een gebruiker uitschakelen (`enabled: false`) maakt **bestaande** aanmeldsessies van die
|
||||
gebruiker onmiddellijk ongeldig — niet pas bij een volgende aanmeldpoging.
|
||||
|
||||
## Wachtwoord vergeten (operator-herstel)
|
||||
|
||||
Er is geen e-mailprovider nodig. Een beheerder geeft een eenmalige herstelcode uit:
|
||||
|
||||
1. Beheerder roept `POST /api/v1/admin/users/{userId}/recovery-tokens` aan (via de
|
||||
webinterface in een latere milestone, of rechtstreeks via de API met een geldige
|
||||
beheerderssessie).
|
||||
2. De ruwe herstelcode wordt **precies één keer** getoond, in het antwoord van die
|
||||
aanroep. Ze wordt nergens anders opgeslagen — alleen een niet-omkeerbare
|
||||
verificatiewaarde blijft bewaard.
|
||||
3. Geef de code veilig door aan de gebruiker (bijvoorbeeld persoonlijk of via een
|
||||
bestaand vertrouwd kanaal — nooit via een onbeveiligd kanaal).
|
||||
4. De gebruiker dient de code en een nieuw wachtwoord in bij
|
||||
`POST /api/v1/auth/recovery/redeem`.
|
||||
5. De code werkt maar één keer en verloopt na 1 uur. Na een geslaagd herstel worden alle
|
||||
bestaande sessies van die gebruiker ongeldig — de gebruiker moet opnieuw aanmelden
|
||||
met het nieuwe wachtwoord.
|
||||
|
||||
## Wat een gewone gebruiker nooit kan zien
|
||||
|
||||
- Of een bepaald e-mailadres al dan niet een account heeft (aanmeldfoutmeldingen zijn
|
||||
altijd generiek).
|
||||
- Of de installatie al dan niet is voltooid, verder dan het installatiescherm tonen of
|
||||
verbergen.
|
||||
- Inhoud, gebruikers of instellingen van een andere werkruimte (de eerste uitgave
|
||||
gebruikt één werkruimte, maar de autorisatie is daar al op voorbereid).
|
||||
@@ -0,0 +1,75 @@
|
||||
# Operationele runbooks — overzicht
|
||||
|
||||
Deze gids wijst naar de bestaande, feitelijk geïmplementeerde runbook-onderwerpen
|
||||
(`docs/25-release-and-operations.md` "Operational runbooks required by 1.0") en
|
||||
beschrijft de twee onderwerpen die nog geen eigen gids hadden. Waar een onderwerp niet
|
||||
of nog niet volledig is geïmplementeerd, staat dat hier expliciet — nooit stilzwijgend
|
||||
verondersteld.
|
||||
|
||||
| Onderwerp | Status | Waar |
|
||||
| --- | --- | --- |
|
||||
| Eerste implementatie | Geïmplementeerd en getest | `docs/23-deployment-unraid.md` "First deployment"; `docs/guides/eerste-installatie-en-aanmelden.md` |
|
||||
| Eigenaarherstel (wachtwoord) | Geïmplementeerd en getest | `docs/guides/eerste-installatie-en-aanmelden.md` (herstel-token) |
|
||||
| Back-up maken | Geïmplementeerd en getest | `docs/guides/back-ups-herstel-en-unraid-beheer.md` |
|
||||
| Schoon herstel | Geïmplementeerd en getest | `docs/guides/back-ups-herstel-en-unraid-beheer.md` |
|
||||
| Applicatie bijwerken | Geïmplementeerd en getest | `docs/23-deployment-unraid.md` "Updates"; schema-driftweigering (M7) |
|
||||
| Applicatie terugzetten (rollback) | Geïmplementeerd en getest | `docs/23-deployment-unraid.md` "Rollback"; zie ook onderstaande sectie |
|
||||
| PostgreSQL kleine update | Geïmplementeerd en getest | Onderstaande sectie (nieuw voor M8) |
|
||||
| PostgreSQL grote upgrade (rehearsal) | **Niet uitgevoerd** | Zie "Bekende beperkingen" hieronder |
|
||||
| Opslag-/integriteitsstoring | Geïmplementeerd en getest | Onderstaande sectie (nieuw voor M8) |
|
||||
| Import en rollback | Geïmplementeerd en getest | `docs/guides/bijlagen-en-leafwiki-import.md` |
|
||||
| Gecompromitteerd service-token | Geïmplementeerd en getest | `docs/guides/service-accounts-en-automatisering.md` (intrekken) |
|
||||
| Gegevensexport | **Niet geïmplementeerd** | Zie "Bekende beperkingen" hieronder |
|
||||
| LeafWiki-overstap (cutover) | Ontworpen, niet uitgevoerd tegen echte data | `docs/17-leafwiki-migration.md`; echte overstap is M9-scope |
|
||||
|
||||
## PostgreSQL kleine update
|
||||
|
||||
Kleine (minor) PostgreSQL-updates binnen dezelfde hoofdversie (18.x) zijn compatibel met
|
||||
hetzelfde datavolume:
|
||||
|
||||
1. Bevestig een recente, geverifieerde back-up (`docs/guides/back-ups-herstel-en-unraid-beheer.md`).
|
||||
2. Werk de `postgres`-image-tag bij naar de nieuwe kleine versie in `docker-compose.yml`
|
||||
(bijvoorbeeld `postgres:18.5-bookworm`).
|
||||
3. `docker compose pull db && docker compose up -d db` — het bestaande datavolume
|
||||
(`knowledge-hub-db`) wordt hergebruikt; PostgreSQL werkt zelf bij bij het opstarten.
|
||||
4. Controleer `docker compose ps` (status `healthy`) en start daarna de applicatie
|
||||
opnieuw op (`docker compose up -d app`).
|
||||
5. Controleer `GET /health/ready` en een geauthenticeerde `GET /api/v1/system/info`.
|
||||
|
||||
Nooit een grote (major) versiesprong op deze manier uitvoeren — zie hieronder.
|
||||
|
||||
## Opslag-/integriteitsstoring
|
||||
|
||||
Wanneer `GET /health/ready` onbereikbaarheid van de database of een niet-beschrijfbaar
|
||||
opslagpad rapporteert (`DatabaseHealthCheck`/`StorageHealthCheck`, M7):
|
||||
|
||||
1. Controleer `docker compose ps` en `docker logs itworx-knowledge-hub-db-1` /
|
||||
`itworx-knowledge-hub-app-1` voor de onderliggende fout.
|
||||
2. Controleer of de onderliggende Unraid-schijf/-pool vol is of in fout-status staat
|
||||
(buiten het bereik van de applicatie zelf — de applicatie draait immers met een
|
||||
alleen-lezen hoofdbestandssysteem en kan de hostopslag niet zelf herstellen).
|
||||
3. Herstel de opslag/host-laag eerst; herstart pas daarna de containers.
|
||||
4. Als gegevensverlies of -corruptie wordt vermoed: **schrijf niets meer** naar de
|
||||
database totdat een back-up is bevestigd. Herstel bij twijfel vanaf de laatst
|
||||
geverifieerde back-up naar een schone doelomgeving
|
||||
(`docs/guides/back-ups-herstel-en-unraid-beheer.md`) in plaats van de productie-
|
||||
database rechtstreeks te herstellen met ad-hoc SQL
|
||||
(`docs/25-release-and-operations.md` "Incident priorities": "Do not 'repair'
|
||||
production data through undocumented ad hoc SQL").
|
||||
|
||||
## Bekende beperkingen
|
||||
|
||||
- **Gegevensexport is nog niet geïmplementeerd** als eindgebruikersfunctie. De enige
|
||||
vorm van "export" die vandaag bestaat, is de back-up zelf
|
||||
(`docs/guides/back-ups-herstel-en-unraid-beheer.md`), die het volledige datamodel
|
||||
bevat maar niet bedoeld is als leesbaar exportformaat voor een individuele pagina of
|
||||
project. Een gerichte exportfunctie (bijvoorbeeld Markdown-export per pagina/project)
|
||||
is niet gepland vóór een toekomstige milestone met een expliciet acceptatiecriterium.
|
||||
- **De PostgreSQL major-upgrade-rehearsal is niet uitgevoerd.** Dit vereist een tweede,
|
||||
oudere PostgreSQL-hoofdversie plus `pg_upgrade`- of dump/restore-oefening, wat buiten
|
||||
de tijdsbox van dit release-traject valt en geen acuut risico vormt zolang de
|
||||
applicatie op één vaste hoofdversie (18) blijft draaien. Voer deze oefening uit
|
||||
vóórdat een major-upgrade daadwerkelijk wordt gepland.
|
||||
- **De echte LeafWiki-overstap** vereist de echte LeafWiki-momentopname en productie-
|
||||
Unraid-omgeving van de gebruiker — een expliciete externe blokkade
|
||||
(`CLAUDE.md` §3), uitgevoerd in M9 zodra beschikbaar.
|
||||
@@ -0,0 +1,98 @@
|
||||
# Pagina's schrijven, bewerken en beheren
|
||||
|
||||
Deze gids beschrijft de M2-functionaliteit: de kennisboom, pagina's aanmaken en
|
||||
bewerken, sjablonen, interne links, concepten (autosave) en de prullenbak. Geschreven
|
||||
voor redacteuren en beheerders die dagelijks inhoud beheren.
|
||||
|
||||
## De kennisboom
|
||||
|
||||
- De kennisboom staat links in de zijbalk en toont eerst alleen de hoofdpagina's.
|
||||
Onderliggende pagina's worden pas opgehaald wanneer u een tak openklapt — ook een
|
||||
boom met tienduizenden pagina's blijft zo direct bruikbaar.
|
||||
- Klik op een pagina om ze te openen. Klik op het driehoekje om een tak met
|
||||
subpagina's open of dicht te klappen.
|
||||
- Op een smal (mobiel) scherm is de zijbalk standaard verborgen. Gebruik de
|
||||
knop "Navigatie" bovenaan om de kennisboom en de knop "Nieuwe pagina" te openen; ze
|
||||
sluit automatisch zodra u een pagina kiest, zodat er op mobiel altijd maar één
|
||||
hoofdvenster tegelijk zichtbaar is.
|
||||
|
||||
## Een pagina aanmaken
|
||||
|
||||
1. Klik op **Nieuwe pagina** (zijbalk, of via **Subpagina maken** op een bestaande
|
||||
pagina om er meteen een onderliggende pagina van te maken).
|
||||
2. Vul een titel in.
|
||||
3. Kies optioneel een **sjabloon**: Studienotitie, Runbook, Architectuurbeslissing
|
||||
(ADR) of Probleemoplossing. Een sjabloon vult de inhoud met een bruikbare
|
||||
startstructuur; u kunt die nadien vrij aanpassen. Kiest u geen sjabloon, dan schrijft
|
||||
u vrije Markdown-inhoud.
|
||||
4. Klik op **Pagina publiceren**.
|
||||
|
||||
Een nieuwe pagina is direct zichtbaar voor iedereen met leesrechten op die plaats in de
|
||||
boom.
|
||||
|
||||
> **V2-R1-update (2026-08-03):** voegt u vóór de eerste publicatie een bijlage toe aan
|
||||
> een nieuwe pagina (via de werkbalk of door een bestand in de editor te slepen), dan
|
||||
> gebeurt dat nu volledig veilig: het bestand wordt meteen definitief opgeslagen en op
|
||||
> de cursorpositie ingevoegd, en pas bij **Publiceren** wordt de pagina in één stap
|
||||
> zichtbaar — inclusief alle al toegevoegde bijlagen. Mislukt een upload, dan blijft de
|
||||
> pagina onzichtbaar en kunt u het gewoon opnieuw proberen; eerder gelukte bijlagen
|
||||
> gaan niet verloren. Er bestaat dus geen tussentoestand meer met een zichtbare pagina
|
||||
> en een kapotte bijlagelink. Zie `docs/adr/ADR-025-v2-r1-data-integrity-remediation.md`.
|
||||
|
||||
## Een pagina bewerken
|
||||
|
||||
1. Open de pagina en klik op **Bewerken**.
|
||||
2. Pas titel, inhoud, documenttype of status aan.
|
||||
3. Klik op **Wijzigingen publiceren**.
|
||||
|
||||
Elke publicatie verhoogt de revisie van de pagina. De vorige inhoud blijft bewaard —
|
||||
volledige revisiegeschiedenis met terugzetten volgt in M3.
|
||||
|
||||
### Versieconflicten
|
||||
|
||||
Als iemand anders de pagina publiceerde terwijl u aan het bewerken was, toont de
|
||||
toepassing dat expliciet in plaats van de wijziging van de ander stilzwijgend te
|
||||
overschrijven: u kiest dan tussen **Gebruik gepubliceerde versie** (uw bewerkvenster
|
||||
wordt bijgewerkt met de nieuwste inhoud) of **Behoud mijn versie (overschrijven)** (uw
|
||||
tekst wordt alsnog gepubliceerd, bovenop de nieuwste revisie). Niets gaat verloren: uw
|
||||
getypte tekst blijft zichtbaar totdat u zelf kiest.
|
||||
|
||||
## Concepten (automatisch opslaan)
|
||||
|
||||
Terwijl u schrijft, wordt uw werk enkele seconden na elke wijziging automatisch
|
||||
opgeslagen als een persoonlijk concept — zichtbaar alleen voor uzelf, nooit voor andere
|
||||
gebruikers, en het overschrijft nooit de gepubliceerde pagina. Sluit u de browser per
|
||||
ongeluk of navigeert u weg, dan biedt de toepassing bij het opnieuw openen van de
|
||||
bewerkpagina aan om dat concept terug te laden.
|
||||
|
||||
## Interne links
|
||||
|
||||
Verwijs naar een andere pagina met dubbele blokhaken en de paginatitel:
|
||||
`[[Titel van de doelpagina]]`. Bij publicatie herkent de toepassing deze verwijzing en
|
||||
koppelt ze aan de betreffende pagina — niet aan de tekst. Wordt de doelpagina later
|
||||
hernoemd of verplaatst, dan blijft de link naar dezelfde pagina wijzen.
|
||||
|
||||
- Bestaat er geen pagina met die titel, of zijn er meerdere pagina's met dezelfde titel,
|
||||
dan blijft de tekst gewoon zichtbaar als platte tekst (`[[Titel]]`) in plaats van een
|
||||
klikbare link — er wordt nooit een kapotte of verkeerde link gemaakt.
|
||||
- Gebruik `[[Titel|Zichtbare tekst]]` om een andere weergavetekst dan de paginatitel te
|
||||
tonen.
|
||||
|
||||
## Pagina's verplaatsen, ordenen, naar de prullenbak en herstellen
|
||||
|
||||
- Een pagina naar de prullenbak verplaatsen kan via **Naar prullenbak** op de
|
||||
paginaweergave. De pagina verdwijnt uit de kennisboom, maar wordt niet definitief
|
||||
verwijderd.
|
||||
- **Herstellen** haalt een pagina terug uit de prullenbak.
|
||||
- Een pagina in de prullenbak kan niet bewerkt worden totdat ze hersteld is.
|
||||
- Verplaatsen tussen ouders en herordenen tussen zusterpagina's gebeurt via de API
|
||||
(`POST /api/v1/pages/{pageId}/move`); een sleep-en-neerzet-interactie in de zijbalk is
|
||||
nog niet gebouwd en volgt in een latere verfijning.
|
||||
|
||||
## Toegankelijkheid
|
||||
|
||||
Elke actie in dit hoofdstuk — pagina's aanmaken, bewerken, publiceren, naar de
|
||||
prullenbak verplaatsen, herstellen en tussen schrijf-/voorbeeldweergave wisselen — is
|
||||
volledig met het toetsenbord te bedienen en voldoet aan WCAG 2.2 AA (geverifieerd met
|
||||
axe-core tegen de echte, draaiende toepassing, op zowel een desktop- als een
|
||||
mobiel-viewport).
|
||||
@@ -0,0 +1,95 @@
|
||||
# Projecten, architectuurbeslissingen en runbooks
|
||||
|
||||
Deze gids beschrijft de M5-functionaliteit: projectdossiers, architectuurbeslissingen
|
||||
(ADR's) en runbooks, bereikbaar via **Projecten** in de hoofdnavigatie. Geschreven voor
|
||||
redacteuren en beheerders.
|
||||
|
||||
## Projecten
|
||||
|
||||
Een project is geen kopie van bestaande pagina's — het is een gestructureerd dossier
|
||||
dat verwijst naar pagina's, beslissingen, runbooks, updates en mijlpalen.
|
||||
|
||||
1. Klik op **Projecten** in de hoofdnavigatie, daarna op **Nieuw project**.
|
||||
2. Vul naam, samenvatting, prioriteit en de huidige stand in. Het project start altijd
|
||||
in status **Concept**.
|
||||
3. Op de projectpagina ziet u in één overzicht: de huidige stand, gekoppelde pagina's,
|
||||
beslissingen, mijlpalen en de meest recente updates.
|
||||
|
||||
### Status wijzigen
|
||||
|
||||
De statusknoppen tonen alleen de overgangen die op dit moment zijn toegestaan (bijvoorbeeld
|
||||
**Concept → Gepland**, **Actief → Geblokkeerd**). Een project dat is **Gearchiveerd**,
|
||||
is bewust een eindstation in deze versie; archiveren gebeurt altijd expliciet en is nooit
|
||||
hetzelfde als verwijderen.
|
||||
|
||||
### Pagina's koppelen
|
||||
|
||||
Een pagina blijft altijd de canonieke plaats voor de inhoud. Een project koppelt er
|
||||
alleen naar, met een rol (bijvoorbeeld **Architectuur**, **Beveiliging**,
|
||||
**Probleemoplossing**). Een pagina ontkoppelen van een project verwijdert nooit de
|
||||
pagina zelf.
|
||||
|
||||
### Updates
|
||||
|
||||
Een update is een tijdlijnitem: voortgang, een oplossing, een release, een risico, enz.
|
||||
Updates worden nooit achteraf gewijzigd — een correctie voegt een nieuwe update toe die
|
||||
verwijst naar de oorspronkelijke, waarna die oorspronkelijke update automatisch als
|
||||
**Vervangen** wordt gemarkeerd. De verificatiestatus (**Gemeld** / **Geverifieerd** /
|
||||
**Vervangen**) maakt altijd duidelijk of een claim al bevestigd is of nog niet.
|
||||
|
||||
### Mijlpalen
|
||||
|
||||
Mijlpalen zijn projectspecifiek en hebben geen verband met de milestones (M0–M9) van dit
|
||||
bouwproces zelf. Wijzig de status van een mijlpaal via het keuzemenu naast de mijlpaal.
|
||||
|
||||
## Architectuurbeslissingen (ADR's)
|
||||
|
||||
Een architectuurbeslissing is een gewone pagina (documenttype
|
||||
**Architectuurbeslissing**) met een extra statusveld erbovenop, zodat beslissingen
|
||||
doorzoekbaar, historisch consistent en onderling te koppelen zijn.
|
||||
|
||||
1. Klik op het tabblad **Architectuurbeslissingen**, daarna op **Nieuwe beslissing**.
|
||||
2. Elke nieuwe beslissing start als **Voorgesteld** en krijgt automatisch een
|
||||
volgnummer (ADR-1, ADR-2, …), per project of, als er geen project gekoppeld is,
|
||||
werkruimtebreed.
|
||||
3. Een redacteur kan een voorgestelde beslissing **accepteren**, **afwijzen** of
|
||||
**intrekken**.
|
||||
|
||||
### Een beslissing vervangen
|
||||
|
||||
Om een eerder geaccepteerde beslissing te vervangen: maak een nieuwe beslissing aan die
|
||||
verwijst naar de oude, en accepteer de nieuwe. Zodra de nieuwe beslissing wordt
|
||||
geaccepteerd, wordt de oude automatisch op **Vervangen** gezet, met een verwijzing in
|
||||
beide richtingen — zo blijft de volledige lijn van beslissingen zichtbaar en navigeerbaar,
|
||||
en verdwijnt de oude beslissing nooit.
|
||||
|
||||
De inhoud (context, overwegingen, gevolgen) bewerkt u via **Open onderliggende pagina om
|
||||
inhoud te bewerken** — dat opent de gewone pagina-editor met revisiegeschiedenis, exact
|
||||
zoals bij elke andere pagina.
|
||||
|
||||
## Runbooks
|
||||
|
||||
Een runbook is een menselijk uit te voeren procedure. Het platform voert zelf nooit
|
||||
commando's uit — het toont en valideert alleen de structuur.
|
||||
|
||||
1. Klik op het tabblad **Runbooks**, daarna op **Nieuwe runbook**.
|
||||
2. Kies een risiconiveau (**Laag**/**Gemiddeld**/**Hoog**/**Kritiek**) en geef aan of een
|
||||
onderhoudsvenster vereist is.
|
||||
3. Werk de inhoud (doel, vereisten, stappen, validatie, rollback) uit via de gewone
|
||||
pagina-editor.
|
||||
|
||||
### Valideren
|
||||
|
||||
Klik op **Valideren tegen huidige revisie** nadat u de procedure hebt gecontroleerd. Dit
|
||||
registreert wie de validatie deed en tegen welke inhoudsversie. Zodra de onderliggende
|
||||
pagina daarna opnieuw wordt bewerkt, toont de runbook automatisch een duidelijke
|
||||
waarschuwing dat de validatie verouderd is — die waarschuwing verdwijnt pas na een
|
||||
nieuwe validatie tegen de bijgewerkte inhoud.
|
||||
|
||||
### Veiligheid
|
||||
|
||||
- Commando's worden altijd als platte tekst of code getoond, nooit als uitvoerbare
|
||||
knop.
|
||||
- Er is geen terminalkoppeling en geen automatische invulling van geheimen.
|
||||
- Gevoelige waarden hoort u als plaatshouder te markeren in de tekst zelf (bijvoorbeeld
|
||||
`<wachtwoord invullen>`), nooit als echte waarde.
|
||||
@@ -0,0 +1,158 @@
|
||||
# Service accounts en automatisering
|
||||
|
||||
Deze gids beschrijft scoped service accounts en tokens voor geautomatiseerde toegang
|
||||
tot de API. Beheerders kunnen een tijdelijk, minimaal gemachtigd importtoken via
|
||||
**Beheer** in de webapplicatie aanmaken en intrekken. De volledige levenscyclus blijft
|
||||
ook via de API beschikbaar voor gecontroleerde automatisering.
|
||||
|
||||
## Wat is een service account?
|
||||
|
||||
Een service account is een niet-persoonlijke identiteit voor een geautomatiseerd
|
||||
systeem (bijvoorbeeld een CI/CD-pipeline of, in de toekomst, een MCP-server) dat via de
|
||||
API met het platform moet praten zonder een gewone gebruikersaanmelding te gebruiken.
|
||||
|
||||
- Een service account heeft één of meer **tokens**. Elk token heeft zijn eigen
|
||||
**scopes** (rechten), een optionele vervaldatum en kan onafhankelijk van andere
|
||||
tokens worden ingetrokken.
|
||||
- Een token bewijst zichzelf met een `Authorization: Bearer <token>`-header, in plaats
|
||||
van een sessiecookie.
|
||||
- Scopes verruimen nooit de gewone workspace-rechten — ze beperken alleen wat een reeds
|
||||
geauthenticeerde aanroep mag proberen. Een token met alleen `knowledge:search` kan
|
||||
nooit een pagina aanmaken, ongeacht welke rol de aanmakende beheerder zelf heeft.
|
||||
|
||||
Service accounts aanmaken, tonen, tokens uitgeven en intrekken kan **alleen** door een
|
||||
ingelogde beheerder (rol Eigenaar/Beheerder), via een gewone, cookie-geauthenticeerde
|
||||
aanroep met CSRF-bescherming — nooit door een service account zelf. Een service account
|
||||
kan dus nooit zijn eigen rechten verruimen of een nieuw token voor zichzelf aanmaken.
|
||||
|
||||
## Beschikbare scopes
|
||||
|
||||
| Scope | Betekenis |
|
||||
| --- | --- |
|
||||
| `knowledge:read` | Pagina's lezen |
|
||||
| `knowledge:search` | Zoeken in de kennisbank |
|
||||
| `pages:read` | Individuele pagina's ophalen |
|
||||
| `pages:write` | Pagina's aanmaken/bewerken |
|
||||
| `projects:read` | Projectdossiers en projectcontext lezen |
|
||||
| `projects:write` | Projecten bewerken |
|
||||
| `project-updates:append` | Een update aan een project toevoegen |
|
||||
| `decisions:read` | Architectuurbeslissingen lezen |
|
||||
| `decisions:write` | Architectuurbeslissingen aanmaken |
|
||||
| `runbooks:read` | Runbooks lezen |
|
||||
| `runbooks:write` | Runbooks aanmaken |
|
||||
| `attachments:read` / `attachments:write` | Bijlagen lezen / uploaden |
|
||||
| `imports:read` / `imports:execute` | Importstatus lezen / een import uitvoeren |
|
||||
| `audit:read` | Audittrail lezen |
|
||||
| `system:read` | Systeeminformatie lezen |
|
||||
|
||||
Een aanvraag met een onbekende scope wordt geweigerd (HTTP 422) — er is geen manier om
|
||||
per ongeluk een niet-bestaande of verkeerd gespelde scope aan een token te koppelen.
|
||||
|
||||
## Een service account aanmaken
|
||||
|
||||
### Via de webapplicatie
|
||||
|
||||
1. Meld aan als beheerder en open **Beheer**.
|
||||
2. Kies onder **Serviceaccounts** een van de drie vaste profielen, afhankelijk van de
|
||||
taak:
|
||||
- **Importserviceaccount aanmaken (pagina's en bijlagen)** — uitsluitend
|
||||
`pages:read`, `pages:write`, `attachments:read` en `attachments:write`. Voor het
|
||||
generieke Markdown-/bijlage-publicatietraject (`tools/knowledge-ingestion/`).
|
||||
- **Automatiseringsserviceaccount aanmaken (infrastructuur, projecten,
|
||||
runbooks)** — uitsluitend `infrastructure:read`, `infrastructure:write`,
|
||||
`projects:read`, `projects:write`, `project-updates:append`, `runbooks:read` en
|
||||
`runbooks:write`. Voor het synchroniseren van gecureerde infrastructuurfeiten
|
||||
(`POST /inventory/curated-package`), het beheren van redactionele
|
||||
serviceprofielen, en het publiceren van projectdossiers en runbooks.
|
||||
- **Migratieserviceaccount aanmaken (LeafWiki-import)** — uitsluitend
|
||||
`imports:read` en `imports:execute`. Voor een eenmalige, gecontroleerde
|
||||
LeafWiki-migratie (`POST /admin/imports/preflight`/`/execute`/`/rollback`).
|
||||
Deliberately gescheiden van het automatiseringsprofiel: een token voor dagelijkse
|
||||
infrastructuur-/projectpublicatie mag nooit ook een migratie kunnen starten.
|
||||
3. Kopieer het eenmalig getoonde token onmiddellijk naar de automatisering of een
|
||||
geheimenbeheerder.
|
||||
4. Trek het token na gebruik in via dezelfde beheerpagina.
|
||||
|
||||
Geen van beide vaste profielen dekt elke mogelijke automatisering — voor een taak die
|
||||
een andere scopecombinatie nodig heeft (bijvoorbeeld alleen zoeken, of alleen
|
||||
architectuurbeslissingen), gebruikt een beheerder de API hieronder met exact de
|
||||
benodigde scopes, nooit ruimer dan nodig.
|
||||
|
||||
### Via de API
|
||||
|
||||
```bash
|
||||
curl -X POST https://hub.example/api/v1/service-accounts \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-CSRF-Token: <csrf-token-van-huidige-sessie>" \
|
||||
-b cookies.txt \
|
||||
-d '{"name":"CI-bot","description":"Leest en doorzoekt de kennisbank vanuit de CI-pipeline.","scopes":["knowledge:search","pages:read"]}'
|
||||
```
|
||||
|
||||
Het antwoord bevat het **ruwe token exact één keer**:
|
||||
|
||||
```json
|
||||
{
|
||||
"serviceAccountId": "…",
|
||||
"tokenId": "…",
|
||||
"rawToken": "ikh_<publieke-id>_<geheim>"
|
||||
}
|
||||
```
|
||||
|
||||
Bewaar dit token onmiddellijk in een geheimenbeheerder. Het platform slaat nooit de
|
||||
ruwe waarde op — alleen een cryptografische hash — en kan het dus nadien nooit meer
|
||||
tonen. Is het token kwijt, dan moet een nieuw token worden uitgegeven en het oude
|
||||
worden ingetrokken.
|
||||
|
||||
## Een service account gebruiken
|
||||
|
||||
```bash
|
||||
curl https://hub.example/api/v1/search?q=backup \
|
||||
-H "Authorization: Bearer ikh_<publieke-id>_<geheim>"
|
||||
```
|
||||
|
||||
Een aanroep zonder de vereiste scope wordt geweigerd — de mutatie of leesactie vindt
|
||||
nooit plaats, ook al is het token op zich geldig.
|
||||
|
||||
## Tokens roteren
|
||||
|
||||
Geef eerst een nieuw token uit, werk de client bij, en trek pas daarna het oude token
|
||||
in. Een service account is op deze manier nooit tijdelijk onbruikbaar tijdens rotatie:
|
||||
|
||||
```bash
|
||||
curl -X POST https://hub.example/api/v1/service-accounts/<serviceAccountId>/tokens \
|
||||
-H "Content-Type: application/json" -H "X-CSRF-Token: …" -b cookies.txt \
|
||||
-d '{"scopes":["knowledge:search","pages:read"]}'
|
||||
```
|
||||
|
||||
## Een token intrekken
|
||||
|
||||
```bash
|
||||
curl -X POST https://hub.example/api/v1/service-accounts/tokens/<tokenId>/revoke \
|
||||
-H "X-CSRF-Token: …" -b cookies.txt
|
||||
```
|
||||
|
||||
Intrekking is onmiddellijk van kracht: de eerstvolgende aanroep met dat token wordt
|
||||
geweigerd, zonder wachttijd.
|
||||
|
||||
## Herhaalde aanroepen veilig maken (Idempotency-Key)
|
||||
|
||||
Een aanmaak- of toevoegaanroep (bijvoorbeeld een nieuwe pagina, beslissing, runbook of
|
||||
projectupdate) accepteert een optionele `Idempotency-Key`-header. Een netwerkfout
|
||||
tijdens een eerdere poging kan zo veilig opnieuw worden geprobeerd zonder het risico op
|
||||
een dubbele pagina of dubbele update:
|
||||
|
||||
- Dezelfde sleutel met exact dezelfde aanvraaginhoud: het eerder gegeven antwoord wordt
|
||||
gewoon opnieuw teruggegeven, zonder de actie nogmaals uit te voeren.
|
||||
- Dezelfde sleutel met een andere aanvraaginhoud: dit wordt geweigerd (HTTP 409) — er
|
||||
wordt nooit stilzwijgend iets anders uitgevoerd onder een hergebruikte sleutel.
|
||||
|
||||
## Projectcontext voor automatisering
|
||||
|
||||
`GET /api/v1/projects/{projectId}/context` geeft een compacte, begrensde momentopname
|
||||
van een project (huidige stand, recente updates, actieve mijlpalen, beslissingen,
|
||||
runbooks, documenten) met stabiele citaten (`kind`, `id`, `revisie`, `titel`, pad,
|
||||
laatst bijgewerkt) in één aanroep — bedoeld voor een toekomstige MCP-server die snel
|
||||
projectcontext nodig heeft zonder tientallen losse aanroepen. Wanneer er meer items zijn
|
||||
dan het maximum, toont het antwoord expliciet `truncation.truncated: true` met per
|
||||
onderdeel het weggelaten aantal — er wordt nooit stilzwijgend informatie weggelaten
|
||||
zonder dat te melden.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Verwijderen van een bronbatch
|
||||
|
||||
De API kan een expliciet geïdentificeerde externe bronbatch definitief verwijderen
|
||||
wanneer die buiten de standaard importjob-rollback is gepubliceerd. Dit is uitsluitend
|
||||
voor een Administrator en nooit een normale wiki-actie.
|
||||
|
||||
## Voorwaarden
|
||||
|
||||
1. Maak en herstel-test eerst een verse applicatiebackup naar een afzonderlijke
|
||||
PostgreSQL-doeldatabase.
|
||||
2. Stel een reviewed, secretvrije lijst met uitsluitend de eerder vastgelegde
|
||||
page-ID's én hun gevalideerde SHA-256-contenthash samen. Gebruik geen titel,
|
||||
pad of zoekresultaat als primaire grens. De API blokkeert elke pagina waarvan
|
||||
de huidige hash niet meer overeenkomt met het batchbewijs.
|
||||
3. Roep `POST /api/v1/admin/source-batches/purge/dry-run` aan met de batch-ID,
|
||||
bronnaam en die lijst.
|
||||
4. Stop wanneer `safe` onwaar is. Blokkerende gevallen zijn onder meer ontbrekende
|
||||
of niet-gemarkeerde pagina's, aanvullende bronpagina's buiten de lijst, afgeleide
|
||||
pagina's zonder betrouwbare koppeling, backlinks vanuit behouden pagina's en
|
||||
project-/runbookkoppelingen.
|
||||
5. Gebruik uitsluitend de ongewijzigde `confirmationHash` uit een groene dry-run in
|
||||
`POST /api/v1/admin/source-batches/purge/execute`.
|
||||
|
||||
De execute-call draait de databaseverwijdering transactioneel uit. Attachmentblobs
|
||||
worden alleen verwijderd als er na die transactie geen references meer bestaan én de
|
||||
fysieke bytes opnieuw dezelfde SHA-256 opleveren. Een fout bij fysiek opruimen laat
|
||||
hoogstens een retriable orphan achter; de toepassing verwijdert nooit een blob waar een
|
||||
behouden database-reference nog naar wijst.
|
||||
|
||||
## Validatie na afloop
|
||||
|
||||
Controleer met een nieuwe dry-run/leesinventarisatie dat er geen bronpagina's of
|
||||
technische brontags meer bestaan. Herbouw zoekprojecties door de normale
|
||||
PostgreSQL-trigger op de verwijdering te laten werken; er is geen tweede zoekindex om
|
||||
apart te verwijderen. Valideer behouden pagina's, gedeelde attachments, gebruikers,
|
||||
projecten en runbooks apart. Maak daarna een nieuwe schone backup en test ook die
|
||||
restore voordat een tijdelijke backup met verwijderde inhoud wordt opgeruimd.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Zoeken, revisiegeschiedenis, verwijzingen en labels
|
||||
|
||||
Deze gids beschrijft de M3-functionaliteit: zoeken, revisiegeschiedenis bekijken en
|
||||
herstellen, zien welke pagina's naar een pagina linken, labels, en het definitief
|
||||
opruimen van de prullenbak. Geschreven voor redacteuren en beheerders.
|
||||
|
||||
## Zoeken
|
||||
|
||||
Klik op **Zoeken** bovenaan om de zoekpagina te openen.
|
||||
|
||||
- Zoeken doorzoekt titels, labels en de inhoud van pagina's. Een exacte titel of
|
||||
woordgroep weegt zwaarder mee dan een los woord dat toevallig ergens voorkomt.
|
||||
- Zoeken is tolerant voor kleine typfouten in een titel (bijvoorbeeld
|
||||
"Trubleshootng" vindt nog steeds "Troubleshooting ...").
|
||||
- Gebruik het filter **Label** om alleen pagina's met een specifiek label te tonen, of
|
||||
**Documenttype** om te filteren op bijvoorbeeld enkel runbooks.
|
||||
- Zoekresultaten tonen nooit pagina's die in de prullenbak staan.
|
||||
- Een fragment van de gevonden tekst wordt getoond, met de gevonden term
|
||||
gemarkeerd.
|
||||
|
||||
## Labels
|
||||
|
||||
- Voeg labels toe aan een pagina via het veld **Labels** in de bewerkpagina, gescheiden
|
||||
door komma's (bijvoorbeeld `netwerk, archief`).
|
||||
- Labels worden getoond als chips bovenaan de pagina.
|
||||
- Klik in de zoekpagina op het filterveld **Label** en typ de naam van een label om
|
||||
alleen pagina's met dat label te zien.
|
||||
|
||||
## Revisiegeschiedenis
|
||||
|
||||
Elke publicatie van een pagina bewaart de vorige inhoud als een onveranderlijke
|
||||
revisie — niets gaat ooit verloren, ook niet wanneer u een pagina hersteld naar een
|
||||
oudere versie.
|
||||
|
||||
1. Open een pagina en klap **Revisiegeschiedenis** open, onderaan de pagina.
|
||||
2. Klik op een revisie om de inhoud van dat moment te bekijken.
|
||||
3. Klik op **Deze revisie herstellen** om die inhoud opnieuw te publiceren als de
|
||||
nieuwste versie. De versie die u zojuist verliet, blijft ook bewaard als revisie —
|
||||
er wordt nooit geschiedenis overschreven of verwijderd.
|
||||
|
||||
## Pagina's die hierheen linken
|
||||
|
||||
Klap **Pagina's die hierheen linken** open, onderaan een pagina, om te zien welke
|
||||
andere pagina's naar deze pagina verwijzen via een `[[interne link]]`. Deze lijst blijft
|
||||
correct nadat de huidige pagina van titel, locatie in de boom, of URL-pad verandert.
|
||||
|
||||
## Prullenbak definitief opruimen (alleen beheerder)
|
||||
|
||||
Een pagina die naar de prullenbak is verplaatst, blijft daar minstens 30 dagen bewaard
|
||||
en is binnen die periode altijd herstelbaar. Na die periode kan een beheerder de
|
||||
prullenbak definitief opruimen via `POST /api/v1/admin/trash/purge` (de webinterface
|
||||
hiervoor volgt in een latere milestone; de API is al volledig functioneel en getest).
|
||||
|
||||
- Alleen pagina's waarvan de bewaarperiode al verstreken is, worden verwijderd.
|
||||
- Een pagina die nog binnen de bewaarperiode valt, blijft ongemoeid — er is geen manier
|
||||
om die termijn via deze aanroep te omzeilen.
|
||||
- Dit is de enige plaats in de toepassing waar inhoud definitief en onomkeerbaar
|
||||
verdwijnt; de gewone webinterface heeft hiervoor geen knop.
|
||||
Reference in new issue
Block a user