Maintenance status transitions (locked)
Canonical status values (use only these strings everywhere: DB, API, TypeScript):
pending | in_progress | completed | cancelled | declined
Never use a hyphenated in-progress form.
Closed definition
Closed = status ∈ { completed, cancelled, declined }
Closed tasks:
- Must have a
finalSnapshotwritten in the same transaction as the terminal transition (see snapshot-behavior.md). - UI uses snapshot for structure; row holds notes and timestamps (see README).
Approval does not change status
Department approval only updates departmentApprovalStatus. It does not by itself change status from pending.
Explicit sub-steps:
Approve (department head or authorized role — see permissions matrix)
- From:
status = pendinganddepartmentApprovalStatus = pending - To:
status = pendinganddepartmentApprovalStatus = approved - Action name: approve (e.g.
PUT …/approve).
- From:
Assign (administrator / super_admin only)
- From:
status = pendinganddepartmentApprovalStatus = approved(and other preconditions in matrix) - To:
status = in_progress - Sets
assignedTo,assignedBy,assignedAt. - Department head cannot assign (locked).
- From:
Progression rule: in_progress is reached by assignment, not by approval alone.
Decline
- Actors:
department_headoradministrator/super_admin(see permissions-matrix.md). - From:
status = pendingonly. - To:
status = declined. declinedNotes: Required at the decline action (API validation). Column remains nullable in DB until decline; then set and immutable for that transition.
After decline, departmentApprovalStatus must be declined (see invariants below).
Cancel
- From:
pendingorin_progress(who may cancel — see matrix). - To:
status = cancelled. cancellationNotes: Required at the cancel action. Column nullable until cancel.
Cancel while departmentApprovalStatus = pending
If the task is cancelled while departmentApprovalStatus is still pending:
departmentApprovalStatusremains unchanged (stayspending).- UI may simultaneously show
status = cancelledanddepartmentApprovalStatus = pending. This is expected for early cancellation before department review.
Complete
- From:
in_progress. - To:
status = completed. - Sets
completedAt(and any completion fields on the row per schema). Do not set cancel/decline fields.
Terminal states (no status transitions out)
These status values are terminal:
completedcancelleddeclined
No further status transitions are permitted after terminal.
Allowed post-terminal operations (only):
- Archive (subject to permissions-matrix.md)
- Purge (hard delete, subject to matrix — never for
completed)
Do not describe transitions as completed → terminal; instead say: terminal states are listed above and admit no further status changes.
departmentApprovalStatus invariants (locked)
status | departmentApprovalStatus |
|---|---|
pending | pending or approved or declined (per stage) |
in_progress | must be approved |
completed | must be approved |
declined | must be declined |
cancelled | retains last known value (e.g. may remain pending if cancelled before dept action) |
Summary transition graph (status)
pending (dept pending)
→ pending (dept approved) [approve — status unchanged]
pending (dept approved)
→ in_progress [assign — admin/super_admin]
pending
→ declined [decline — with declinedNotes]
pending | in_progress
→ cancelled [cancel — with cancellationNotes]
in_progress
→ completed [complete — sets completedAt]
Terminal: completed | cancelled | declined
→ (no further status change; archive / purge only as allowed)Related documentation
- permissions-matrix.md — who may approve, assign, decline, cancel, complete, archive, purge.
- snapshot-behavior.md —
finalSnapshoton terminal transitions.