Rooster (Backend)
Technisch Ontwerp
De backend van de module Rooster in Remedice beheert de roosterstructuur (werkdagen, dagdelen, taken, minimale bezetting) en de wekelijkse toewijzing van medewerkers aan die structuur. Het systeem werkt met een concept/gepubliceerd-workflow: een WeekRooster heeft de status concept totdat een geautoriseerde gebruiker publiceert, waarna pushnotificaties worden verstuurd via de notificatieservice.
Alle business-logica zit in services.py. De views zijn dun: ze parseren parameters, controleren aanvullende permissies en delegeren naar de servicelaag. Het opslaan van een weekrooster en het vervangen van toewijzingen zijn volledig atomair via @transaction.atomic.
Een Celery-taak ruimt periodiek verouderde roosters op: concept-roosters ouder dan 4 weken en gepubliceerde roosters ouder dan 2 jaar worden verwijderd.
Datamodel (ERD)
erDiagram
RoosterWerkdag ||--o{ RoosterDagdeel : "bevat"
RoosterDagdeel ||--o{ RoosterMinBezetting : "vereist"
RoosterDagdeel ||--o{ WeekRoosterAssignment : "gepland in"
RoosterDagdeel ||--o{ VasteWerkdag : "heeft vaste dag"
RoosterTaak ||--o{ RoosterMinBezetting : "heeft norm"
RoosterTaak ||--o{ WeekRoosterAssignment : "toegewezen"
WeekRooster ||--o{ WeekRoosterAssignment : "bevat"
User ||--o{ WeekRoosterAssignment : "is toegewezen"
User ||--o{ VasteWerkdag : "heeft vaste werkdag"
RoosterWerkdag {
uuid id PK
smallint day_index "0-6, uniek"
smallint sort_order
}
RoosterDagdeel {
uuid id PK
uuid werkdag_id FK
string name
string start_time "HH:MM"
string end_time "HH:MM"
smallint sort_order
}
RoosterTaak {
uuid id PK
string name
string color "hex"
smallint sort_order
}
RoosterMinBezetting {
uuid id PK
uuid taak_id FK
uuid dagdeel_id FK
smallint min_count
}
WeekRooster {
uuid id PK
date week_start_date "uniek, db_index"
string status "concept | published"
bigint created_by_id FK "nullable, SET_NULL"
datetime created_at
datetime updated_at
datetime published_at "nullable"
json last_published_grid "nullable, snapshot"
}
WeekRoosterAssignment {
uuid id PK
uuid week_rooster_id FK
smallint day_index
uuid dagdeel_id FK "PROTECT"
bigint employee_id FK
uuid taak_id FK "nullable, SET_NULL"
}
VasteWerkdag {
uuid id PK
bigint employee_id FK
smallint day_index
uuid dagdeel_id FK
}
Het PlanningGrid-formaat dat de frontend verstuurt en dat de backend opslaat:
{day_index: {dagdeel_id: {employee_id: taak_id | null}}}.
Het veld last_published_grid op WeekRooster slaat een snapshot van het grid op bij publicatie; dit wordt gebruikt om bij een volgende publicatie alleen de medewerkers te notificeren van wie de inplanning daadwerkelijk veranderd is.
API & Communicatie
Alle eindpunten vallen onder het prefix /api/rooster/ en vereisen authenticatie (HasPermissionCode).
| Methode | Pad | Permissie | Omschrijving |
|---|---|---|---|
| GET | /api/rooster/instellingen/ |
ingelogd | Haalt werkdagen, dagdelen, taken en minimale bezetting op. |
| PUT | /api/rooster/instellingen/ |
roster.manage_settings |
Volledige atomaire vervanging van de roosterstructuur. Items zonder id krijgen een nieuw UUID; ontbrekende items worden verwijderd. |
| GET | /api/rooster/medewerkers/ |
ingelogd | Lijst van actieve medewerkers. |
| GET | /api/rooster/week/?week_start=YYYY-MM-DD |
ingelogd | Weekrooster voor de opgegeven maandag. Geeft een leeg concept terug als er nog niets bestaat. |
| PUT | /api/rooster/week/?week_start=YYYY-MM-DD |
roster.edit |
Slaat het planning-grid atomair op als concept; vervangt alle bestaande toewijzingen. |
| POST | /api/rooster/week/publish/?week_start=YYYY-MM-DD |
roster.publish |
Publiceert het weekrooster en verstuurt pushnotificaties aan betrokken medewerkers. |
| GET | /api/rooster/vaste-werkdagen/ |
ingelogd | Alle vaste werkdagen voor alle medewerkers. |
| PUT | /api/rooster/vaste-werkdagen/ |
roster.manage_settings |
Volledige vervanging van alle vaste werkdagen; triggert automatisch het vullen van beschikbaarheid. |
| GET | /api/rooster/export/?scope=week\|month\|year&anchor_date=YYYY-MM-DD |
ingelogd | CSV-export van gepubliceerde en conceptroosters voor de opgegeven periode. Geeft Content-Disposition en X-Export-Filename headers mee. |
Notificatielogica bij publicatie
Bij publish_rooster worden de nieuwe en vorige grid-snapshots vergeleken per medewerker. Alleen medewerkers van wie de inplanning is gewijzigd (toegevoegd of verwijderd) ontvangen een notificatie. De notificatietekst verschilt per situatie: eerste publicatie, puur toevoegen, puur verwijderen of een combinatie.
Foutafhandeling & Statuscodes
400 Bad Request- Ontbrekende of incorrecte queryparameters (week_start,anchor_date), ongeldig grid-formaat of ongeldige export-scope.403 Forbidden- Onvoldoende permissie voor schrijfacties (bijv. aanpassen zonderroster.edit, publiceren zonderroster.publish).404 Not Found- Publiceren van een week waarvoor geenWeekRoosterbestaat.
Ongeldige UUID-referenties in het grid (medewerker, dagdeel, taak) worden zonder fout overgeslagen; alleen bekende, actieve records worden als WeekRoosterAssignment aangemaakt.
Autorisatie & Beveiliging
Alle views gebruiken HasPermissionCode als basisklasse. Aanvullende schrijfcontroles worden per methode uitgevoerd via has_permission(request.user, "...").
| Permissie | Beschrijving |
|---|---|
roster.edit |
Rooster plannen en concept-toewijzingen opslaan. |
roster.publish |
Concept publiceren naar medewerkers. |
roster.manage_settings |
Werkdagen, dagdelen, taken en vaste werkdagen beheren. |
Tenant-isolatie: alle modellen leven in het tenant-schema (django-tenants). Er is geen cross-tenant datadeling; query's bevatten geen expliciete tenant-filter omdat het schema dit afdwing.
Bestandsstructuur & Verantwoordelijkheden
backend/features/rooster/models.py- Datamodellen:RoosterWerkdag,RoosterDagdeel,RoosterTaak,RoosterMinBezetting,WeekRooster,WeekRoosterAssignment,VasteWerkdag.backend/features/rooster/services.py- Business-logica:get_instellingen,save_instellingen,get_week_rooster,save_concept,publish_rooster,export_rooster_csv,save_vaste_werkdagenen bezettingshulpfuncties.backend/features/rooster/views.py- Dunne APIView-klassen die parameters parsen, permissies controleren en naar services delegeren.backend/features/rooster/serializers.py- Serializers voor instellingen, weekroosters, medewerkers en vaste werkdagen.backend/features/rooster/tasks.py- Celery-taken voor periodieke opruiming van verouderde roosters.backend/features/rooster/urls.py- URL-routering voor alle roostereindpunten.
Belangrijke bestanden
backend/features/rooster/models.pybackend/features/rooster/services.pybackend/features/rooster/views.pybackend/features/rooster/tasks.pybackend/features/rooster/urls.py