Nieuw: scripts/install.sh — installeert de stack in zeven zichtbare stappen
met drie vragen, standaard in /srv/server-up (aan te passen met
ROOSTERWIJS_DIR). Het script:
- controleert git, docker, de compose-plugin en of de daemon bereikbaar is;
- maakt de doelmap aan, of legt uit welk commando daarvoor nodig is als de
rechten ontbreken (roept zelf geen sudo aan);
- kloont of werkt de checkout bij;
- laat kiezen waar de gegevens komen (zie hieronder);
- genereert .env met een willekeurige DJANGO_SECRET_KEY en een sterk
databasewachtwoord, en zet hostnaam, CSRF-origin en DJANGO_SECURE op basis
van twee vragen; een bestaande .env wordt nooit zomaar overschreven;
- bouwt en start de containers;
- meldt of er een account is en biedt aan er een aan te maken.
Opslagkeuze bij de installatie:
- docker-compose.yml gebruikt nu ${DATA_DB}, ${DATA_MEDIA} en ${DATA_STATIC}.
Een naam = Docker-volume, een pad = gewone map naast de code.
- De standaardwaarden zijn de bestaande named volumes, dus installaties die
al draaien veranderen niet en er gaan geen gegevens verloren.
- Kies je voor mappen, dan komt alles onder /srv/server-up/data/.
Verder:
- .gitignore: /data/ uitgesloten. Zonder dat zou de gegevensmap als lokale
wijziging gelden en zou deploy.sh weigeren te draaien.
- deploy.sh maakt de gegevensmappen aan als de opslagkeuze paden gebruikt,
zodat Docker ze niet als root aanmaakt.
- DEPLOY.md en README: installatie via het script, de opslagkeuze in een
tabel, en de dump/restore-stappen die nodig zijn bij het omzetten van
volumes naar mappen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAQ4Np13v8fwbTtKHKnwDz
|
||
|---|---|---|
| .github/workflows | ||
| .ui-backup | ||
| backend | ||
| frontend | ||
| scripts | ||
| .env.example | ||
| .gitignore | ||
| DEPLOY.md | ||
| docker-compose.yml | ||
| PLAN.md | ||
| README.md | ||
| ROADMAP.md | ||
| SECURITY-AUDIT.md | ||
Roosterwijs
Modulair, flexibel roostersysteem voor het speciaal onderwijs (uil-logo: een
uil staat voor wijsheid → Roosterwijs). Zie PLAN.md voor de visie en de
fasering, en DEPLOY.md voor draaien op een test-/productieserver.
Status: Fase 0–4 klaar. Fase 0 (plugin-framework), Fase 1 (personen, groepen, subgroepen, functies), Fase 2 (schooljaarkalender + roosterblokken), Fase 3 (afwezigheid, uitzonderingen, effectief weekrooster) en Fase 4 (conflictdetectie: dubbele inzet van begeleider/leerling en locatiebotsingen).
Het Rooster-scherm is een weekweergave met drag-and-drop (muis én touch) en een touch-vriendelijk ontwerp; vrije dagen, afwezigheid en uitzonderingen worden automatisch verwerkt. De Roostermaker heeft tabs Week / Genereren / Instellingen: onder Instellingen beheer je schooljaar + kalender, tijdvakken, vakken, lokalen, locaties en vormgeving; onder Genereren zitten de Vak-wizard en het Auto-rooster. Conflicten verschijnen als melding boven het weekrooster, niet als aparte tab. De zijbalk groepeert items onder inklapbare submenu's (Personen, Groepen) en heeft onderaan een subtiel Instellingen-blok met Gebruikers en Modulebeheer.
Er zijn twee rooster-schermen: Rooster (alleen-lezen weergave, om te bekijken en af te drukken) en Roostermaker (de aanpasser met drag-and-drop, tabs en conflictdetectie). In de Roostermaker open je een blok met een klik om het te bewerken (vak, locatie, doelgroep, begeleiders, opmerking) of te kopiëren naar andere tijden/dagen. Het aparte scherm Groepsindeling (zijbalk → Organisatie) verdeelt een hoofdgroep of leerplein kolomsgewijs in subgroepen, met per subgroep de vakken en de verantwoordelijke(n), en je kunt er direct subgroepen toevoegen. Beide roosterschermen hebben een scope-filter (alles / per klas / per leerplein / per leerling / per personeel); de module Printen/Exporteren voegt — als die aanstaat — een subtiele Afdrukken-knop toe die het (gefilterde) weekrooster printvriendelijk afdrukt of als PDF bewaart.
Optionele module Multi-user & toegang: een Gebruikers-scherm (onder Instellingen, alleen voor beheerders) om inloggers te beheren — gebruikersnaam, wachtwoord, rol (beheerder/medewerker/ouder/leerling), koppeling aan een persoon, en actief/beheerder-status.
Optionele module Leerplein: koppelt subgroepen aan groepen en bundelt groepen, subgroepen én losse leerlingen onder een overkoepelend leerplein. Optionele module Stage: interne en externe stages van leerlingen — beide met een begeleider, een interne stage ook met een ruimte. Beide modules zijn aan/uit te zetten via Modulebeheer.
Fase 5 (recent): vaste tijden zijn per groep aan te passen (een tijdslot zonder groep = algemene tijd, met groep = afwijkende tijd). Personeel en leerlingen hebben gescheiden invoerschermen. Bij personeel koppel je direct functie(s), stamgroep/plein en de vakken die ze kunnen geven; een leerkracht krijgt de theorievakken automatisch. Bij een leerling leg je groep en geboortedatum vast.
Wat er nu staat
- Backend (
backend/) — Django + Django REST Framework.plugins/— het plugin-framework: een moduleregister, opslag van de aan/uit-status per module en een beheer-API.core/— de kern (altijd actief): personen, groepen, subgroepen, functies, schooljaar + kalender, tijdvakken, activiteiten, locaties, lokalen, roosterblokken en conflictdetectie, elk met een CRUD-API.modules/— twaalf modules die zich bij opstarten aanmelden bij het register:printing,accounts,leerplein,stage,uren,blokwizard,personenwizard,autorooster,huisstijl,importexport,vervangingenportal. De volledige lijst staat inMODULE_APPSinbackend/config/settings.py.
- Frontend (
frontend/) — React (Vite). Zijbalk met Roosterwijs-logo die alleen menu's toont van ingeschakelde modules, beheerschermen voor Personen, Groepen en Subgroepen, en een scherm Modulebeheer.
Hoe modulariteit werkt (het verkoopargument)
- Een module is een gewone Django-app met een
apps.pydie inready()eenModuleSpecregistreert (naam, beschrijving, versie, afhankelijkheden en menu-items). - Het register weet wélke modules bestaan; de database onthoudt of ze aan staan. Een beheerder schakelt ze per school in/uit via Modulebeheer.
- Uitgeschakelde modules leveren geen menu's of schermen — de kern blijft overal gelijk, modules zijn los bij te schakelen.
Een nieuwe module toevoegen = nieuwe app maken, één regel in
MODULE_APPS (in backend/config/settings.py), klaar.
Installeren op een server
Eén commando, zeven stappen, drie vragen. Alles komt standaard in
/srv/server-up:
git clone <jouw-forgejo-url>/roosterwijs.git /tmp/roosterwijs-install
/tmp/roosterwijs-install/scripts/install.sh
Het script controleert Docker, haalt de code op, laat je kiezen of de gegevens
in Docker-volumes of in gewone mappen (/srv/server-up/data/) komen,
genereert .env met willekeurige geheimen, bouwt de containers en maakt een
beheerder aan. Bijwerken doe je daarna met ./scripts/deploy.sh.
Details, de opslagkeuze en het draaien achter TLS staan in DEPLOY.md.
Starten (lokaal ontwikkelen)
Voor een test- of productieserver gelden andere stappen: zie
DEPLOY.md. Daar draait alles in Docker en komt de configuratie uit.env.
Backend (Django, poort 8000)
cd backend
python3 -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# Zonder DJANGO_DEBUG=1 weigert Django te starten: buiten debug is
# DJANGO_SECRET_KEY verplicht. Met debug aan valt hij terug op een dev-sleutel.
export DJANGO_DEBUG=1 # Windows: $env:DJANGO_DEBUG="1"
python manage.py migrate
python manage.py createsuperuser # VERPLICHT, zie hieronder
python manage.py runserver
createsuperuser is geen optionele stap. De hele API staat op
IsAuthenticated en de frontend toont eerst een inlogscherm; zonder account kom
je nergens binnen — ook niet in de app zelf, niet alleen in /admin/.
Zonder POSTGRES_DB in de omgeving gebruikt de backend automatisch SQLite in
backend/db.sqlite3. DEPLOY.md zet PostgreSQL in via .env.
API-eindpunten:
GET /api/modules/— alle modules met status.POST /api/modules/<key>/state/— body{"enabled": true|false}.GET /api/info/— korte systeem-/gezondheidsinfo.- CRUD-endpoints (telkens met
PATCH/DELETEop/<id>/):/api/personen/(filter?rol=leerling),/api/groepen/,/api/subgroepen/,/api/functies/,/api/schooljaren/,/api/kalenderdagen/(filter?schooljaar=<id>),/api/tijdsloten/,/api/activiteiten/,/api/locaties/,/api/roosterblokken/(filters?schooljaar=,?groep=,?subgroep=,?leerling=),/api/afwezigheden/(filters?persoon=,?van=,?tot=),/api/blok-uitzonderingen/(filters?roosterblok=,?schooljaar=,?van=,?tot=). GET /api/conflicten/?schooljaar=<id>— roosterconflicten (dubbele inzet, locatiebotsing, onderbezetting).- Module Leerplein:
/api/leerpleinen/,/api/subgroep-groep-koppelingen/. - Module Stage:
/api/stages/(filters?type=intern|extern,?leerling=<id>). - Tijdsloten kennen een optionele
groep(per-groep tijden); personen hebbenstamgroep,vakkenengeboortedatum; activiteiten eentheorievak-vlag. /admin/— Django-admin (personen, groepen, subgroepen en modulestatus).
Draait SQLite niet op je projectmap (bv. op een netwerkschijf)? Zet dan
ROOSTER_DB_PATHnaar een lokaal pad, of pasDATABASESaan.
Frontend (React, poort 5173)
Vereist Node 20.19+ of 22.12+ — Vite 8 weigert oudere versies.
Controleer met node -v.
cd frontend
npm install
npm run dev
De dev-server stuurt /api automatisch door naar de backend op poort 8000.
Open daarna http://localhost:5173 en ga naar Modulebeheer om modules
aan/uit te zetten.
Volgende stap (Fase 5 & 6)
De losse modules verder uitbouwen: Printen/Exporteren (roosters als PDF) en Multi-user & toegang verfijnen (leerling-/ouder-/collega-rollen). Eventueel de conflictdetectie datum-specifiek maken (rekening houdend met afwezigheid per dag).