teach/db/013_parent_portal.sql
Ramon 9d83e13bc3
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 36s
feat: server-kant ouderportaal (v0.3.57-beta)
- 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

30 lines
1.5 KiB
SQL

-- v0.3.57-beta: ouderportaal.
-- Ouders (role 'parent', school_id NULL) koppelen aan kind-accounts (pupils):
-- * parent_children: de koppeling zelf (een kind kan meerdere ouders hebben).
-- * users.parent_code: eenmalige code waarmee staf een schoolleerling aan een
-- ouder koppelt (code vervalt na gebruik).
-- * school_link_requests: aanmeldverzoek van een thuiskind (pupil zonder
-- school) bij een school; de school handelt het verzoek af (adopteren,
-- koppelen aan een bestaande leerling of afwijzen).
CREATE TABLE IF NOT EXISTS parent_children (
parent_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
pupil_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (parent_id, pupil_id)
);
CREATE INDEX IF NOT EXISTS idx_parent_children_pupil ON parent_children(pupil_id);
ALTER TABLE users ADD COLUMN IF NOT EXISTS parent_code TEXT;
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_parent_code
ON users (parent_code) WHERE parent_code IS NOT NULL;
CREATE TABLE IF NOT EXISTS school_link_requests (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
school_id BIGINT NOT NULL REFERENCES schools(id) ON DELETE CASCADE,
parent_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
pupil_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (pupil_id, school_id)
);
CREATE INDEX IF NOT EXISTS idx_school_link_requests_school ON school_link_requests(school_id);