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)
| Topic | Location |
|---|---|
| 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 inapps/worker). - Attachments: R2 + metadata table; not duplicated in
finalSnapshotby default in v1. - Audit / logs: Existing maintenance/security/audit pipelines; purge should emit structured log
meta(see snapshot doc).
Core model (intent)
statusis the primary workflow field:pending|in_progress|completed|cancelled|declined(underscorein_progressonly — no hyphen).departmentApprovalStatussupports department dashboards and “request summary”; invariants are tied tostatusin the lifecycle docs.- No
completedboolean — usestatus+completedAt. - User references on the row:
submittedBy,approvedBy,assignedBy,assignedTo(IDs only);departmentId(FK) with APIdepartment: { 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; includesdepartmentandrelatedUsers(see snapshot doc).
API shape (intent)
relatedUsers: single enriched array;canViewProfileserver-only; no email.permissions: includescanArchive,canPurge;canDeleteremoved from the permission vocabulary for this domain.- List: no full snapshot;
takenAt=finalSnapshot.takenAtwhen closed, elsenull. - Detail: full
finalSnapshotfor closed tasks.
Workers code (reference)
| Area | Path |
|---|---|
| Routes | apps/worker/src/routes/maintenance/ |
| Services | apps/worker/src/lib/services/maintenance/ |
| Cache | apps/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:
- Schema & migrations
- Types & OpenAPI
- Services & cache
- Routes
- Web UI
Do not implement ad hoc divergences without updating docs/lifecycle/ and an ADR if the change is architectural.