Skip to content

Maintenance system (architecture overview)

This page is the architecture entry point for the maintenance domain. Authoritative behavioral specs (transitions, permissions, snapshots, cache contracts) live under docs/lifecycle/ and must stay aligned with implementation.


Documentation map (single source of truth)

TopicLocation
Overview & definitions../../lifecycle/maintenance/README.md
Status & departmentApprovalStatus../../lifecycle/maintenance/status-transitions.md
RBAC, canArchive, canPurge, archive visibility../../lifecycle/maintenance/permissions-matrix.md
finalSnapshot, takenAt, list vs detail../../lifecycle/maintenance/snapshot-behavior.md
User / maintenance / system / session cache../../lifecycle/cache/
Lifecycle index../../lifecycle/README.md

Operational handoff: maintainer/phases/maintenance-handoff.md.


Storage

  • Primary persistence: PostgreSQL (Neon) table maintenance_requests (Drizzle ORM in apps/worker).
  • Attachments: R2 + metadata table; not duplicated in finalSnapshot by default in v1.
  • Audit / logs: Existing maintenance/security/audit pipelines; purge should emit structured log meta (see snapshot doc).

Core model (intent)

  • status is the primary workflow field: pending | in_progress | completed | cancelled | declined (underscore in_progress only — no hyphen).
  • departmentApprovalStatus supports department dashboards and “request summary”; invariants are tied to status in the lifecycle docs.
  • No completed boolean — use status + completedAt.
  • User references on the row: submittedBy, approvedBy, assignedBy, assignedTo (IDs only); departmentId (FK) with API department: { id, name }.
  • Terminal states: completed, cancelled, declined — no further status changes; only archive and purge (and reads) per matrix.
  • finalSnapshot: JSON column, v: 1, written once in the same transaction as terminal transition; immutable; includes department and relatedUsers (see snapshot doc).

API shape (intent)

  • relatedUsers: single enriched array; canViewProfile server-only; no email.
  • permissions: includes canArchive, canPurge; canDelete removed from the permission vocabulary for this domain.
  • List: no full snapshot; takenAt = finalSnapshot.takenAt when closed, else null.
  • Detail: full finalSnapshot for closed tasks.

Workers code (reference)

AreaPath
Routesapps/worker/src/routes/maintenance/
Servicesapps/worker/src/lib/services/maintenance/
Cacheapps/worker/src/lib/services/cache/

Implementation status

Legacy behavior in the codebase may still reflect older field names (approvedById, in-progress, completed boolean, nested employee/technician objects). Migration to this spec is intentional and should follow:

  1. Schema & migrations
  2. Types & OpenAPI
  3. Services & cache
  4. Routes
  5. Web UI

Do not implement ad hoc divergences without updating docs/lifecycle/ and an ADR if the change is architectural.