Skip to content

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 finalSnapshot written 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:

  1. Approve (department head or authorized role — see permissions matrix)

    • From: status = pending and departmentApprovalStatus = pending
    • To: status = pending and departmentApprovalStatus = approved
    • Action name: approve (e.g. PUT …/approve).
  2. Assign (administrator / super_admin only)

    • From: status = pending and departmentApprovalStatus = approved (and other preconditions in matrix)
    • To: status = in_progress
    • Sets assignedTo, assignedBy, assignedAt.
    • Department head cannot assign (locked).

Progression rule: in_progress is reached by assignment, not by approval alone.


Decline

  • Actors: department_head or administrator / super_admin (see permissions-matrix.md).
  • From: status = pending only.
  • 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: pending or in_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:

  • departmentApprovalStatus remains unchanged (stays pending).
  • UI may simultaneously show status = cancelled and departmentApprovalStatus = 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:

  • completed
  • cancelled
  • declined

No further status transitions are permitted after terminal.

Allowed post-terminal operations (only):

Do not describe transitions as completed → terminal; instead say: terminal states are listed above and admit no further status changes.


departmentApprovalStatus invariants (locked)

statusdepartmentApprovalStatus
pendingpending or approved or declined (per stage)
in_progressmust be approved
completedmust be approved
declinedmust be declined
cancelledretains 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)