roosterwijs/README.md
Ramon f795e85333
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
Installatiescript met opslagkeuze, standaard /srv/server-up (v0.2.04 beta)
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
2026-08-19 15:17:08 +02:00

169 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 04** 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`, `vervanging` en `portal`. De volledige lijst staat in
`MODULE_APPS` in `backend/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)
1. Een module is een gewone Django-app met een `apps.py` die in `ready()` een
`ModuleSpec` registreert (naam, beschrijving, versie, afhankelijkheden en
menu-items).
2. Het register weet wélke modules bestaan; de database onthoudt of ze **aan**
staan. Een beheerder schakelt ze per school in/uit via Modulebeheer.
3. 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`:
```bash
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)
```bash
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`/`DELETE` op `/<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 hebben
`stamgroep`, `vakken` en `geboortedatum`; activiteiten een `theorievak`-vlag.
- `/admin/` — Django-admin (personen, groepen, subgroepen en modulestatus).
> Draait SQLite niet op je projectmap (bv. op een netwerkschijf)? Zet dan
> `ROOSTER_DB_PATH` naar een lokaal pad, of pas `DATABASES` aan.
### Frontend (React, poort 5173)
Vereist **Node 20.19+ of 22.12+** — Vite 8 weigert oudere versies.
Controleer met `node -v`.
```bash
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).