added mermaid and a lot of cmap changes
This commit is contained in:
@@ -17,6 +17,8 @@ De database bevat zowel de huidige toestand als de auditgeschiedenis. De browser
|
||||
| `attachment_references` | Huidige en historische verwijzingen vanuit paginaversies |
|
||||
| `concept_maps` | Actuele titel, JSONB-document en versieteller per CMap |
|
||||
| `concept_map_versions` | Expliciete CMap-snapshots en maximaal vijf handmatige opslagversies per CMap |
|
||||
| `concept_definitions` | Wiki-brede inhoud per stabiele `conceptId`; plaatsing en opmaak blijven in het CMap-document |
|
||||
| `people` | Wiki-breed register van actieve en inactieve namen voor getypeerde persoonstags |
|
||||
| `password_reset_tokens` | Gehashte, tijdelijke en eenmalige herstelcodes |
|
||||
| `wiki_settings` | Beheerinstellingen, momenteel vooral e-mail |
|
||||
| `wiki_schema` | Geïnstalleerde migratieversie |
|
||||
@@ -39,7 +41,7 @@ Een paginaopslag is één atomaire transactie:
|
||||
6. Vervang huidige bijlageverwijzingen en leg historische verwijzingen voor de nieuwe versie vast.
|
||||
7. Commit alles, of niets.
|
||||
|
||||
Een CMap-opslag volgt voor de actuele projectie hetzelfde kernpatroon: rij vergrendelen, versienummer vergelijken en actuele JSONB bijwerken. Autosave verhoogt wel het optimistische versienummer, maar maakt geen historieregel. Een expliciete opslag voegt een volledige toestand aan `concept_map_versions` toe en verwijdert oudere handmatige versies boven de grens van vijf. Benoemde snapshots vallen niet onder die grens.
|
||||
Een CMap-opslag volgt voor de actuele projectie hetzelfde kernpatroon: rij vergrendelen, versienummer vergelijken en actuele JSONB bijwerken. In dezelfde transactie worden de aangeleverde inhoudelijke velden op `conceptId` in `concept_definitions` gezet. Een `conceptId` is een kale, lowercase en globaal unieke UUID; hij bevat bewust geen CMap-slug. De getrimde, hoofdletterongevoelige conceptnaam is wiki-breed uniek; een tweede plaatsing met dezelfde naam krijgt direct de bestaande id. Het opgeslagen CMap-document bevat zelf geen inhoudelijke kopie: `items[]` bewaart alleen structuur en opmaak en `concepts[]` bevat uitsluitend `{id}`-verwijzingen. `concept_definitions` is de enige persistente bron voor naam, samenvatting, aspecten, personen, koppelingen, afbeelding en toelichtingspagina. Bij uitlezen hydrateert de server die verwijzingen voor de editor. Ieder item behalve een verbindingszin is een plaatsing van een concept; `submap`, `page` en `concept` zijn lokale structurele rollen en geen afzonderlijke conceptsoorten. Positie, afmetingen, kleuren, typografie en structurele rol kunnen per plaatsing verschillen. De CMap zelf houdt haar stabiele, leesbare `concept_maps.slug`; die slug identificeert de kaart en staat los van de concept-UUID's. Autosave verhoogt wel het optimistische versienummer, maar maakt geen historieregel. Een expliciete opslag voegt een volledige toestand aan `concept_map_versions` toe en verwijdert oudere handmatige versies boven de grens van vijf. Benoemde snapshots vallen niet onder die grens.
|
||||
|
||||
## Waarom volledige snapshots
|
||||
|
||||
@@ -49,10 +51,16 @@ De prijs is lineaire databasegroei met het aantal versies maal de documentgroott
|
||||
|
||||
## Afgeleide gegevens
|
||||
|
||||
`pages.search_document`, `todo_items` en `attachment_references.current_reference` zijn afgeleide gegevens. Zij moeten in dezelfde transactie als hun bron worden aangepast. Een los herstelcommando mag ze opnieuw kunnen opbouwen, maar gewone reads mogen niet afhankelijk zijn van een toevallig later achtergrondproces.
|
||||
`pages.search_document`, `todo_items` en `attachment_references.current_reference` zijn afgeleide gegevens. Zij moeten in dezelfde transactie als hun bron worden aangepast. Een los herstelcommando mag ze opnieuw kunnen opbouwen, maar gewone reads mogen niet afhankelijk zijn van een toevallig later achtergrondproces. Concepten met het aspect `TODO` worden daarentegen rechtstreeks uit `concept_definitions` geselecteerd en met de pagina-todo's samengevoegd; daarvoor bestaat bewust geen tweede index.
|
||||
|
||||
De gecombineerde navigatiegraaf is momenteel volledig afgeleid in de browser. Zij wordt niet als databasegraaf bewaard.
|
||||
|
||||
## CMap-uitwisselingsformaat
|
||||
|
||||
Het versieerbare JSON-formaat `racket-wiki-cmap-bundle` volgt dezelfde scheiding als de database. `cmaps[]` bevat per stabiele slug het volledige structuur- en opmaakdocument, `concepts[]` bevat de gedeelde inhoud per UUID en `pages[]` bevat de actuele titel, Markdown, tags en daarin gebruikte attachments van gekoppelde wiki- en uitlegpagina's. De binaire inhoud staat base64-gecodeerd bij de pagina. Daardoor kan één concept op meerdere kaarten dezelfde inhoud houden terwijl positie, formaat, kleuren en typografie per plaatsing behouden blijven. Verbindingszinnen en connectoren verwijzen naar lokale item-id's en blijven dus bij hun diagramcontext.
|
||||
|
||||
Een nieuw extern gegenereerd concept mag een tijdelijke `new:<naam>`-identiteit hebben, maar moet altijd in minstens één `items[]`-plaatsing met coördinaten voorkomen. De opslaglaag vervangt die tijdelijke identiteit bij de eerste import door een Racket-gegenereerde UUID en hergebruikt die via de wiki-breed unieke conceptnaam in volgende kaarten. Het JSON Schema staat onder `/schemas/racket-wiki-cmap-bundle-v1.schema.json`. Pagina- en CMap-versiegeschiedenis horen niet bij versie 1; alleen de actuele gekoppelde pagina-inhoud en haar actuele attachmentverwijzingen worden meegenomen.
|
||||
|
||||
## Bijlagen
|
||||
|
||||
Een upload hoort bij de id van de eigenaarpagina en krijgt een veilige opgeslagen naam. PostgreSQL bewaart zowel metadata als bytes. Markdown verwijst via de pagina en opgeslagen naam. Huidige en historische referenties worden afzonderlijk gevolgd, zodat beheer kan zien of een bestand alleen nog in oude versies voorkomt.
|
||||
@@ -77,6 +85,8 @@ De volgende regels mogen niet alleen in de browser staan:
|
||||
|
||||
- iedere actuele paginaversie heeft een overeenkomstige onveranderlijke snapshot;
|
||||
- CMap-autosave wijzigt alleen de actuele projectie; CMap-historie bevat alleen snapshots en maximaal vijf handmatige versies;
|
||||
- alle actuele plaatsingen met dezelfde `conceptId` lezen hun inhoud uit dezelfde `concept_definitions`-rij;
|
||||
- iedere actuele `conceptId` is een kale lowercase UUID; de CMap-slug blijft afzonderlijk bewaard;
|
||||
- versienummers nemen per object strikt toe;
|
||||
- een stale editor overschrijft geen nieuwere toestand;
|
||||
- e-mailadressen zijn hoofdletterongevoelig uniek wanneer ingevuld;
|
||||
|
||||
@@ -46,6 +46,32 @@ Iedere serveropslag controleert opnieuw het basisversienummer en schrijft de act
|
||||
|
||||
Wanneer een actueel CMap-concept een `pageSlug` heeft, toont de gelezen wikipagina onder de inhoud een verwijzing naar dat concept. Plaatsingen worden op `conceptId` gegroepeerd en iedere betrokken CMap is rechtstreeks aanklikbaar. Alleen actuele, niet-gearchiveerde CMap-documenten tellen mee; historische CMap-versies leveren geen navigatielinks op.
|
||||
|
||||
Een CMap bewaart exportmetadata met tags, een samenvatting en een optionele uitlegpagina. De Markdown-export volgt gekoppelde CMaps tot de gekozen diepte, breekt cycli af en kan gekoppelde wiki- en conceptbeschrijvingspagina's als bijlage opnemen. Een persoon bij een concept is een getypeerde tag met type `person`. De personenlijst is wiki-breed; deactiveren verbergt een naam voor nieuwe selecties maar verandert bestaande CMap-documenten niet.
|
||||
|
||||
Een versleept bron- of doeluiteinde van een CMap-connector wijzigt zowel de zichtbare lijn als de
|
||||
logische `sourceId`/`targetId`-relatie. Submapprojectie mag alleen zichtbare eindpunten vervangen en
|
||||
mag een handmatige relatiebewerking bij inklappen of uitklappen niet terugdraaien. Een eindpunt dat
|
||||
op lege ruimte of op het andere uiteinde wordt losgelaten, keert terug naar de laatste geldige
|
||||
relatie.
|
||||
|
||||
Bij navigatie in afzonderlijk geopende sub-CMaps gaat de CMap-terugknop één niveau per actie terug.
|
||||
Een lokale ouder in `mapHistory` heeft voorrang op navigatie naar de bronroute van een afgeleide
|
||||
CMap. Alleen wanneer de wortel van die afgeleide kaart actief is, gaat terug naar de bron-CMap.
|
||||
|
||||
De vaste selectietoolbar naast het diagram biedt veelgebruikte selectieacties en groepslayout.
|
||||
Het laatst geselecteerde concept is het blauwe referentieobject: zijn maat, randen en middellijnen
|
||||
bepalen het doel voor gelijke breedte/hoogte en uitlijnen. Een klik op een reeds geselecteerd concept
|
||||
wisselt dit referentieobject zonder de meervoudige selectie op te heffen. Verticaal verdelen houdt
|
||||
het bovenste en onderste element vast; horizontaal verdelen houdt het meest linkse en rechtse
|
||||
element vast. De overige elementen krijgen in de gekozen richting gelijke tussenruimte. Iedere
|
||||
layoutactie wordt via dezelfde historie en autosave als slepen en handmatig schalen bewaard.
|
||||
|
||||
Relatiepijlen worden altijd in een lagere tekenlaag dan concepten en verbindingszinnen geplaatst.
|
||||
Ook wanneer een relatie wordt geselecteerd of naar voren wordt gehaald, blijft zij achter alle
|
||||
conceptkaarten. De hit-test gebruikt dezelfde laagprioriteit, zodat een achterliggende lijn geen
|
||||
klik kan afvangen op de kaart die haar bedekt. Tijdelijke eindpunthendels blijven wel bovenop liggen
|
||||
zolang een relatie wordt versleept.
|
||||
|
||||
## Zoeken, Recent en navigatiegraaf
|
||||
|
||||
Paginazoeken gebruikt een opgeslagen gewogen `tsvector` en GIN-index. CMap-zoeken verzamelt titel, slug, labels en synopses uit JSONB. Recent voegt de nieuwste pagina- en CMapwijzigingen samen.
|
||||
|
||||
@@ -6,6 +6,10 @@ De backendfuncties zijn meestal procedureel en krijgen `config` expliciet mee. D
|
||||
|
||||
Versie 0.2.93 introduceert wel tests in `architecture/import.rkt`. Die controleren de manifestset, interne paginalinks, CMap-embeds, unieke node-id's, connector-endpoints en de bronmarkeringen waarmee lokaal gewijzigde importinhoud wordt beschermd. Dit is een begin, geen voldoende dekking van de wiki.
|
||||
|
||||
Versie 0.2.100 voegt pure Node-tests toe voor de Markdown-export: dieptebegrenzing, cycli, optionele wikipagina's, persoonstags, leesbare relaties en afgeleide sub-CMapweergaven. De extractie van persoonsnamen uit CMap-documenten heeft daarnaast een kleine RackUnit-test; database- en browsergedrag blijven integratietestwerk.
|
||||
|
||||
Versie 0.2.115 voegt pure roundtrip- en validatietests toe voor het JSON-uitwisselingsformaat. Zij controleren dat coördinaten, afmetingen, kleuren, typografie, groepering en connectoren in de diagramlaag blijven, dat gedeelde conceptinhoud apart wordt opgeslagen en bij import wordt teruggekoppeld, en dat losse concepten, dubbele namen/slugs en ongeldige connector-endpoints worden geweigerd.
|
||||
|
||||
## Testpiramide voor racket-wiki
|
||||
|
||||
| Laag | Doel | Voorbeelden |
|
||||
@@ -47,6 +51,21 @@ Introduceer geen groot mockframework. Gewone procedures en expliciete parameters
|
||||
|
||||
Voor frontendcode zijn browsercomponenttests met een echte DOM geschikter dan het namaken van ieder element. De CMap-adapter moet met een klein vast document getest kunnen worden zonder de hele wiki te starten.
|
||||
|
||||
De JavaScript-regressietest `test/cmap-connector-rewire.test.js` simuleert het verslepen van een
|
||||
connector naar een andere verbindingszin, klapt de submap in en uit en controleert daarna zowel de
|
||||
tekenlaag als de geserialiseerde `sourceId`.
|
||||
|
||||
`test/cmap-submap-navigation.test.js` opent twee geneste afzonderlijke sub-CMaps en bewijst dat één
|
||||
terugactie alleen het diepste niveau verlaat en de tussenliggende kaart actief houdt.
|
||||
|
||||
`test/cmap-selection-layout.test.js` controleert dat het laatst geselecteerde referentieconcept de
|
||||
doelmaat en uitlijning bepaalt, naast horizontale en verticale verdeling, documentserialisatie en
|
||||
opname van layoutcommando's in Undo.
|
||||
|
||||
`test/cmap-layering.test.js` rendert concepten en een kruisende relatie in een kleine test-DOM. De
|
||||
test bewijst dat de relatie ook na `toFront()` een lagere z-index houdt en dat de hit-test op het
|
||||
kruispunt het concept selecteert in plaats van de verborgen relatie.
|
||||
|
||||
## Contract- en structuurcontroles
|
||||
|
||||
Naast functionele tests hoort de releasecontrole automatisch te verifiëren:
|
||||
|
||||
Reference in New Issue
Block a user