API — Demand
Purpose
Demand plans (the matrix of required coverage by date/terminal/shift) and demand templates (reusable shapes you apply to create a plan).
Auth & roles
- Demand plans — base
/api/demand/plans· readdemand.read, writedemand.write(SYS_ADMIN + HR_ADMIN + PLANNER). - Demand templates — base
/api/demand/templates· readdemand.template_read, applydemand.write.
See the RBAC matrix.
Endpoints
Demand plans — /api/demand/plans
| Method | Path | Purpose | Gate |
|---|---|---|---|
| GET | /api/demand/plans |
List plans (filterable by date/terminal/state) | demand.read |
| POST | /api/demand/plans |
Create a plan | demand.write |
| GET | /api/demand/plans/{id} |
Plan detail (the matrix) | demand.read |
| PATCH | /api/demand/plans/{id} |
Edit cells / status | demand.write |
| DELETE | /api/demand/plans/{id} |
Delete a plan | demand.write |
Demand templates — /api/demand/templates
| Method | Path | Purpose | Gate |
|---|---|---|---|
| GET | /api/demand/templates · /{id} |
List / read templates | demand.template_read |
| POST | /api/demand/templates/{id}/apply |
Apply a template (dry-run + commit) | demand.write |
Shapes & errors
A plan has a status state machine and a cell-edit surface; apply-template supports a dry-run then commit (sheet 08). Editing a locked plan returns 409. Standard ProblemDetails.
Gotchas
DemandPlanStatus.Lockedis a defined-but-unreachable enum value (F1). The enum declaresLocked, but no code path transitions a plan into it — publishing a roster does not lock its demand plan. TreatLockedas dead for plans; don't write logic assuming a plan can reach it.- The locked-edit 409 still exists in the API contract for plan cells, but the plan-level
Lockedstatus itself is unreachable — these are different things; the cell-level guard is real. - Demand reasons referenced by plans are managed via the admin CRUD (
/api/admin/demand-reasons) and read via lookups.
Related
- Demand (concept) · Create a demand plan (task)
- Swagger:
/swagger· Fact sheet 08 (demand planning).