Commit graph

195 commits

Author SHA1 Message Date
Ramon
308f877be6 feat: herteken de resterende zwakke kleurplaten (v0.4.77-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 38s
De twee platen die ik zelf had aangemerkt plus de overige zwakke plekken uit de
visuele controle. Audit blijft schoon op alle drie de niveaus: geen
onbereikbare vakken, geen onzichtbare of afdwalende lijnen.

Dieren met vier poten in plaats van twee latjes:
- savanne: giraf en zebra hebben nu vier poten met een knik en een hoef, een
  langere en slankere giraffennek die breed uitloopt in de schouder, een kop
  met snuit, ossenhoorns en oor, en een manestreep bij de zebra.
- dinosaurusvallei: vier poten met voeten en een staart die echt versmalt.

Vormen die verkeerd lazen:
- boom van vier seizoenen: de kroon was een gladde cirkel met een kruis erin en
  las als een bal. De vier seizoenskwarten hebben nu een geschulpte buitenrand,
  dus het leest als bladerdek. De losse plukken op de rand zijn vervangen door
  bladclusters binnen elk kwart, waardoor ook de inkepingen verdwenen die
  ontstonden waar plukken en bladvormen elkaar overlapten.
- koraalrif: het zeepaardje was een smal buisje dat als worm las. Nu een
  stevige romp met een aparte gekrulde staart, de rugvin op de rug in plaats
  van dwars door het lichaam, en meer buikringen.
- vrienden in zee: de schildpad stond klem tegen de rechterrand; hij is groter
  en verder naar binnen geschoven, met grotere schildplaten.

Lege vlakken gevuld, want er was niets te kleuren:
- kleine tuindieren: zon, wolk en een vlinder in de bovenhelft.
- koraalrif: een schooltje visjes in de lege bovenhoek; de bellen zijn
  meegeschoven.
- feesttaart: een tafelkleed met schulprand in de onderste strook.
- grote graafmachine: zonnestralen, zoals bij de andere zonnen.

Losse elementen vastgezet:
- regenwoud: de bladeren aan de rechterkant zweefden los naast de stam en
  sluiten nu aan, met bladnerven op niveau 3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YErxhic5w9K57zmt8Q1uS
2026-07-30 14:40:30 +02:00
Ramon
e800467745 fix: verbeter het lijnwerk van de kleurplaten (v0.4.76-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
Systematisch nagelopen met een meetkundige audit in de browser plus een
visuele controle van alle 20 platen op ware grootte (800x600). De audit meet
per niveau welke kleurvakken volledig achter latere vakken verdwijnen, welke
detaillijnen onzichtbaar zijn en welke lijnen buiten het blad vallen.

Onbereikbare kleurvakken verholpen (waren onzichtbaar én niet te kleuren):
- kleine tuindieren: de kop van het lieveheersbeestje zat volledig achter het
  schild; de kop komt nu boven het lichaam uit.
- molen in de polder: de onderste wiek verdween achter de romp. De wieken
  staan nu als schuin kruis, zodat alle vier vrij liggen, met latwerk erin.
- regenwoud: een mosplukje zat achter de ara.
- kasteel: de verre heuvels waren voor 89% bedekt en zijn opgeschoven.
- leven rond de vijver: twee bloemblaadjes van de waterlelie zaten achter de
  vis; de bloem staat nu naast de vis.

Overtollige strepen weggehaald:
- graspollen in vlinder, tuindieren, molen en vogelnest stonden los in het
  gras; ze beginnen nu op de grondlijn zelf.
- feesttaart: losse kruisjes in de lucht lazen als vergissingen, nu confetti-
  stippen; de ballontouwtjes lopen door tot op de tafel.
- bergkamp: de graatlijnen liepen door tot in het meer en stoppen nu bij de
  bergvoet.
- boom van vier seizoenen: een losse kromme stond midden in de kroon.
- kasteel: het bootje overlapte de brug, waardoor zeil en brugdek door elkaar
  heen liepen; het ligt nu links in de rivier.
- koraalrif: de rugvin van het zeepaardje stak dwars door het lichaam.

Ontbrekende strepen toegevoegd:
- schorslijnen op de stammen van picknick en regenwoud.
- glazuur op de middelste laag van de taart (alleen boven- en onderlaag hadden
  het).
- sneeuwkappen op beide bergtoppen zijn groter en echt zichtbaar.
- fanlijnen in het fankoraal, bloemblaadjeslijnen in de bloesems.

Vormen die verkeerd lazen hertekend:
- tulpen bij de molen hadden een ronde koepel en lazen als paddenstoelen; nu
  een puntige kelk van drie blaadjes.
- lensvormen die als ogen of blaadjes lazen zijn ronde plukken geworden in de
  herfstboom, de acacia (met een derde pluk om het "ogenpaar" te breken) en de
  kroon van de vierseizoenenboom.
- de kikker had lensvormige poten naast zich; nu poten met knik en voet.
- graspollen op de savanne zijn tuiltjes van twee blaadjes.
- dinosaurus: dikkere poten, lava op de kraterrand in plaats van in de kegel.
- vlinder: acht symmetrische zonnestralen in plaats van vijf scheve.
- rechte kadelijnen in molen, bergkamp, kasteel, dinosaurusvallei, tuindieren
  en vierseizoenen zijn golvend gemaakt; ze lazen als een liniaal.
- leven rond de vijver had een lege bovenhelft: zon, wolk en zwaluwen erbij.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YErxhic5w9K57zmt8Q1uS
2026-07-30 11:29:43 +02:00
Ramon
c6b3a14923 fix: maak kleurplaatverf zichtbaar en herteken de atlas (v0.4.75-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
Kwast en verfemmer werkten al, maar het resultaat was onzichtbaar: de
contourlaag zette fill="#fff" op elk vak en vertrouwde op
mix-blend-mode:multiply om dat onschadelijk te maken. Doordat .coloring-ink
zelf een stacking context is (position+z-index), vormt die een geisoleerde
blendgroep zonder achtergrond, en werd het wit gewoon dekkend over de hele
tekening gelegd. Live nagemeten met headless Chromium.

- Tekenmodel omgezet naar een echte schildersvolgorde in een enkele SVG: elk
  vak wordt uitgeklapt naar vak -> verflaag -> contour, zodat verf zichtbaar
  blijft en latere vakken de verf en contour van eerdere vakken afdekken.
  Daarmee kijk je ook niet meer door figuren heen.
- Canvas vervangen door SVG-streken: geen opschalingsonscherpte meer en geen
  donkere naden (dekking staat per streek op de groep, niet per segment).
- Kwast blijft binnen de lijnen als hulp, gestuurd door niveau: groep 1-4 op
  niveau 1 en 2, groep 5-8 op niveau 1, daarboven vrij schilderen.
- Verfemmer dekt een vak volledig; de gum pelt de bovenste laag af (eerst de
  vulling, daarna de streken eronder).
- Kleurwijzer toegevoegd: op niveau 1 laat een stip per vak de voorgestelde
  kleur zien, op niveau 2 op te vragen met een knop, op niveau 3 uit.
- Niveau sloopt de tekening niet meer: data-tier staat alleen op groepen en
  detaillijnen, dus een rekwisiet verdwijnt als geheel en de plaat is op elk
  niveau een complete tekening. Niveau 3 voegt alleen fijn lijnwerk toe.
- Atlas hertekend naar 20 platen, 5 per groepenband en 1 per thema. Twee
  lijndiktes, vakken op maat van de band, geen evenodd-gaten, en composities
  met voor-, midden- en achtergrond.
- partBelow/elementFromPoint en het omzetten van pointer-events vervallen:
  aanwijzen gebeurt meetkundig met isPointInFill/isPointInStroke.
- langchange-listener ruimt zichzelf op na demontage.
- Staat bewaart nu streken in plaats van een PNG; oud werk met een ink-PNG
  blijft zichtbaar.
- Tests: asserties die de bug vastzetten verwijderd en vervangen door een
  regressietest die verbiedt dat CSS een fill op een kleurvak zet, plus
  controles op gesloten vakken, geen transform, tier-regels, vakaantallen per
  niveau en de clip-matrix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YErxhic5w9K57zmt8Q1uS
2026-07-30 00:39:14 +02:00
Ramon
66d6cf4d46 feat: bouw kleurplatenatlas opnieuw op (v0.4.74-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
- Teken alle 28 scènes vanaf een leeg canvas opnieuw met samenhangende silhouetten en detailniveaus per leerjaar.
- Geef dieren soortspecifieke anatomie, natuurlijke verhoudingen en vloeiende realistische contouren.
- Borg gesloten vulvakken, correcte laagvolgorde en blijvend zichtbare contour- en binnenlijnen.
- Verwijder de oude reparatielaag en voeg anatomische en functionele regressietests toe.
2026-07-29 16:59:27 +02:00
Ramon
6a08cee75c feat: herteken kleurplaten als illustraties (v0.4.73-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
- vervang alle 28 kleurplaten door samenhangende scènes met organische contouren en leeftijdsgerichte detaillering
- houd buiten- en binnenlijnen zichtbaar boven kwastwerk en sluit verfemmerkleuren zonder witte rand aan
- borg gesloten kleurvakken, anatomische laagvolgorde en scene-opbouw met uitgebreide regressietests
2026-07-29 15:44:38 +02:00
Ramon
03bfb9feda fix: herstel gum en kleurplaatlagen (v0.4.72-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 36s
- laat de gum ook verfpotvullingen bij tikken en slepen verwijderen
- vervang dubbele filterlagen door één gemaskeerde contourlaag zonder witte halo
- verberg overlappende herkenningshulplijnen en dek achterliggende contouren correct af
- voeg regressietests toe voor gum, vulranden en lijnlagen
2026-07-29 14:49:34 +02:00
Ramon
724eb6a33c feat: herontwerp kleurplaten professioneel (v0.4.71-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 40s
Gewijzigde functionaliteiten:
- Vervang losse geometrische dierdelen door vloeiende Bézier-silhouetten met geloofwaardiger anatomie.
- Schilder poten, staarten, vinnen, vleugels, wielen en andere appendages achter het hoofdsilhouet voor aansluitende contouren.
- Voeg een SVG-occlusiefilter toe dat alleen werkelijk zichtbare lijnen boven kwast en verfpot toont.
- Verfijn lijngewichten, witte contrastrand, wielkasten, manen en objectcontouren.
- Geef kwast, verfpot en gum zichtbare labels en verbeter ARIA-groepering van gereedschappen en palet.
- Voeg regressietests toe voor organische contouren, schildervolgorde, gesloten kleurvakken en UX-bediening.

Tests:
- npm test (201 geslaagd)
2026-07-29 14:27:26 +02:00
Ramon
33398c8594 fix: herstel kleurplaatgereedschappen (v0.4.70-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 33s
Gewijzigde functionaliteiten:
- Vervang foutgevoelige zwarte en witte SVG-vullingen door transparante contourlagen.
- Laat de verfpot rechtstreeks de aanklikbare kleurvakken bedienen.
- Vervang het kleurpotlood door een vloeiende, pendrukgevoelige kwast met eigen icoon en cursor.
- Migreer opgeslagen potloodstate automatisch naar het nieuwe kwastgereedschap.
- Voeg regressietests toe voor achtergrond, laagweergave en gereedschapsinvoer.

Tests:
- npm test (201 geslaagd)
2026-07-29 14:05:57 +02:00
Ramon
979f30a935 feat: geef kleurplaten een grafische upgrade (v0.4.69-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
Gewijzigde functionaliteiten:
- Splits kleurplaten in kleur-, potlood- en bovenste inktlaag zodat contouren zichtbaar blijven.
- Versterk lijnen met een lichte contrastrand en donkere inkt, met behoud van de juiste overlappingen.
- Vernieuw werkvlak, gereedschappen en kleurenpalet voor een krachtiger grafische uitstraling.
- Voeg regressietests toe voor laagvolgorde en inktweergave.

Tests:
- npm test (201 geslaagd)
2026-07-29 10:18:59 +02:00
Ramon
1e0f0c6d03 feat: verfijn grafische kwaliteit kleurplaten (v0.4.68-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
Gewijzigde functionaliteiten:

- Brengt een rustige lijnhiërarchie aan met subtiele buitenkaders, stevige kleurvlakken en lichtere binnenlijnen.
- Voegt herkenbare textuurdetails toe aan onder meer vlinder, herfstboom, taart, zeedieren, molen, raket en kasteel.
- Verbetert het fietsframe in de duurzame-stadplaat en markeert kleurvlakken bij aanwijzen met de verfemmer.
- Borgt het consistente SVG-profiel voor alle 28 kleurplaten met aanvullende tests.

Tests: 201 geslaagd (npm test); 5 gerichte kleurplaattests geslaagd.
2026-07-29 08:37:32 +02:00
Ramon
3aafd50d62 Verbeter grafische kwaliteit kleurplaten
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
2026-07-29 08:02:53 +02:00
Ramon
24816c0d64 feat: breid kleurplaten uit en verfijn details (v0.4.66-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 42s
2026-07-28 23:05:49 +02:00
Ramon
0841962824 feat: voeg thematische kleurplaten toe (v0.4.65-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 44s
2026-07-28 22:34:15 +02:00
Ramon
fcb117eb54 fix: lijn het stippenpatroon uit binnen elk blokformaat (v0.4.64-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 50s
Gewijzigde functionaliteiten:

- De open stippen in de doelvakken stonden links-boven in hun rastercel in
  plaats van gecentreerd, waardoor het patroon scheef oogde; ze staan nu op
  dezelfde as als de gevulde stippen.

- De stippen van de geldblokken en van alle cijferblokken in een smalgemaakte
  widget staken onder het blok uit. De stipmaat komt nu uit een variabele die
  elk bloktype naast zijn eigen hoogte zet, in plaats van uit losse
  hardgecodeerde regels per widget.

- De smalle-widget-weergave verkleint alleen nog de breedte; blokhoogtes
  blijven gelijk, want juist het verkleinen van de hoogte duwde het raster naar
  buiten. Letterblokken krijgen daar een passend kleiner cijfer/letterformaat.

- Nieuw vangnet: het raster houdt altijd zijn maat en het label geeft mee als
  een blokformaat krap is, zodat een nieuw blokformaat dit niet opnieuw kan
  veroorzaken.

Tests: 196 geslaagd (4 nieuw in test/dot-grid.test.js; die vier vallen ook
daadwerkelijk om op de oude CSS). Daarnaast in de browser opgemeten voor alle
zeven blokcontexten, bij normale en smalle widgetbreedte, plus screenshots en
een controle in de echte leerlingweergave.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126hjBPD2ggZ2LEoDYZSW7S
2026-07-26 08:13:02 +02:00
Ramon
50b9f32e91 feat: voeg voortgangdetail toe aan de taalwidgets (v0.4.63-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m56s
Gewijzigde functionaliteiten:

- Letterblokken logt per afgerond woord hoeveel pogingen het kostte en welke
  letter op welke plek fout ging (beide invoerwijzen: blokken slepen en typen).

- Ballonnenwoord logt nu ook een verloren woord; dat leverde tot nu toe geen
  enkele voortgang op. Een gewonnen woord telt de fout geraden letters mee.

- Flitswoorden stuurt de bestaande zelfcheck ("Gelukt" / "Nog oefenen") door
  naar de voortgang; die uitkomst werd eerder weggegooid.

- Hakken & plakken krijgt dezelfde zelfcheck en daarmee als laatste taalwidget
  een goed/fout-moment; de oefening zelf verandert niet.

- Voortgang-tab toont de fouten van taal: naast fout afgesloten opdrachten ook
  "na N pogingen goed" (letterblokken kent geen faalmoment) en zelfchecks.

- Reeksstappen met flitswoorden of hakken & plakken wachten nu op een echt
  afgerond moment in plaats van meteen te completeren.

Tests: 192 geslaagd (7 nieuw), plus live nagelopen in de leerlingweergave met
echte interactie per widget en een screenshot van de Voortgang-tab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126hjBPD2ggZ2LEoDYZSW7S
2026-07-26 03:16:28 +02:00
Ramon
043831e1dd feat: make assignments independent from boards
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m28s
2026-07-25 22:15:52 +02:00
Ramon
05f3dbe56c feat: simplify assignment sequence sharing
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 55s
2026-07-24 23:08:44 +02:00
Ramon
b8e9e46819 fix: patch Fastify static security vulnerabilities
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m20s
2026-07-24 22:46:22 +02:00
Ramon
a7180d8390 feat: combine assignments and class management
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 56s
2026-07-24 22:36:15 +02:00
Ramon
131ffc2f38 feat: breid live klasinteractie grafisch uit
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 47s
2026-07-24 13:40:18 +02:00
Ramon
90851f960a feat: voeg live leersessies toe aan klasdashboard
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m38s
2026-07-24 10:53:42 +02:00
Ramon
b2f6a69897 fix: maak leerkrachtfuncties zichtbaar in voorbeeldmodus
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 1m10s
2026-07-23 23:15:08 +02:00
Ramon
ae8d0d4bb4 feat: voeg leerpaden dashboard en avatarbeloningen toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m23s
2026-07-23 21:23:54 +02:00
Ramon
9dc896964d fix: maak mobiele opdrachten volledig zichtbaar
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m11s
2026-07-23 19:05:53 +02:00
Ramon
ff6dbc5c2e fix: voorkom witte onderstrook op mobiel
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 53s
2026-07-23 17:34:47 +02:00
Ramon
c33eb71640 fix: centreer letter- en cijferdoelvakken
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m4s
Gewijzigde functionaliteiten:

- Centreert doelvakken in letter-, reken-, klok-, geld-, plaatswaarde- en wereldwidgets.

- Houdt lange woordrijen scrollbaar zonder de eerste vakken af te snijden.

- Centreert kleinere geplaatste cijferblokken binnen hun doelvak.

- Verwijdert de links uitgelijnde compacte woordrij.

Tests: 160 geslaagd.
2026-07-23 17:06:26 +02:00
Ramon
34c4d6e1a4 feat: laat avatars dansen na afgeronde opdrachten
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 42s
Gewijzigde functionaliteiten:

- Voegt vijf afwisselende avatardansen toe.

- Houdt lichaam, haar en accessoires als een verbonden SVG-figuur.

- Danst na afgeronde woordgroepen, flitsrondes, galgjerondes en rekenrondes.

- Respecteert verminderde beweging met een stil feestbeeld.

Tests: 159 geslaagd; npm audit: 0 kwetsbaarheden.
2026-07-23 07:07:30 +02:00
Ramon
4544306ccd feat: voeg avatarsoortvarianten toe (v0.4.50-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m8s
2026-07-22 23:40:36 +02:00
Ramon
2b40488208 fix: patch fast-uri kwetsbaarheid (v0.4.49-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m15s
2026-07-22 23:21:23 +02:00
Ramon
6832043470 feat: maak avatarhaar natuurlijker (v0.4.48-beta)
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 43s
2026-07-22 23:13:20 +02:00
Ramon
7237cb6290 feat: breid compacte avatars uit (v0.4.47-beta)
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 35s
2026-07-22 19:59:15 +02:00
Ramon
d0522d7e33 feat: verbeter anatomie en accessoires van avatars (v0.4.46-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 58s
2026-07-21 23:25:12 +02:00
Ramon
dc3c591c76 feat: stem taalwidgets af op beginnende geletterdheid
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m5s
2026-07-21 22:27:44 +02:00
Ramon
6f593e05b2 fix: corrigeer woordplaatjes in taalbibliotheek (v0.4.44-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m1s
2026-07-21 22:01:41 +02:00
Ramon
ba4483d5d3 feat: breid taalbibliotheek uit met 1000 woorden (v0.4.43-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 59s
2026-07-21 18:50:47 +02:00
Ramon
17ee47dd09 fix: maak bordniveaus instelbaar (v0.4.42-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 42s
2026-07-21 07:58:56 +02:00
Ramon
fabe721991 feat: voeg leerjaarprofielen toe aan taal en rekenen (v0.4.41-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
2026-07-20 22:45:01 +02:00
Ramon
629329894d feat: laat systeemmanager leerlingwidgets toevoegen (v0.4.40-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 53s
2026-07-20 16:06:33 +02:00
Ramon
b81f5ac5dd feat: voeg rolvoorbeeld voor systeemmanager toe (v0.4.39-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 56s
2026-07-20 14:08:37 +02:00
Ramon
9bab7f39c0 feat: koppel widgets aan kerndoelen (v0.4.38-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
2026-07-19 21:46:38 +02:00
Ramon
322147d3d1 feat: voeg curriculumwiki voor volwassenen toe (v0.4.37-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m1s
2026-07-19 21:13:11 +02:00
Ramon
216ab8d5dd docs: leg SLO-kerndoelen 2026 vast (v0.4.36-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
2026-07-19 20:58:17 +02:00
Ramon
8ccfa5dc8c feat: voortgang flinke UI-upgrade + bug (1 opdracht i.p.v. groep) + grafiek (v0.4.35-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m17s
- Bug gevonden en bevestigd (niet blind aangenomen): math.js riep
  onProgress maar op ÉÉN plek aan, in endRound(), NA een heel blok van
  10 sommen, met alleen het geaggregeerde totaal. Eén sessie van 10
  sommen - "een groep opdrachten" - leverde dus precies 1 rij op in
  progress_events, niet 10, en maakte "welke som ging fout" onmogelijk
  te zien (alleen een totaaltelling per blok).
- Fix: onProgress verplaatst naar check(), bij elke afgeronde som (goed
  op de eerste keer, of opgeven na 3 pogingen) - een sessie van 10
  sommen levert nu 10 progress_events-rijen op, elk met een nieuw
  optioneel detail-veld (welke som, gegeven antwoord, juist antwoord).
  letters.js/ball.js blijven deze ronde ongemoeid (hun granulariteit
  veroorzaakte niet deze bug).
- Nieuwe kolom progress_events.detail (JSONB, nullable, puur additief -
  db/020_progress_detail.sql). POST /my/progress accepteert het
  optioneel; te groot/geen plain object wordt stilzwijgend genegeerd
  zonder de rest van de log-poging te laten falen (detail is decoratief,
  geen kernfunctionaliteit).
- Voortgang-tab (admin.js) herontworpen, zelfde ontwerptaal als de
  eerdere School-navigator-herbouw: vakgebied-tabs, een
  klassenmanagement-infobadge (Groep {n} · Niveau {n}, opgehaald via de
  bestaande /levels/pupil/:id-route) zodat resultaten meteen tegen het
  toegewezen niveau afgezet kunnen worden, een met de hand getekende
  SVG-nauwkeurigheidsring + staafdiagram (goed/fout per dag, laatste 14
  dagen - geen library, zelfde aanpak als avatar.js) en een "recente
  fouten"-lijst die precies toont welke som fout ging. De bestaande
  ruwe tijdlijn blijft eronder staan, niets is verwijderd.
- Terzijde gevonden en gefixt: .am-btn.active bestond nergens in de
  CSS, waardoor de vakgebied-tabs (hier én in Klassenmanagement,
  v0.4.34-beta) geen enkele visuele aanduiding hadden welke actief was.
- Tests: test/progress-logging.test.js uitgebreid met 4 tests voor het
  detail-veld (opgeslagen, te groot genegeerd, geen plain object
  genegeerd, afwezig blijft null). Volledige testsuite: 132/132.
- Live geverifieerd: een math.js-sessie met een mix van goede/foute
  sommen doorlopen en bevestigd dat er 3 aparte POST /my/progress-
  aanroepen gebeuren voor 3 sommen (niet 1 aggregaat), elk met het
  juiste detail; de herbouwde Voortgang-tab geopend met gemockte data
  en met screenshots bevestigd dat de nauwkeurigheidsring (38% = 3/8,
  rekenkundig geverifieerd), het klassenmanagement-infobadge, de
  staafdiagram en de "recente fouten"-lijst (met de daadwerkelijke som)
  correct tonen, én dat de active-tab-fix ook op de Klassenmanagement-
  tab zichtbaar is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 15:56:14 +02:00
Ramon
e7bb76b76d feat: klassenmanagement - niveaugroep + niveau per leerling per vakgebied (v0.4.34-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m9s
- Grootste openstaande roadmap-punt. Nieuwe tabel pupil_levels
  (db/019_pupil_levels.sql, zelfde class_id/pupil_id-vorm als
  assignments) legt per vakgebied (taal/rekenen/world) een niveaugroep
  vast (groep 1-8, gebaseerd op de leerjaren van de basisschool waaraan
  de leerdoelen gekoppeld zijn) + niveau (1-3, fijnmazige verfijning
  BINNEN die groep). Klas-standaard met individuele leerling-overrides,
  net zo laagdrempelig instelbaar als de standaard - het speciaal-
  onderwijs-geval waar dat vanaf het begin de norm is.
- Server: GET/PUT/DELETE /levels/class/:id en /levels/pupil/:id
  (src/api.js) hergebruiken exact het assignments-patroon (upsert via
  partial-unique-index, pupil-eerst-dan-klas-resolutie), plus
  GET /my/level voor de leerling-kant. Zelfde permissie
  (assignments.manage) en sameSchool/teacherOnly/pupilAccessible-
  guards als de bestaande toewijzingsroutes.
- Nieuwe admin-tab "Klassenmanagement": klas + vakgebied kiezen, een
  klas-standaard instellen, en per leerling de effectieve groep/niveau
  zien (overerft van de klas tenzij een eigen afwijking is ingesteld)
  met bewerk- en terug-naar-standaard-knoppen.
- ECHTE inhoudskoppeling, niet alleen een standaardwaarde: rekenen is
  het eerste vakgebied waarvan de SLO/TULE-leerlijn direct in
  getalgrenzen te vertalen is (groep 3 t/m 20, groep 4 t/m 100, groep 5
  t/m 1000, groep 6 t/m 10.000). Nieuwe SLO_MATH_RANGES/mathRangeFor()
  in data.js; math.js's gen() gebruikt dit voor de daadwerkelijke
  getallen zodra een leerling een groep heeft (S.yearGroup), met het
  bestaande niveau 1-3 als verfijning daarbinnen. Zonder groep blijft
  het oude vaste 10/20/100-gedrag exact bestaan.
- pupil.js geeft groep/niveau door aan taal/rekenen-widgets bij het
  mounten: niveau is een standaardwaarde (een al opgeslagen bord-niveau
  blijft leidend), groep wordt voor rekenen-widgets altijd meegegeven
  (er is geen "oud" groep-concept om te respecteren). Terzijde ook de
  stille .catch() op de nieuwe async renderPupilWidgets() opgelost.
- Taal/wereldoriëntatie krijgen deze ronde nog geen eigen
  inhoudskoppeling (vraagt een eigen contentbron per groep, nog niet
  uitgezocht) - eerlijk benoemd als vervolgstap, geen loze belofte.
- Tests: test/pupil-levels.test.js (10 tests) dekt de server-routes
  (mocked-pool-patroon) én - via dezelfde vm-techniek als elders in
  test/widgets.test.js voor MONEY_LEVELS - een ECHTE (niet regex-)test
  van mathRangeFor die bevestigt dat elke groep de juiste getalgrens
  oplevert en niveau nooit boven de groep-grens uitkomt. Twee bugs
  gevonden en gefixt tijdens het schrijven van deze tests: null-yearGroup
  werd per ongeluk als groep 1 behandeld i.p.v. "geen groep", en de
  testrol had geen klas-eigenaarschap waardoor 403 in plaats van 200
  terugkwam. Volledige testsuite: 128/128.
- Live geverifieerd in de sandbox: klas-standaard + leerling-override
  instellen in de nieuwe admin-tab, en drie scenario's in de
  leerling-omgeving die bevestigen dat de daadwerkelijk gegenereerde
  sommen binnen de juiste groep-grens blijven (geen klassenmanagement →
  ongewijzigd oud gedrag; groep zonder eigen bord-niveau → volledige
  groep-grens; groep mét een al opgeslagen bord-niveau → dat niveau
  blijft leidend, geschaald naar de juiste groep-grens).
- public/js/data.js bevatte al niet-gerelateerde, nog niet gecommitte
  wijzigingen van vóór deze sessie (extra taalthema's/woorden) - alleen
  de SLO_MATH_RANGES/mathRangeFor-hunk is hier meegenomen (git add -p),
  de rest blijft bewust ongemoeid staan, net als test/language-library.test.js.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 15:31:26 +02:00
Ramon
36695a06f6 fix: leerling in werken-modus kreeg abusievelijk readonly:true (v0.4.33-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 46s
- Roadmap-punt "de voortgangen werken niet" onderzocht (niet blind
  herbouwd - eerst gediagnosticeerd via de code en git-geschiedenis).
- Gevonden: pupil.js zette sinds v0.3.15-beta (toen kijken/werken-modus
  werd toegevoegd) readonly:true in BEIDE takken van de modus-keuze -
  een kopieerfout, want de hele reden voor die commit was net dat
  "werken" de leerling wél moet laten werken. In "werken"-modus hoort
  er geen readonly-vlag te staan; "kijken" (blijft ongewijzigd) is de
  enige modus die dat nodig heeft.
- Concreet effect: de twee widgets die opts.readonly daadwerkelijk
  lezen (letters.js/anchor.js) verborgen voor leerlingen in
  werken-modus onterecht hun eigen bewerk-gereedschap (woordenlijst-
  editor, opslaan/bibliotheek) - gereedschap dat een leerling in
  werken-modus wél hoort te zien. De kernoefening zelf (spellen,
  slepen) werd hierdoor niet geblokkeerd, dus dit verklaart niet de
  volledige klacht - overige widgets negeren opts.readonly toch al.
- Tegelijk de stille `.catch(()=>{})` op het voortgang-loggen vervangen
  door `console.warn` bij een mislukte POST /my/progress: een mislukte
  log (verlopen sessie, weggehaalde toewijzing, servergolf) verdween
  eerder spoorloos, wat een "werkt niet"-klacht onmogelijk te
  onderzoeken maakte.
- Nieuwe test/progress-logging.test.js dekt het serverpad dat nog
  helemaal geen tests had: leerling-eigen toewijzing wint van
  klasbrede, thuiskind-zonder-school valt terug op de gekoppelde
  ouder, geen-toewijzing geeft 400 zonder insert, niet-leerling geeft
  403, ongeldige widgetId/widgetType geeft 400 - alle zes bevestigen
  dat de SQL/toewijzingslogica zelf klopt, wat het probleem verder
  vernauwt tot de nu twee gefixte punten hierboven of iets dat alleen
  in de echte omgeving van de gebruiker reproduceerbaar is.
- Live geverifieerd: werken-modus toont nu het bewerk-gereedschap in
  letters.js (voorheen verborgen), kijken-modus blijft exact
  ongewijzigd (overlay + verborgen gereedschap). Volledige testsuite:
  118/118.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 14:39:00 +02:00
Ramon
643a00c1c3 feat: personage-aanmoediging uitgebreid naar klok, geld, plaatswaarde en spellen (v0.4.32-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 55s
- De math.js-pilot (v0.4.23-beta: eigen personage kort naast "Goed!" bij
  een juist antwoord) hergebruikt in vier andere widgets, zoals destijds
  al voorzien in de roadmap: klok (mountClock), geld (mountMoney),
  plaatswaarde (mountPlacevalue) en de wereldoriëntatie-spelopdracht
  (mountWorldQuiz - dekt bomen/vogels/planten in één keer - en
  mountTopography).
- Zelfde patroon overal: bij S.feedback==='good' (of S.spellSolved) en
  een ingesteld personage verschijnt renderAvatarFace(...,"md") met de
  av-cheer-animatie naast het bestaande feedbackbericht - puur visueel,
  geen nieuw feedbacktype. Zonder personage blijft het gedrag exact
  ongewijzigd.
- Geverifieerd met echte oplos-interacties (niet alleen mounten): klok
  (typemodus + toetsenbord), geld (typemodus + toetsenbord), plaatswaarde
  (blokken plaatsen via toetsenbord-Enter) en de spelopdracht (letters
  plaatsen via toetsenbord-Enter) - in alle vier verschijnt het
  personage daadwerkelijk in de feedback-HTML na een echt juist
  antwoord. Volledige testsuite: 112/112.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 14:03:58 +02:00
Ramon
c183c8f931 perf: opstart-fetches /auth/me en /me/data parallel i.p.v. serieel (v0.4.31-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 37s
- Beide verzoeken hangen alleen af van dezelfde sessie-cookie, niet van
  elkaars antwoord - ze werden tot nu toe na elkaar aangeroepen
  (hydrateFromServer() startte pas na een voltooide /auth/me), wat een
  hele round-trip extra kost bij elke opstart voor staf/thuisgebruikers.
- app.js vraagt ze nu tegelijk op via Promise.allSettled; hydrateFromServer()
  krijgt het /me/data-resultaat optioneel meegegeven i.p.v. het zelf
  (opnieuw) op te halen. Voor een leerling/ouder wordt dat resultaat
  genegeerd (zij krijgen sowieso geen whiteboard-data) - nooit verspild
  werk, soms ongebruikt, wat de server niet meer kost dan de bestaande
  losse aanroep die er toch al was.
- De twee andere hydrateFromServer()-aanroepen (na inloggen, na een
  save-conflict) geven bewust niets mee en halen gewoon vers op, zoals
  voorheen - alleen de allereerste opstart kan dit parallelliseren.
- Geverifieerd met de volledige testsuite (112/112) en drie losse
  boot-scenario's in de sandbox (gast/staf/leerling): in alle drie komen
  /auth/me en /me/data binnen ~1ms van elkaar aan (voorheen serieel), en
  blijft het bestaande gedrag (gast blijft gast, staf krijgt het bord,
  leerling krijgt de afgeschermde weergave) exact hetzelfde.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 13:43:32 +02:00
Ramon
4e4aeb4b6d feat: exporteren van vers-gegenereerde wachtwoorden als CSV (v0.4.30-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 38s
- "Exporteer als CSV"-knop toegevoegd aan het bestaande multireset-
  resultatenscherm (klas-wachtwoorden resetten in de School-navigator),
  naast de bestaande "kopieer alles"-knop.
- BELANGRIJKE BEPERKING, bewust zo: dit exporteert alleen wat op dit
  scherm al staat (net-gegenereerde wachtwoorden). Wachtwoorden worden
  na het zetten nergens leesbaar bewaard (alleen gehashet in de
  database) - er is dus geen "haal wachtwoorden van bestaande accounts
  op"-mogelijkheid en die komt er ook niet.
- CSV bevat gebruikersnaam (het echte inlogveld) naast de naam, ook al
  toont het scherm zelf alleen de naam - zonder gebruikersnaam is een
  uitdeelvel niet bruikbaar om mee in te loggen.
- Hergebruikt de csvValue()/downloadCsv()-helpers uit de vorige
  resultaten-exportfeature (v0.4.29-beta) - eerste echte tweede
  gebruiker, dus die keuze om ze lokaal in admin.js te houden i.p.v.
  te verplaatsen was terecht.
- Geverifieerd met de volledige testsuite (112/112) en een live
  browserdoorloop: klas-wachtwoorden resetten (dubbele bevestigingsklik)
  → CSV-download met correcte escaping van een leerlingnaam met komma
  én aanhalingsteken.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 13:31:10 +02:00
Ramon
8fe6fc10cc feat: exporteren van resultaten per klas (CSV) (v0.4.29-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 51s
- Nieuwe sectie "Exporteren per klas" in de bestaande Voortgang-tab: klas
  kiezen + "Exporteer als CSV" downloadt de volledige activiteitenlijst
  van die klas (leerling, widget, pogingen, goed, sterren, datum/tijd).
- Bouwt voort op de bestaande route GET /progress/class/:id, die tot nu
  toe geen enkele frontend-consument had.
- Server: nieuwe optionele ?limit=-queryparameter (begrensd op 5000) -
  de export vraagt expliciet meer dan de standaard activiteitenweergave
  (200) op, zodat een drukke klas niet stilzwijgend wordt afgekapt in het
  exportbestand. Zonder de parameter blijft het bestaande gedrag (200)
  ongewijzigd.
- Eerste CSV-export in deze codebase: kleine lokale csvValue()/
  downloadCsv()-helpers in admin.js (komma/quote/newline-escaping,
  BOM zodat Excel-NL accenten en komma-scheiding herkent) - bewust nog
  niet gedeeld/verplaatst naar core.js, want er is nu nog maar één
  gebruiker (de geplande wachtwoorden-export kan dit later hergebruiken).
- Tests: test/progress-export.test.js (limit wordt doorgegeven, te hoge
  waarde wordt afgekapt op 5000, standaardgedrag zonder parameter blijft
  200) + volledige testsuite (112/112). Ook live geverifieerd: klas
  kiezen zonder selectie toont een hint i.p.v. te crashen, een echte
  CSV-download met correcte escaping van komma's/aanhalingstekens in
  een leerlingnaam, en de vertaalde widget-namen in de kolommen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 12:54:48 +02:00
Ramon
09a1326c7e feat: meer personage-accessoires incl. zonnebril (v0.4.28-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m10s
- Nieuwe hoofdaccessoires: zonnebril, koptelefoon, feesthoedje.
- Nieuwe lichaamsaccessoires: ketting, rugtas (bandjes over de
  schouders, zichtbaar van voren).
- Server-validatie (src/api.js) en vertalingen (nl+en) meegewerkt met
  dezelfde nieuwe waarden - anders zou de client een optie tonen die de
  server als "ongeldig hoofdaccessoire" afwijst.
- Geen wijziging aan de bestaande pet/kroon-onderdrukkingsregel nodig:
  zonnebril/koptelefoon/feesthoedje bedekken het bovenhoofd niet volledig,
  dus haar blijft er gewoon zichtbaar naast/onder.
- Geverifieerd: alle select-opties komen aan in de instellingen-editor,
  een PUT met de nieuwe waarden slaagt (bestaande server-validatie
  accepteert ze nu), en alle soort/accessoire-combinaties oogden goed in
  screenshot (zonnebril op de dino, koptelefoon op het monster,
  feesthoedje + ketting samen, rugtas op het dier).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ
2026-07-19 11:55:25 +02:00