Ga naar inhoud

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 zonder roster.edit, publiceren zonder roster.publish).
  • 404 Not Found - Publiceren van een week waarvoor geen WeekRooster bestaat.

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_werkdagen en 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.py
  • backend/features/rooster/services.py
  • backend/features/rooster/views.py
  • backend/features/rooster/tasks.py
  • backend/features/rooster/urls.py

API & Communicatie (Swagger)