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
169 lines
8.2 KiB
Markdown
169 lines
8.2 KiB
Markdown
# 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`, `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).
|