Skip to content

Maintenance permissions matrix (locked)

This document defines who may perform which actions and how permissions flags behave. Frontend must not infer policy; it renders from permissions, relatedUsers[].canViewProfile, and route guards.

Role names match the backend enum: e.g. administrator, super_admin, department_head, employee, technician.


Actions by role (summary)

Actionemployeetechniciandepartment_headadministratorsuper_admin
Create request✓ (own)
Approve (dept)✓ (same dept)✓*✓*
Assign
Decline✓ (same dept)
Cancel✓†✓‡
Complete✓ (if assigned)
Archive✓§✓¶
Purge (hard delete)

* Scope rules must match product (e.g. admin may approve any dept — confirm in implementation).
† Employee cancel: typically own request, before or after dept rules per product; must match status-transitions.md.
‡ Department head: same department as request.
§ Submitter: own request only.
¶ Department head: same department only.

Assign: assignedBy is always the administrator / super_admin who performed the assignment (audit).


permissions object (intent)

The API returns a permissions object on detail (and as needed on list). At minimum:

FlagMeaning
canArchiveUser may archive this row (see archive rules below).
canPurgeUser may hard-delete this row (see purge rules below).

Other flags (e.g. canUpdate, canCancel, canApprove) remain as today’s product requires; do not add canDelete (ambiguous).

When archived

FlagRule
canArchivefalse (already archived; unarchive not supported).
canPurgeStill true for administrator / super_admin if status is cancelled or declined (purge allowed even when archived).

Archive rules

Archive sets archivedAt / archivedBy (soft hide from default lists).

Eligible status (terminal only)

Archive is allowed only when:

status ∈ { completed, cancelled, declined }

Not allowed for pending or in_progress.

Who may archive

RoleScope
Submitter (employee on own request)Own request
department_headSame department as request
administrator, super_adminPer product (typically any)

Technician cannot archive (locked).

Visibility (archived rows)

Archive does not revoke read access for users who could already see the request. Archived tasks:

  • Are hidden from default lists
  • Appear when includeArchived (or equivalent) is true

Accessible by (read): submitter, department head (same department), assigned technician, administrator, super_admin — per locked product spec.


Purge rules (hard delete)

Registry: Only administrator and super_admin may hold purge permission; remove purge from employee, department_head, etc. (breaking change vs legacy if applicable).

Eligible status

  • cancelled or declined only.
  • completedmust not be purgeable (canPurge false even for admin).

Archived

  • Purge is allowed for cancelled / declined even if archivedAt is set.

Completed + archive

  • Completed tasks: canArchive may be true; canPurge is false (retention / audit; compliance tooling out of scope for v1).

relatedUsers[].canViewProfile

  • Computed only on the server from viewer role + target user role + policy.
  • Frontend: show link to /users/:id only when canViewProfile === true.
  • No email in relatedUsers (locked).

Decline (API validation)

  • declinedNotes: required on the decline request (body).
  • DB column nullable until decline.

Cancel (API validation)

  • cancellationNotes: required on the cancel request (body).
  • DB column nullable until cancel.

Same user, multiple roles in relatedUsers

  • A user may appear more than once with different type values.
  • Frontend must not deduplicate by user id when rendering role lines.