# 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 - reviewstop vóór save Reden: - minder risico in productie - platformvalidaties blijven actief - gebruiker kan meekijken - geen directe backend writes ## Huidige bestanden ### Input / referentie - [create-md-format.md](/Users/nico/skillstown/create-md-format.md) - [body.html](/Users/nico/skillstown/body.html) ### 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 - login - editorverificatie - pagina-aanmaak - blokinsertie/invulling - DOM-snapshot voor detectie van nieuw ingevoegde blokken - drop-targeting op de onderkant van het laatste bestaande blok - reviewstop vóór save ### Testdata - [pilot-mvp.md](/Users/nico/skillstown/pilot-mvp.md) - [pilot-multi-response.md](/Users/nico/skillstown/pilot-multi-response.md) - [pilot-image.md](/Users/nico/skillstown/pilot-image.md) - [pilot-table.md](/Users/nico/skillstown/pilot-table.md) - [pilot-table-large.md](/Users/nico/skillstown/pilot-table-large.md) - [pilot-open-question.md](/Users/nico/skillstown/pilot-open-question.md) - [pilot-chapters.md](/Users/nico/skillstown/pilot-chapters.md) - [pilot-chapters-large.md](/Users/nico/skillstown/pilot-chapters-large.md) - [create-md-format.onlineacademy.json](/Users/nico/skillstown/create-md-format.onlineacademy.json) - [pilot-mvp.onlineacademy.json](/Users/nico/skillstown/pilot-mvp.onlineacademy.json) ### Config - [package.json](/Users/nico/skillstown/package.json) ## Wat werkt al ### Lokaal - Markdown parsing werkt - dry-run JSON generatie werkt - plan/validatie-export werkt ### Live in de zichtbare browser Bewezen: - login werkt - editorherkenning werkt - reviewmodus zonder mutaties werkt - 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 - er is niet opgeslagen ## Artifacts / bewijs Belangrijkste artifacts: - [editor-ready.png](/Users/nico/skillstown/artifacts/oa-runner/editor-ready.png) Editor succesvol geladen. - [page-1-structure.png](/Users/nico/skillstown/artifacts/oa-runner/page-1-structure.png) Nieuwe pagina `Intro` succesvol aangemaakt. - [page-1-block-1-text.png](/Users/nico/skillstown/artifacts/oa-runner/page-1-block-1-text.png) Tekstblok zichtbaar ingevoegd en gevuld. - [page-1-block-2-heading.png](/Users/nico/skillstown/artifacts/oa-runner/page-1-block-2-heading.png) Oud artifact uit een eerdere run waarin blokvolgorde/targeting nog niet stabiel was. - [page-1-block-2-quote.png](/Users/nico/skillstown/artifacts/oa-runner/page-1-block-2-quote.png) Quoteblok succesvol ingevuld in een latere geharde run. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner/review-stop.png) Laat de huidige reviewstop zien vóór save, met de blokken in de goede volgorde bovenaan zichtbaar. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner/validation.json) Pilot na drag/drop-hardening: - [page-1-block-3-quote.png](/Users/nico/skillstown/artifacts/oa-runner-pilot/page-1-block-3-quote.png) Laat zien dat `text`, `heading` en `quote` in natuurlijke volgorde onder elkaar staan. - [page-1-block-4-multiple-choice.png](/Users/nico/skillstown/artifacts/oa-runner-pilot/page-1-block-4-multiple-choice.png) Laat zien dat daarna ook `multiple-choice` onder het quote-blok is ingevoegd en dat de vraag is ingevuld. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-pilot/review-stop.png) Bevestigt de pagina-opbouw in volgorde `text` -> `heading` -> `quote` -> `multiple-choice`, zonder save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-pilot/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-pilot/validation.json) Pilot voor `multiple-choice` afwerking: - [page-1-block-4-multiple-choice.png](/Users/nico/skillstown/artifacts/oa-runner-mc/page-1-block-4-multiple-choice.png) Laat zien dat de meerkeuzevraag nu met exact 2 antwoorden uit Markdown is ingevuld, met het correcte antwoord geselecteerd. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-mc/review-stop.png) Laat zien dat ook de feedback/toelichting is ingevuld en dat de run weer stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-mc/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-mc/validation.json) Pilot voor `multiple-response` afwerking: - [page-1-block-1-multiple-response.png](/Users/nico/skillstown/artifacts/oa-runner-mr/page-1-block-1-multiple-response.png) Laat zien dat de multi-antwoordvraag nu exact 3 antwoorden uit Markdown overneemt, met 2 correcte checkboxen geselecteerd. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-mr/review-stop.png) Laat zien dat ook de toelichting is ingevuld en dat de run weer stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-mr/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-mr/validation.json) Pilot voor `image` afwerking: - [page-1-block-1-image.png](/Users/nico/skillstown/artifacts/oa-runner-image/page-1-block-1-image.png) Laat zien dat de afbeelding is geüpload en dat `Titel`, `Onderschrift` en `Alternatieve tekst` zijn ingevuld. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-image/review-stop.png) Laat zien dat de image-run ook weer stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-image/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-image/validation.json) Pilot voor `table` verkenning: - [page-1-block-1-table.png](/Users/nico/skillstown/artifacts/oa-runner-table/page-1-block-1-table.png) Laat zien dat `Titel`, `Top header`, kolomuitbreiding, rijuitbreiding en de volledige celvulling nu werken voor de tabelpilot. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-table/review-stop.png) Laat zien dat de tabel-run ook stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-table/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-table/validation.json) - [failure-state.png](/Users/nico/skillstown/artifacts/oa-runner-table/failure-state.png) Artifact uit een tussenrun waarin de plusknoppen voor kolom/rij-uitbreiding nog niet betrouwbaar werden geraakt. Pilot voor grotere `table` validatie: - [page-1-block-1-table.png](/Users/nico/skillstown/artifacts/oa-runner-table-large/page-1-block-1-table.png) Laat zien dat de tabel ook opschaalt naar 4 kolommen en 10 regels totaal, inclusief volledige celvulling uit Markdown. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-table-large/review-stop.png) Laat zien dat ook de grotere tabel-run stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-table-large/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-table-large/validation.json) Pilot voor `open-question` afwerking: - [page-1-block-1-open-question.png](/Users/nico/skillstown/artifacts/oa-runner-open-question/page-1-block-1-open-question.png) Laat zien dat de open vraag en de toelichting correct uit Markdown zijn ingevuld. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-open-question/review-stop.png) Laat zien dat ook de open-vraag-run stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-open-question/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-open-question/validation.json) Pilot voor hoofdstukaanmaak: - [chapter-2-structure.png](/Users/nico/skillstown/artifacts/oa-runner-chapters/chapter-2-structure.png) Laat zien dat een tweede hoofdstuk wordt toegevoegd en dat de automatisch aangemaakte eerste pagina daarvan wordt hernoemd en gevuld. - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-chapters/review-stop.png) Laat zien dat de tweekoppige hoofdstukpilot stopt vóór save. - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-chapters/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-chapters/validation.json) Pilot voor grotere hoofdstukvalidatie: - [review-stop.png](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/review-stop.png) Laat zien dat 4 hoofdstukken met wisselende aantallen pagina's goed worden opgebouwd: - `Hoofdstuk Alfa`: 1 pagina - `Hoofdstuk Bravo`: 3 pagina's - `Hoofdstuk Charlie`: 2 pagina's - `Hoofdstuk Delta`: 4 pagina's - [chapter-2-structure.png](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/chapter-2-structure.png) - [chapter-3-structure.png](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/chapter-3-structure.png) - [chapter-4-structure.png](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/chapter-4-structure.png) - [plan.json](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/plan.json) - [validation.json](/Users/nico/skillstown/artifacts/oa-runner-chapters-large/validation.json) ## 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 nieuwe drop-strategie en execute-flow zijn live gevalideerd voor pilots met `text`, `heading`, `quote`, `multiple-choice`, `multiple-response`, `image`, `table`, `open-question` en hoofdstukken/pagina's - scoped targeting per bloktype blijft verder hardening nodig hebben voor bredere bloksets en afwijkende editorstates - de nieuwe "altijd nieuw hoofdstuk"-strategie moet nog live opnieuw gevalideerd worden Nog niet opgepakt: - matching-pairs UI-flow - save-flow - opschonen van oude, ongebruikte delete-helpers in de runner ## Veiligheidsafspraken Tot nu toe gehanteerd: - headed browser - slow motion - reviewmodus zonder mutaties - execute stopt vóór save - geen directe backend writes - artifacts per stap - execute-flow gebruikt nu geen delete-acties meer Bewust nog niet gedaan: - automatisch opslaan - 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`: Installeren: ```bash npm install ``` Dry-run parser: ```bash node markdown-to-onlineacademy-json.mjs pilot-mvp.md ``` Zichtbare review-run zonder mutaties: ```bash # verwacht een lokaal `.env` bestand met ten minste: # OA_EMAIL='...' # OA_PASSWORD='...' ``` Credentials laden uit `.env`: ```bash set -a source .env set +a ``` Zichtbare review-run zonder mutaties: ```bash node onlineacademy-playwright-runner.mjs \ --markdown pilot-mvp.md \ --url 'https://create.onlineacademy.nl/8602e048-d7ee-4764-aafb-43412d0f65f3/edit?idsVersion=6' ``` Zichtbare execute-run tot reviewstop, zonder save: ```bash set -a; source .env; set +a node onlineacademy-playwright-runner.mjs \ --markdown pilot-mvp.md \ --url 'https://create.onlineacademy.nl/8602e048-d7ee-4764-aafb-43412d0f65f3/edit?idsVersion=6' \ --execute \ --output-dir artifacts/oa-runner-pilot ``` Zichtbare execute-run zonder save: ```bash set -a source .env set +a node onlineacademy-playwright-runner.mjs \ --markdown pilot-mvp.md \ --url 'https://create.onlineacademy.nl/8602e048-d7ee-4764-aafb-43412d0f65f3/edit?idsVersion=6' \ --execute ``` ## Directe volgende stap Niet meer werken met "laatste blok = nieuw blok". Hardeningvoorstel: 1. `multiple-choice` volledig afmaken: Status: afgerond voor de pilot-run. 2. `multiple-response` Status: afgerond voor de pilot-run. 3. `image` Status: afgerond voor de pilot-run. 4. `table` Status: afgerond voor de pilot-run. 5. `open-question` Status: afgerond voor de pilot-run. 6. hoofdstukaanmaak Status: afgerond voor de pilot-run, maar execute-flow is inmiddels vereenvoudigd naar "altijd nieuw hoofdstuk" en moet daarop opnieuw live gevalideerd worden. 7. verdere hardening voor andere bloktypes en editorvarianten 8. save-flow ## 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 veiligste huidige koers is om in execute-runs alleen nieuwe hoofdstukken op te bouwen en geen bestaande content te verwijderen. Verdere hardening blijft nodig op blokpositie, veldtargeting en uiteindelijk de save-flow voordat dit betrouwbaar genoeg is voor herhaalbaar gebruik.