Commit graph

54 commits

Author SHA1 Message Date
Ramon
4ffb69ca61 fix: gebruiker verwijderen toont echte oorzaak i.p.v. kale serverfout (v0.3.97-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m19s
- DELETE /admin/users/🆔 hele handler (niet alleen deleteUserFully) in
  één try/catch, zodat ook een fout vóór het verwijderen zelf (bv. de
  opzoekquery) de echte reden teruggeeft i.p.v. terug te vallen op de
  generieke 500 "serverfout"
- generieke errorhandler logt voortaan altijd het volledige fouteobject en
  geeft ingelogde gebruikers de werkelijke foutmelding mee i.p.v. alleen
  "serverfout"
- test toegevoegd die dit nieuwe pad dekt
2026-07-17 22:27:20 +02:00
Ramon
e48a3a4e46 fix: gebruiker verwijderen werkt gegarandeerd - ruimt afhankelijke rijen zelf op (v0.3.96-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 51s
- De "serverfout" bij verwijderen komt van een foreign key die op de live-database geen ON DELETE CASCADE heeft, waardoor DELETE FROM users faalt zodra er nog een gekoppelde rij bestaat
- Nieuw: de verwijderroute haalt in één transactie eerst alle afhankelijke rijen weg (sessies, rollen, klaskoppelingen, toewijzingen, voortgang, ouderkoppelingen, aanmeldingen, reservekopieën, gedeelde items, afbeeldingen, borden/mappen) en verwijdert daarna de gebruiker - dit werkt ongeacht de exacte FK-instelling en heeft migratie 015 niet nodig
- Mocht verwijderen tóch falen, dan komt nu de echte databasereden terug (constraint-detail) i.p.v. een kale "serverfout", zodat de oorzaak zichtbaar is
- 3 servertests: volledige opruiming in transactievolgorde (afhankelijke rijen vóór users), echte foutreden bij een gesimuleerde fout; 97 tests groen

LET OP: dit werkt pas na deploy van deze versie; v0.3.94 (huidige live) bevat de fix nog niet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-17 21:50:48 +02:00
Ramon
e3036580ce fix: gebruiker verwijderen werkt weer (herstel foreign-key cascade) (v0.3.95-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 32s
- Verwijderen gaf op de live-database een 500 "serverfout". Oorzaak: op databases die zijn ontstaan vóór alle foreign keys ON DELETE CASCADE waren, houdt een tabel de oude constraint (CREATE TABLE IF NOT EXISTS werkt een bestaande constraint nooit bij), waardoor DELETE FROM users een foreign-key-fout geeft
- Migratie 015: zoekt elke FK naar users(id) die niet cascade en niet set-null is en zet die alsnog op ON DELETE CASCADE (bewuste SET NULL-constraints blijven ongemoeid). Draait bij de volgende deploy en is idempotent
- Verwijderroute vangt een resterende FK-fout (23503) op als een begrijpelijke 409 i.p.v. een kale serverfout
- Geverifieerd: alle INSERT INTO users-paden vangen al 23505 op (gebruikersnaam uniek per school); dezelfde naam in verschillende scholen is bewust toegestaan (inloggen kiest de school) en staat sinds 0.3.94 per school gegroepeerd
- 3 nieuwe servertests (FK-fout -> 409, normale verwijdering, migratie-inhoud); 97 tests groen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-17 21:39:29 +02:00
Ramon
c86abcf794 fix: onzichtbare knopteksten, lege klassenlijst en correcte klas-schoolregels (v0.3.93-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 32s
- Onzichtbare knoppen opgelost: .tbtn houdt standaard witte tekst (wit-op-blauw), maar in het beheer staat hij op een lichte achtergrond -> tekst was wit-op-wit. Nu expliciet donkere tekst; de primaire accentknop houdt bewust witte tekst
- Systeemmanager kreeg standaard "alle scholen" waardoor klassen leeg leken en niet toe te voegen waren; er wordt nu meteen een concrete school gekozen (klassen/gebruikers direct gevuld). Contextbalk laat wisselen; "alle scholen" blijft een bewuste keuze
- Lege school toont nu een duidelijke uitleg dat bestaande klassen bij een andere school kunnen horen, met verwijzing naar de schoolkeuze
- Correcte gegevensregels: classes.school_id is NOT NULL met ON DELETE CASCADE, dus een klas kan niet "los" bestaan (die eerdere aanname is teruggedraaid). Een klas is nu te VERPLAATSEN naar een andere school (PATCH weigert null/ongeldig); een verwijderde school neemt zijn klassen mee (cascade) - dat verklaart verdwenen klassen
- Bij een leerling naar een andere school koppelen blijft de klas behouden als die al bij de doelschool hoort
- Verificatie uitgebreid met een echte kleurcontrast-scan (vangt wit-op-wit) over alle secties + de default-school-flow; alle 94 servertests en 8 Playwright-suites groen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-17 20:22:36 +02:00
Ramon
aee1c59fbd fix: leerlingen zichtbaar bij gekozen school + uniforme controls in het beheer (v0.3.92-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 35s
- Leerlingen stonden onder standaard-ingeklapte klasgroepen, dus met een gekozen school leek de lijst leeg terwijl de detailweergave de juiste school toonde. Klasgroepen staan nu standaard open zodra een school is gekozen (de schoolkeuze wás al het filter); bewust dichtklappen wordt onthouden
- Losse klassen (school verwijderd) waren nergens zichtbaar: de systeemmanager ziet ze nu zonder gekozen school met een uitleg, en kan ze via een School-veld terugkoppelen; nieuwe PATCH /admin/classes/:id + GET ?school=none (super) met servertests
- Bij het aan een school koppelen van een leerling blijft de klasindeling behouden als die klas al bij de doelschool hoort (eerst klas terugkoppelen, dan de leerlingen)
- UI-consistentie: één uniforme control-hoogte (32px) voor álle knoppen, selects en invoervelden in Instellingen - einde aan de grote maatverschillen; T() valt terug op NL en dan de sleutelnaam zodat een knop nooit zonder tekst kan staan
- Status in de gebruikerstabel als compacte glyph (● in gebruik / ○ wacht) met uitleg bij aanwijzen i.p.v. een afgekapte "nog niet ing…"-chip
- Geverifieerd in headless Chromium: nieuwe suite (21 checks: zichtbaarheid met schoolfilter, losse klassen, geen lege knoppen, uniforme hoogte over 8 secties) + volledige regressie van 5 bestaande suites

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-17 19:46:09 +02:00
Ramon
b4eee9f78f feat: gebruikers aan een school koppelen en losmaken (v0.3.90-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 52s
- PATCH /admin/users/:id ondersteunt schoolId (alleen systeemmanager, rollen teacher/admin/pupil): null = losmaken, anders koppelen met bestaanscheck (404); bij wissel worden klas, klaskoppelingen en (voor leerlingen) oude toewijzingen opgeruimd; naamconflicten in doelschool of school-loze naamruimte geven een nette 409
- Detailpaneel toont voor de systeemmanager een School-veld bij deze rollen - losse accounts (ooit aan een school gekoppeld) zijn hiermee terug te zetten en bewust los te maken; werkt ook in de beheerder-subrijen op het Scholen-tabblad
- Gebruikers-tab (alle scholen): losse accounts staan in een eigen inklapbare groep "Zonder school (n)" i.p.v. onopvallend tussen de rolgroepen; de oudergroep is nu ook inklapbaar
- 3 nieuwe servertests (koppelen incl. opruiming, losmaken, 404, geen rechten/no-op voor admin en parent, 409 bij naamconflict) + 10 Playwright-checks voor de volledige flow

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-17 14:30:41 +02:00
Ramon
aa4c5faaf9 feat: server-kant CMS voor de systeemmanager (v0.3.83-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 31s
- Migratie 014: site_content (sleutel/waarde, JSONB) voor site-inhoud die zonder release aanpasbaar moet zijn
- GET /content (publiek): welkomstwoord, update-melding en widget-uitleg in één antwoord - het inlogscherm toont het welkomstwoord al vóór het inloggen
- PUT /admin/content/:key (alleen systeemmanager, nieuwe permissie content.manage): upsert per toegestane sleutel (welcome/announcement/widgetInfo) met maat-limieten
- 4 servertests: publiek lezen, upsert door super, 403/401 voor anderen, whitelist/vorm/omvang-validatie

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 19:29:08 +02:00
Ramon
2fff8a3aa5 perf: gzip-vangnet in nginx voor geproxyde responses (v0.3.82-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m4s
- gzip on + gzip_proxied any (zonder die laatste comprimeert nginx geproxyde responses helemaal niet) + gzip_vary + min_length 1024 voor css/js/json/svg/tekst
- Geen dubbele compressie: responses die al Content-Encoding dragen (brotli/gzip uit de app) laat nginx ongemoeid; dit vangt alleen wat de app mist
- Cache-beleid blijft bewust op één plek (de app), zodat lokaal en productie identiek gedragen
- Configtest erbij in security-config-stijl

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 19:02:53 +02:00
Ramon
456d664718 perf: compressie, cache-headers, cache-busting en parallel ladende scripts (v0.3.81-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 1m14s
- @fastify/compress (brotli quality 4 + gzip, global): alle statische assets én API-JSON (zoals /me/data) gaan gecomprimeerd over de lijn - eerste lading van ~715 KB naar grofweg een derde
- Nieuw src/frontend.js: index.html wordt bij boot één keer gelezen, ?v=__V__ wordt vervangen door de app-versie en de pagina wordt uit het geheugen geserveerd met no-cache
- Cache-beleid per prefix: js/css een jaar immutable (veilig dankzij de geversioneerde URL's), fonts 7 dagen, afbeeldingen 1 dag met zwakke etag als 304-vangnet - herhaalbezoek kost vrijwel geen bytes meer
- Alle 31 scripts staan nu met defer in de head: parallel downloaden, uitvoeren in dezelfde dwingende volgorde (core → widgets → board → app); font-preload bewust ongeversioneerd (moet byte-gelijk blijven aan de url() in teach.css)
- Compress geregistreerd vóór de api/frontend-registraties (onSend-hook geldt alleen voor latere routes) - geborgd met een teksttest
- 6 nieuwe tests (test/frontend.test.js): versie-injectie, cache-headers per prefix, gzip+brotli round-trip, 304 op etag, defer/?v= op elk script

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 19:01:25 +02:00
Ramon
cb97dc2bb1 feat: breid taalwidgets en plaatjesbibliotheek uit (v0.3.80-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 31s
2026-07-16 16:27:38 +02:00
Ramon
4356658c96 fix: versietest pint geen vast nummer meer (v0.3.79-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 43s
- De CI faalde omdat een test het versienummer hardcodeerde (0.3.77-beta) en dus bij elke reguliere versiebump breekt
- De test bewaakt nu het echte beleid: de dev-branch voert altijd een -beta-versie en de VERSION-file loopt gelijk met de const in core.js (die controle stond er al en blijft)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 15:01:59 +02:00
Ramon
7a5d7c57ff feat: maak widgets speelser en kindvriendelijker (v0.3.77-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 41s
2026-07-16 14:15:28 +02:00
Ramon
abafcafe3a feat: breid natuurwidgets uit
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 30s
2026-07-16 13:43:46 +02:00
Ramon
93c287979c feat: breid wereldorientatie-oefeningen uit (v0.3.71-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 30s
2026-07-16 11:44:30 +02:00
Ramon
100dc62087 feat: verbeter wereldorientatie met echte beelden (v0.3.70-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
2026-07-16 10:31:50 +02:00
Ramon
88d1f9cb86 feat: voeg wereldorientatiewidgets toe (v0.3.69-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 26s
2026-07-16 09:42:45 +02:00
Ramon
22233c5f92 fix: laat de minutenwijzer de urenwijzer verzetten (v0.3.68-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 24s
2026-07-16 09:14:15 +02:00
Ramon
66fbac7221 fix: laat de oefenklok door alle 24 uren draaien (v0.3.67-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
2026-07-16 08:53:09 +02:00
Ramon
ecf60304a9 fix: centreer widgetopdrachten en herstel 24-uursinvoer (v0.3.66-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 39s
2026-07-16 08:41:26 +02:00
Ramon
99e807595a feat: alle widgets mobielvriendelijk maken (v0.3.64-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 51s
2026-07-16 08:02:20 +02:00
Ramon
bdb5ef9875 feat: instellingen volledig herbouwd - sectieregister, rolweergaven en zoeken (v0.3.60-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 34s
- Nieuwe architectuur: één sectieregister (settings.js) als enige bron van waarheid; secties melden zich aan met rol-zichtbaarheid, activate() en zoekgegevens - de schil kent het beheer niet van binnen
- Nieuwe indeling: navigatie links (gegroepeerd Persoonlijk / School / Systeem), inhoud rechts met sectiekop + toelichting; zakelijk en rustig, responsief op smalle schermen
- Alles doorzoekbaar: één zoekbalk vindt secties, instellingen (trefwoorden, o.a. wachtwoord/thema/taal) én data - gebruikers, klassen en scholen op naam; klik navigeert en filtert de gebruikerslijst direct op de treffer
- Per rol alleen de essentie: gast alleen Weergave; leerling en ouder Account + Weergave; groepsleiding + Gebruikers/Toewijzingen/Voortgang; schoolbeheerder ook Klassen; systeemmanager ook Systeem en Opslag
- Thuiskinderen (leerling zonder school) krijgen nu zoals ontworpen het volledige whiteboard met eigen opslag en reservekopieën; schoolleerlingen blijven beperkt tot de toewijzing
- Oude dubbele tabbalk en #adminTabsSlot verwijderd; beheerdata laadt één keer per bezoek en wordt tussen secties hergebruikt
- 28 Playwright-checks over zes rollen (navigatie, zoeken, filteren, thuiskind-whiteboard)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 07:07:53 +02:00
Ramon
42fc323ab1 fix: toon gekoppelde ouders in de gebruikerslijst van de school (v0.3.59-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 28s
- Ouders (school_id NULL) vielen buiten elke schoolgescopeerde gebruikerslijst; /admin/users levert nu ook de ouders die aan leerlingen van de school gekoppeld zijn (groepsleiding: alleen ouders van leerlingen uit eigen klassen)
- Ouder-rijen tonen de namen van hun gekoppelde kinderen (childNames)
- Servertest voor de gekoppelde-ouders-lijst

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 00:23:51 +02:00
Ramon
9d83e13bc3 feat: server-kant ouderportaal (v0.3.57-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 36s
- Nieuwe rol parent (school_id NULL): registreert zichzelf via POST /auth/register-parent (rate-limited, stafwachtwoordregels, directe sessie)
- Migratie 013: parent_children-koppeltabel, eenmalige users.parent_code, school_link_requests (aanmeldverzoeken, uniek per kind+school)
- Ouderroutes: kinderen bekijken (met school/klas/aanmeldstatus), thuiskind aanmaken (pupil zonder school, wachtwoord eenmalig terug), koppelen via ouder-code, aanmelden bij school, ontkoppelen
- Staf: ouder-code genereren per leerling, aanmeldingen bekijken en afhandelen (adopteren in klas met optionele nieuwe gebruikersnaam, koppelen aan bestaande leerling met opruiming van lege thuisaccounts, afwijzen)
- Voortgang: thuiskind zonder toewijzing logt met de gekoppelde ouder als leerkracht (bord "thuis"); gekoppelde ouders mogen de voortgang van hun kind opvragen
- 18 nieuwe servertests (registratie, koppelmodel, aanmeldflow, resolve-acties, voortgang)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-16 00:02:16 +02:00
Ramon
a9bf2270d0 fix: beperk rollen en klaskoppeling tot staf (v0.3.56-beta)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 38s
- Functie-select in gebruikersbeheer alleen zichtbaar voor staf-rollen (teacher/admin/super)
- Klaskoppeling-UI alleen voor staf-rollen
- Server: rolwijziging alleen tussen staf-rollen onderling (leerlingen en toekomstige ouder-accounts kunnen nooit promoveren)
- Server: klaskoppeling weigert alle niet-staf-rollen expliciet
- canPersist() sluit de komende ouderrol uit van borden-opslag
- Servertest: ouder-achtige rol krijgt geen promotie en geen klaskoppeling

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
2026-07-15 23:56:39 +02:00
Ramon
0d644ba41d feat: voeg afbeeldingscatalogus en opslagquota toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
2026-07-15 23:45:17 +02:00
Ramon
3ad7c80bad feat: koppel geldniveaus aan realistische winkelprijzen
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 24s
2026-07-15 22:51:49 +02:00
Ramon
54a95b2c19 revert: herstel officiële biljetten 2026-07-15 22:36:42 +02:00
Ramon
ff91ae0f2b test: gebruik eigen oefenbiljetten zonder markering
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 38s
2026-07-15 22:32:20 +02:00
Ramon
2742196c11 feat: toon echt euromateriaal in geldwidget
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 47s
2026-07-15 22:19:15 +02:00
Ramon
2fa9879107 feat: maak geld realistischer en uitsleepbaar
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 23s
2026-07-15 21:59:38 +02:00
Ramon
c2e6622546 feat: breid geldrekenen uit met niveaus en spellen
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 21s
2026-07-15 21:45:40 +02:00
Ramon
2d176cfc30 feat: voeg 24-uursoptie aan oefenklok toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 30s
2026-07-15 21:31:57 +02:00
Ramon
d900c25339 feat: breid niveau drie en wijzerbediening uit
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 23s
2026-07-15 21:10:31 +02:00
Ramon
e0220cdd00 fix: toon klokniveaus en verplaats koppeling
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 32s
2026-07-15 21:03:59 +02:00
Ramon
6e920e32db feat: koppel klokwijzers en start direct
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 20s
2026-07-15 20:53:47 +02:00
Ramon
cd15c0435b feat: voeg klokniveaus en typmodus toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 21s
2026-07-15 20:47:22 +02:00
Ramon
6e17dc5982 fix: voeg vrije uurmarkeringen toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 21s
2026-07-15 20:38:30 +02:00
Ramon
54782781bf fix: voorkom overlap op klokwijzerplaat
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 50s
2026-07-15 20:35:49 +02:00
Ramon
4cc8d466b8 feat: voeg sleepbare tijdblokken toe
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
2026-07-15 20:32:12 +02:00
Ramon
72ea486518 feat: verbeter klokopdrachten en bediening
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 44s
2026-07-15 20:23:21 +02:00
Ramon
d02f7de72d feat: maak oefenklok visueel bedienbaar
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 20s
2026-07-15 20:12:43 +02:00
Ramon
3efe57b43c feat: breid oefenklok uit met niveaus en spellen
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 27s
2026-07-15 20:05:50 +02:00
Ramon
7287e49e0c v0.3.38-beta: koppel ook schoolbeheerders en systeemmanagers aan klassen
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 23s
- De klas-koppeling (chips + "voeg toe aan klas…") staat nu bij elke
  staf-rol, niet alleen bij groepsleiding; de klasnamen staan ook in de
  rijkop ("Schoolbeheerder · Groep 4")
- Server: /admin/classes/:id/teachers accepteert alle staf-rollen; alleen
  leerlingen niet (die horen al bij één klas). Een systeemmanager is
  school-onafhankelijk en mag aan klassen van elke school; overige staf
  moet bij dezelfde school horen
- Nieuwe servertest: admin en super koppelen ok, leerling en staf van een
  andere school geweigerd
2026-07-15 16:35:55 +02:00
Ramon
df921d5968 v0.3.36-beta: scholen mét schoolbeheerders in het Systeem-tabblad
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 33s
- Systeem toont per school een rij in klassen-stijl (🏫, accentkleur,
  aantal schoolbeheerders) met daaronder de schoolbeheerders als duidelijk
  onderscheiden subrijen (🛡, ingesprongen, eigen randkleur)
- Beide zijn in dit menu aan te passen via hetzelfde ✏-gereedschap:
  de school heeft een Naam-veld (nieuwe route PATCH /admin/schools/:id,
  alleen systeemmanager) en de bevestigde verwijder-actie; beheerders
  hebben hun volledige gereedschap (functie, extra functies, code,
  wachtwoord, verwijderen)
- Systeem-tab laadt beheerders van álle scholen, ook als de contextbalk
  elders op één school staat
- Drie nieuwe servertests voor het hernoemen (super ok, admin 403,
  naamvalidatie)
2026-07-15 16:02:57 +02:00
Ramon
24180beec1 v0.3.28-beta: alleen-lezen-vlag voor gedeelde items (server)
- Nieuwe migratie db/011: shared_library.readonly (default false)
- Beheerregel aangescherpt: een vergrendeld school-item is ook voor de
  eigenaar alleen-lezen; alleen schoolbeheerder en systeemmanager kunnen
  het nog wijzigen (systeem-items waren al alleen-lezen voor iedereen
  behalve de systeemmanager) - kopiëren blijft altijd werken
- De vlag zetten/weghalen kan per item (PATCH readonly) of per map
  (PATCH /shared/:kind/folder met {from, readonly}), uitsluitend door de
  schoolbeheerder van die school of de systeemmanager
- Lijst/detail geven readonly + canLock terug voor de UI; drie nieuwe tests
2026-07-14 22:49:17 +02:00
Ramon
939c4ee68b v0.3.26-beta: server-API voor de gedeelde bibliotheek
- Nieuwe migratie db/010: shared_library-tabel (school_id NULL =
  systeembreed, anders per school; kind board/anchor; folder als pad)
- Routes: GET /shared/:kind (lijst, gefilterd op systeembreed + eigen
  school), GET /shared/:kind/:id (met data, voor kopiëren), POST (publiceren;
  scope global vereist systeemmanager, scope school staf met school),
  PATCH/DELETE per item en PATCH /shared/:kind/folder (prefix-rewrite,
  alleen als álle items onder het pad beheerd mogen worden)
- Beheerregel: systeemmanager altijd, eigenaar altijd, schoolbeheerder voor
  items van de eigen school; leerlingen hebben geen toegang
- Nieuwe permissies shared.global.manage / shared.school.manage (beide
  permissions.js); zes nieuwe servertests
2026-07-14 22:27:16 +02:00
Ramon
86478ebaca v0.3.24-beta: bewaar ankerdiagrammen los van het bord (bibliotheek)
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 18s
- Nieuwe ankerbibliotheek ANCHOR_LIB, opgeslagen in een eigen data-sectie
  "anchors" (server-whitelist + 5MB-cap; lijst i.p.v. object toegestaan);
  reist mee in de volledige save, hydrate, gastreset en reservekopie-herstel
- Ankerwidget: 💾 bewaart het huidige diagram (naam = middelwoord, met
  ✓-feedback; leeg diagram wordt geweigerd met een hint), 🗂 opent dezelfde
  Windows-stijl mappenverkenner met de bewaarde diagrammen (geneste mappen,
  slepen, hernoemen, verwijderen)
- Dubbelklik op een bewaard diagram laadt het in het widget (cellen +
  plaatjes, thema-spiegel en bord-autosave volgen automatisch)
- Nieuwe servertest: anchors-sectie accepteert een lijst, andere secties
  weigeren die (en andersom)
2026-07-14 22:14:37 +02:00
Ramon
2ce82ab998 v0.3.19-beta: verstuur bij het opslaan alleen gewijzigde secties
- Nieuwe route PUT /me/data/:section (boards/themes/generalExtra): vervangt
  alleen die sub-key via jsonb_set, met dezelfde rev/409-controle en
  snapshot-hook als de volledige PUT (die blijft bestaan als terugval)
- Per-sectie size-caps (boards 20MB, themes/generalExtra 2MB)
- core.js: DIRTY-set houdt bij wat er gewijzigd is; woordwijzigingen sturen
  alleen themes+generalExtra, bordwijzigingen alleen boards (sequentieel,
  rev per respons bijgewerkt); zonder gerichte wijziging volledige save
- Twee nieuwe servertests (jsonb_set op de juiste sub-key, onbekende sectie
  is 404)
2026-07-14 16:26:16 +02:00
Ramon
6980d72041 v0.3.18-beta: bewaar en herstel eerdere versies van borddata
- Elke data-write bewaart eerst de oude data in user_data_versions (hooguit
  één snapshot per 10 minuten, maximaal 10 versies per gebruiker)
- Nieuwe routes: GET /me/data/versions (lijst) en POST /me/data/restore
  (zet een versie terug; bewaart de huidige data eerst zodat herstel zelf
  ook omkeerbaar is); beide niet voor leerlingen
- Nieuw blok "Reservekopieën" in Instellingen → Account met datum/tijd per
  versie en een herstelknop met bevestigingsstap (arm-then-confirm)
- Vier nieuwe servertests (snapshot vóór write, opruimen op 10, pupil-403,
  restore bewaart huidige data eerst)
2026-07-14 16:23:10 +02:00
Ramon
b28d25296d v0.3.17-beta: detecteer save-conflicten tussen tabbladen
- Nieuwe migratie db/009: users.data_rev + data_updated_at en de
  user_data_versions-tabel (voor de komende versiegeschiedenis)
- GET /me/data geeft nu {data, rev}; PUT /me/data controleert een optionele
  x-data-rev-header en weigert een verouderde schrijver met 409 (zonder
  header blijft het oude laatste-schrijver-wint-gedrag voor oude clients)
- core.js: rev wordt bijgehouden en meegestuurd; bij 409 toont de opslaan-
  knop "Elders bewerkt" en haalt een klik eerst de nieuwste serverversie op
  in plaats van te overschrijven
- beforeunload-waarschuwing bij een openstaande, lopende of mislukte save
- Nieuwe test test/save-system.test.js (rev mee, 409, legacy zonder header)
2026-07-14 16:19:25 +02:00