Maintenance lifecycle (overview)
This document summarizes the locked maintenance request system. Detailed rules live in sibling files.
Definitions
Closed (terminal workflow state)
A request is closed when:
status ∈ { completed, cancelled, declined }
archivedAtdoes not change whether a task is closed. Archive affects list visibility and permissions (canArchive), not the closed definition.- For closed tasks, the UI must use
finalSnapshotfor structural display (title, priority, category, location, department,relatedUsersas stored at terminal time). - Notes and timestamps on the main row (
cancellationNotes,declinedNotes, completion-related fields,completedAt,cancelledAt,declinedAt, etc.) are read from the row alongside the snapshot.
Primary status (status)
Canonical values (underscore only; no hyphenated in-progress):
| Value | Meaning |
|---|---|
pending | Created; not yet in active work |
in_progress | Work underway (after department approval and assignment) |
completed | Work finished successfully |
cancelled | Cancelled (with cancellationNotes at transition) |
declined | Declined by department or admin (with declinedNotes at transition) |
Department approval (departmentApprovalStatus)
Tracks department-level approval, used for department dashboards and “request summary” views (e.g. /departments/:id). It is not a replacement for status; status remains the primary workflow field.
See status-transitions.md for invariants tying status and departmentApprovalStatus together.
Database identity fields (IDs only)
User references on the row are scalar IDs only:
submittedByapprovedBy(department head user id when approved)assignedBy(administrator or super_admin who performed assignment)assignedTo(technician)
Also: departmentId (FK, indexed). API exposes:
"department": { "id": "...", "name": "..." }Completion model
- No
completedboolean. UsestatusandcompletedAt. completedAtis set only whenstatusbecomescompleted.- Cancelled tasks set
cancelledAtandcancellationNotes(at cancel transition); do not setcompletedAtor any “completed” semantics. - Declined tasks set
declinedAtanddeclinedNotes(at decline transition).
Terminal states (no further status changes)
These status values are terminal:
completedcancelleddeclined
After a row reaches a terminal status, no further status transitions are allowed. Only archive and purge (and reads) apply afterward, per permissions-matrix.md.
Archive (soft hide)
- Columns:
archivedAt,archivedBy. - Unarchive: not supported in v1.
- Visibility: Archived rows are hidden from default lists but visible when
includeArchived(or equivalent) is used. Access rules: see permissions-matrix.md.
Purge (hard delete)
- Allowed roles:
administratorandsuper_adminonly (registry must not grant purge to other roles). - Allowed statuses:
cancelledordeclinedonly — notcompleted. - Archived: Purge is allowed when status is
cancelledordeclined, even ifarchivedAtis set.
API shapes (intent)
relatedUsers
Single array replacing nested employee, technician, assigner objects. Built on the server, enriched from user cache; canViewProfile is computed server-side only.
See snapshot-behavior.md and ../cache/user.md.
permissions
Existing pattern retained; includes at least:
canArchive— terminal states only; see matrix.canPurge— admin only; cancelled or declined; allowed when archived.
canDelete is not used (removed to avoid ambiguity with cancel vs purge).
List vs detail
| Endpoint | finalSnapshot | takenAt |
|---|---|---|
| List | Do not include full snapshot | See snapshot-behavior.md |
| Detail | Full finalSnapshot for closed tasks | N/A (detail carries snapshot) |
Document map
| Topic | File |
|---|---|
| Transitions and invariants | status-transitions.md |
RBAC and permissions flags | permissions-matrix.md |
finalSnapshot JSON, immutability | snapshot-behavior.md |