4.9 KiB
Implementation Plan: Admin List Views
Branch: 012-admin-list-views | Date: 2026-09-07 | Spec: spec.md
Input: Feature specification from specs/012-admin-list-views/spec.md
Summary
Adds three read-only endpoints, each a straightforward findMany on an already-existing model
plus a small ticket-id/code projection: GET /admin/sla-runs (optional ?status=),
GET /admin/escalation-events (optional ?limit=), and GET /admin/products (products joined
to their integration's status). No new persisted entity, no write capability.
Technical Context
Language/Version: TypeScript 5.4 / Node.js 20+ (unchanged).
Primary Dependencies: None new — Prisma only.
Storage: PostgreSQL via Prisma. No schema change — every field already exists; these are
projections over SLARun, EscalationEvent, and Product/ProductIntegration.
Testing: Vitest — integration tests against real Postgres/Redis for each endpoint's filter/
ordering/projection behavior, plus one admin-role-gating check for GET /admin/products.
Target Platform: Same Fastify modular monolith. Modifies orchestration/sla (new route +
repository method), orchestration/escalation (new route + repository method), and
catalog/products (new admin route + repository method) — no new module, each list lives in
the module that already owns its underlying model.
Project Type: Backend service — single project.
Performance Goals: Each list is one indexed/simple query — SLARun has no per-status
index today (status is a small string column, not indexed), acceptable at this stage per
spec.md's own "no general search API" scoping; revisit if a future feature's data volume
demands one.
Constraints: FR-004 — read-only, no new write path. The product-catalog list must not leak
ProductIntegration.credentialRef (encrypted secret) or any other sensitive integration field
— only status is projected.
Scale/Scope: Three new GET routes across three existing modules, three new repository
methods, no new module, no schema migration. Explicitly excludes: pagination (spec.md
Assumptions — limit only on the escalation-event list), and any filter beyond status/limit.
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
| Principle / Section | Check | Result |
|---|---|---|
| I. SaaS Is the Sole Identity & Access Authority | Purely internal SupportHub domain (SLA/escalation/product-catalog monitoring) — no SaaS/customer identity involved. | PASS — N/A |
| II. Configuration Over Hardcoding | No new configurable values. | PASS — N/A |
| III. Layered Architecture With Enforced Module Boundaries | Each list lives in the module that already owns its model (orchestration/sla, orchestration/escalation, catalog/products) — no cross-module reach-through; the ticket id/code projection reads ticketsRepository's own public surface via ticketing/tickets's existing index.ts. |
PASS |
| IV. AI Recommends, Deterministic Policy Decides | Not applicable. | PASS — N/A |
| V. Evidence-Based Verification | Not applicable. | PASS — N/A |
| VI. Durable Audit & History | Not applicable — no new mutable state. | PASS — N/A |
| VII. Concurrency-Safe, Durable Job Handling | Read-only queries; no concurrency concern. | PASS |
| VIII. Problem and Ticket Are Separate, Related Entities | Not applicable. | PASS — N/A |
| Technology & Platform Constraints | No new dependencies or infrastructure. | PASS |
No violations requiring Complexity Tracking justification.
Project Structure
Documentation (this feature)
specs/012-admin-list-views/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
Source Code (repository root)
supporthub-api/
└── src/
└── modules/
├── orchestration/
│ ├── sla/ # MODIFIED — GET /admin/sla-runs
│ │ ├── controller/ routes/
│ │ └── repository/ (new findAll(status?) method)
│ └── escalation/ # MODIFIED — GET /admin/escalation-events
│ ├── controller/ routes/
│ └── repository/ (new findRecent(limit?) method)
└── catalog/
└── products/ # MODIFIED — GET /admin/products
├── controller/ routes/
└── repository/ (new findAllWithIntegrationStatus() method)
└── tests/
└── integration/ # one new test file per endpoint's own scenarios
Structure Decision: Single project, no new module — each endpoint extends the module that already owns its underlying data, matching 011-agent-ticket-queue's own precedent.
Complexity Tracking
No constitution violations — table intentionally omitted.