Files
markdown_to_skillstown/HANDOVER.md
T
kodi 410f37a008 feat(oa): add training-dir workflow and save flow for OnlineAcademy runner
Introduce a simpler training-based workflow for the OnlineAcademy Playwright runner.

Changes included:
- support --training-dir and automatic loading of content.md and training.json
- support --env-file so OA credentials no longer need manual shell sourcing
- resolve asset paths relative to the training directory
- improve human-readable review and execute output with step-by-step progress
- keep the browser open after execute when no save flag is used
- add optional --save flow that clicks 'Opslaan als' and then chooses 'Concept'
- add a concrete user guide for preparing and running training imports
- update handover documentation to reflect the current repo structure and workflow
- align the repo around trainings/<name>/content.md, training.json and assets/
- remove reliance on older pilot/test material in the documented main flow
2026-05-09 11:29:35 +02:00

421 lines
12 KiB
Markdown

# OnlineAcademy Handover
## Doel
Automatiseren van het opbouwen van elearningmodules in `create.onlineacademy.nl` met Markdown als bron, maar bewust via de zichtbare editor-UI met Playwright in plaats van via backend write-API's.
De gebruiker wil meekijken tijdens de browserrun en de oplossing moet veilig blijven in een productieomgeving.
## Onderzoeksuitkomst
### Platformstructuur
Live bevestigd:
- links: hoofdstukken/pagina's
- midden: paginacanvas met contentblokken
- rechts: blokbibliotheek en instellingen
Belangrijke UI-ankers die zijn aangetroffen:
- `data-testid="editor-main"`
- `data-testid="page-button"`
- blokken rechts zoals:
- `drag-block-text`
- `drag-block-heading`
- `drag-block-quote`
- `drag-block-table`
- `drag-block-multiple-choice`
- `drag-block-multiple-response`
- `drag-block-open-question`
- `drag-block-matching-pairs`
### Bloktypes
In UI gezien:
- `text`
- `heading`
- `quote`
- `table`
- `image`
- `video`
- `audio`
- `downloads`
- `links`
- `expert`
- `typeform`
- `multiple-choice`
- `multiple-response`
- `open-question`
- `matching-pairs`
### Backend read-only bevindingen
Er is bewust alleen read-only gekeken naar de data die de editor zelf ophaalt.
Belangrijke GET endpoints:
- `GET /authoring/v1.0/contents/course/{contentId}`
- `GET /authoring/v1.0/contents/version?externalId=...`
De echte cursusinhoud zit in `jsonContent` en heeft grofweg deze vorm:
```json
{
"chapters": [
{
"id": "...",
"title": "...",
"pages": [
{
"id": "...",
"pageType": "number",
"title": "...",
"blocks": [
{
"id": "...",
"type": "text",
"data": { "...": "..." }
}
]
}
]
}
],
"examPage": {
"enabled": false,
"blocks": [],
"examSettings": {
"showFeedbackAfterExam": false,
"questionPool": false,
"numberOfQuestions": 0,
"minimumPassingScore": 60
}
}
}
```
Deze kennis is alleen gebruikt voor begrip en mapping, niet voor writes.
## Gekozen oplossingsrichting
Niet API-first.
Wel:
- Markdown parser
- intern trainingsmodel
- UI-plan
- zichtbare Playwright runner
- review en execute via de editor-UI
- optionele save via `Opslaan als` -> `Concept`
Reden:
- minder risico in productie
- platformvalidaties blijven actief
- gebruiker kan meekijken
- geen directe backend writes
## Huidige bestanden
### Input / referentie
- [GEBRUIKSHANDLEIDING-IMPORT.md](/Users/nico/skillstown/GEBRUIKSHANDLEIDING-IMPORT.md)
### Gebruikersinvoer volgens huidige werkwijze
De beoogde gebruikersflow is nu:
- per training een eigen map onder `/Users/nico/skillstown/trainings/`
- vaste bestandsnamen binnen die map:
- `content.md`
- `training.json`
- `assets/`
Concreet voorbeeld dat nu is ingericht:
- [trainings/hoofdstuk-04-basisqueries/content.md](/Users/nico/skillstown/trainings/hoofdstuk-04-basisqueries/content.md)
- [trainings/hoofdstuk-04-basisqueries/training.json](/Users/nico/skillstown/trainings/hoofdstuk-04-basisqueries/training.json)
- [trainings/hoofdstuk-04-basisqueries/assets](/Users/nico/skillstown/trainings/hoofdstuk-04-basisqueries/assets)
Belangrijk:
- de runner ondersteunt nu direct `--training-dir <map>`
- daarbij wordt automatisch `content.md` en `training.json` gebruikt
- de URL wordt dus standaard uit `training.json` gelezen
- credentials kunnen via `--env-file .env` worden geladen zonder `source .env`
### Scripts
- [inspect-onlineacademy.mjs](/Users/nico/skillstown/inspect-onlineacademy.mjs)
Read-only inspectie van login, editor, requests en payloads.
- [markdown-to-onlineacademy-json.mjs](/Users/nico/skillstown/markdown-to-onlineacademy-json.mjs)
Parser en dry-run converter van Markdown naar platform-compatibele `jsonContent`.
- [onlineacademy-playwright-runner.mjs](/Users/nico/skillstown/onlineacademy-playwright-runner.mjs)
Zichtbare Playwright runner met:
- reviewmodus
- execute-modus
- optionele `--save` flag
- login
- inlezen van `.env` via `--env-file`
- inlezen van `training.json` via `--training-dir`
- editorverificatie
- pagina-aanmaak
- blokinsertie/invulling
- asset-resolutie relatief aan `content.md`
- menselijk leesbare voortgangsmeldingen
- DOM-snapshot voor detectie van nieuw ingevoegde blokken
- drop-targeting op de onderkant van het laatste bestaande blok
- execute zonder save laat het scherm open voor handmatige controle
- save klikt `Opslaan als` en kiest daarna `Concept`
### Config
- [package.json](/Users/nico/skillstown/package.json)
- [\.env](/Users/nico/skillstown/.env)
De runner verwacht credentials via environment variables:
- `OA_EMAIL`
- `OA_PASSWORD`
Praktisch worden die lokaal in `.env` gezet en tijdens een run automatisch ingelezen met:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env
```
Zonder deze stap stopt de runner met:
```text
Error: Zet OA_EMAIL en OA_PASSWORD in /Users/nico/skillstown/.env of in de omgeving.
```
## Wat werkt al
### Lokaal
- Markdown parsing werkt
- dry-run JSON generatie werkt
- plan/validatie-export werkt
- trainingsmap-structuur werkt
- `.env` en `training.json` worden automatisch ingelezen via flags
### Live in de zichtbare browser
Bewezen:
- login werkt
- editorherkenning werkt
- reviewmodus zonder mutaties werkt
- menselijk leesbare statusuitvoer werkt
- execute zonder `--save` laat het scherm nu open voor handmatige controle
- execute met `--save` bewaart nu via `Opslaan als` -> `Concept`
- nieuwe pagina `Intro` aanmaken werkt
- paginatitel invullen werkt
- drag/drop insertie van blokken werkt aantoonbaar stabieler wanneer op de onderkant van het laatste bestaande blok wordt gedropt
- execute-run in natuurlijke volgorde van boven naar beneden werkt nu voor:
- `text`
- `heading`
- `quote`
- `multiple-choice` blokinsertie werkt en de vraag wordt ingevuld
- `multiple-choice` werkt nu end-to-end voor de pilot:
- vraag invullen
- aantal antwoorden afstemmen op Markdown
- juiste antwoord selecteren
- feedback invullen
- `multiple-response` werkt nu end-to-end voor de pilot:
- vraag invullen
- aantal antwoorden afstemmen op Markdown
- alle checkboxen resetten
- meerdere correcte antwoorden selecteren
- feedback invullen
- `image` werkt nu voor de pilot:
- upload via lokaal bestandspad
- titel invullen
- onderschrift invullen
- alternatieve tekst invullen
- `table` werkt nu end-to-end voor de pilot:
- titel invullen
- `Top header` aan/uit zetten
- `Left header` aan/uit zetten
- aantal kolommen uitbreiden op basis van Markdown
- aantal rijen uitbreiden op basis van Markdown
- header- en bodycellen invullen
- `open-question` werkt nu end-to-end voor de pilot:
- vraag invullen
- toelichting invullen
- hoofdstukaanmaak werkt nu voor de pilot:
- de execute-flow maakt nu altijd een nieuw hoofdstuk aan via `Nieuw hoofdstuk`
- automatisch aangemaakte eerste pagina in nieuwe hoofdstukken hernoemen en hergebruiken
- extra pagina's per hoofdstuk aanmaken wanneer Markdown meer pagina's bevat
- asset-paden in trainingsmappen werken nu correct via relatieve resolutie vanaf `content.md`
- save via `Opslaan als` -> `Concept` werkt nu
## Artifacts / bewijs
De repo is opgeschoond; oude pilots en artifacts zijn verwijderd.
Huidige relevante artifacts worden per run geschreven naar:
- `artifacts/<trainingsnaam>/`
Daar vind je typisch:
- `plan.json`
- `validation.json`
- `editor-ready.png`
- `review-stop.png` of `after-save.png`
- `failure-state.png` als een run mislukt
## Belangrijkste observatie over drag/drop
De eerdere generieke drop in het bovenste deel van `editor-main` gaf instabiele invoegposities.
Verbetering die live is gevalideerd:
- wanneer het nieuwe blok naar het onderste deel van het laatste bestaande blok wordt gedropt, wordt het in de pilot-run onder dat blok ingevoegd
- de runner vult niet meer "eerste" of "laatste" blok blind in, maar detecteert het nieuwe blok via een DOM-snapshot vóór en na insertie
Gevolg:
- omgekeerde insertievolgorde is niet meer nodig voor de huidige MVP-blokken
- de gebruiker ziet nu een natuurlijke opbouw van boven naar beneden tijdens de zichtbare run
## Belangrijke observatie over verwijderen
Tijdens de grotere hoofdstukpilot verscheen zichtbaar een bevestigingspopup bij het leegmaken van de bestaande eerste pagina.
Waarschijnlijk oorzaak:
- de runner hergebruikt voor hoofdstuk 1 de al bestaande geopende pagina
- daarvoor probeert `clearCurrentPageBlocks(...)` bestaande blokken via `Verwijderen` weg te halen
- de huidige implementatie klikt wel op `Verwijderen`, maar handelt de bevestigingspopup nog niet expliciet en stap-voor-stap af
Gevolg:
- de popup kan enkele seconden knipperen of opnieuw focus krijgen
- dit oogt voor de gebruiker onrustig
- het is een risicovoller stuk gedrag dan de overige blokinvullingen, omdat het om verwijderacties gaat
Pragmatische koerswijziging:
- de execute-flow verwijdert nu geen bestaande hoofdstukken, pagina's of blokken meer
- de runner hergebruikt hoofdstuk 1 niet meer
- voor elk Markdown-hoofdstuk wordt nu altijd een nieuw hoofdstuk aangemaakt
- daarmee verdwijnt de delete-confirmation popup uit het normale execute-pad
## Huidige tekortkomingen
Nog niet robuust:
- de execute-flow is nu gevalideerd voor de gebruikte bloksets in `hoofdstuk-04-basisqueries`
- scoped targeting per bloktype blijft verder hardening nodig hebben voor bredere bloksets en afwijkende editorstates
Nog niet opgepakt:
- matching-pairs UI-flow
- functionele bevestiging van succesvol opslaan nog explicieter maken in de output
- opschonen van oude, ongebruikte delete-helpers in de runner
## Veiligheidsafspraken
Tot nu toe gehanteerd:
- headed browser
- slow motion
- reviewmodus zonder mutaties
- execute zonder `--save` stopt vóór save en laat het scherm open
- geen directe backend writes
- artifacts per stap
- execute-flow gebruikt nu geen delete-acties meer
Bewust nog niet gedaan:
- extra verificatie van succesvol opslaan na klik op `Opslaan als` -> `Concept`
- API writes
- bulkimport in productie
Aanbevolen aanvullende veiligheidsafspraak:
- als een run bestaande content zou moeten verwijderen, laat dat alleen gebeuren na expliciete gebruikersbevestiging
- voor het standaard execute-pad heeft een flow zonder delete-acties de voorkeur
## Run-instructies
In `/Users/nico/skillstown`:
Benodigd op macOS:
- Terminal
- Node.js
- npm
Installeren:
```bash
npm install
```
Credentials lokaal in `.env` zetten:
```dotenv
OA_EMAIL=jouw.email@voorbeeld.nl
OA_PASSWORD=jouwWachtwoordHier
```
Dry-run parser:
```bash
node markdown-to-onlineacademy-json.mjs trainings/hoofdstuk-04-basisqueries/content.md
```
Zichtbare review-run zonder mutaties:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env
```
Zichtbare review-run op een trainingsmap volgens de nieuwe gebruikersstructuur:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env
```
Zichtbare execute-run tot reviewstop, zonder save:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env \
--execute \
--output-dir artifacts/hoofdstuk-04-basisqueries
```
Zichtbare execute-run zonder save:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env \
--execute
```
Zichtbare execute-run met save-klik:
```bash
node onlineacademy-playwright-runner.mjs \
--training-dir trainings/hoofdstuk-04-basisqueries \
--env-file .env \
--execute \
--save
```
## Directe volgende stap
Pragmatische vervolgstappen:
1. save-bevestiging explicieter maken in de output
2. package scripts laten aansluiten op de huidige `--training-dir` flow
3. ondersteuning uitbreiden voor extra bloktypes zoals `matching-pairs`
4. oude, ongebruikte helpers verder opschonen
## Eindconclusie
De drag/drop Playwright-route is technisch haalbaar en veiliger passend bij deze productiecontext dan direct backend writes.
De basis is gelegd en live gevalideerd. De huidige flow ondersteunt nu review, execute zonder save en execute met save via `Opslaan als` -> `Concept`, vanuit een vaste trainingsmap-structuur met `content.md`, `training.json` en `assets/`.