# Feature Specification: Admin List Views **Feature Branch**: `012-admin-list-views` **Created**: 2026-09-07 **Status**: Draft **Input**: User description: "Add missing read-only list endpoints supporthub-web's admin monitoring and catalog screens need: SLA runs across tickets, recent escalation events across tickets, and products with their integration status, none of which exist as a single query today." ## User Scenarios & Testing *(mandatory)* ### User Story 1 - An agent or admin sees SLA status across every ticket at a glance (Priority: P1) Rather than checking one ticket's SLA state at a time, an agent or admin retrieves a list of every ticket's current SLA run, filterable by status (running/paused/warning/breached), each entry carrying enough to identify and link to its ticket. **Why this priority**: This is the entire reason this feature exists — supporthub-web's own 001-agent-admin-ui, User Story 6, has no data source for its SLA monitor view without it, and no endpoint in the SLA module answers "every ticket's SLA state," only one ticket's own. **Independent Test**: With SLA runs in different states across several tickets, call this endpoint unfiltered and confirm every run appears; call it filtered by `status=breached` and confirm only breached runs appear. **Acceptance Scenarios**: 1. **Given** tickets with SLA runs in running, paused, and breached states, **When** the endpoint is called with no filter, **Then** every run is returned, each including its ticket's id and code, status, and due/breached timestamps. 2. **Given** the same tickets, **When** the endpoint is called with `status=breached`, **Then** only the breached runs are returned. --- ### User Story 2 - An agent or admin sees recent escalation events across every ticket (Priority: P1) An agent or admin retrieves a list of recent escalation events across all tickets — each showing the triggering reason, the rule that fired it (if automatic) or the actor who triggered it (if manual), and the resulting target hierarchy node. **Why this priority**: The same 001-agent-admin-ui User Story 6 has no data source for its escalation matrix view without it — today the only way to see an escalation event at all is `EscalationEventRepository.findAllForTicket`, which requires already knowing which ticket to ask about. **Independent Test**: With escalation events (both automatic and manual) recorded across several tickets, call this endpoint and confirm every event appears, most recent first, each identifying its ticket, reason, rule-or-actor, and target node. **Acceptance Scenarios**: 1. **Given** three tickets each with one escalation event, **When** the endpoint is called, **Then** all three appear, ordered most-recent-first, each including its ticket id/code, reason, `ruleId` (or null for manual), `triggeredBy`, and `toNodeId`. --- ### User Story 3 - An admin views the product catalog with integration status (Priority: P2) An admin retrieves the product catalog with each product's integration status (active/suspended) visible directly in the list, rather than needing a second lookup per product. **Why this priority**: Lower than User Stories 1-2 (matches 001-agent-admin-ui's own User Story 7 being P3) — the product catalog changes far less often than SLA/escalation state, but its own consuming frontend story still has no single query to build a list screen against: the existing public `GET /products` doesn't include `ProductIntegration`, and integration status is only otherwise reachable per-integration-id, not per-product. **Independent Test**: With two products, one with an active integration and one with a suspended integration, call this endpoint and confirm each product's own integration status is present without a further request. **Acceptance Scenarios**: 1. **Given** a product with an active integration and one with a suspended integration, **When** an admin calls this endpoint, **Then** both appear with their correct integration status; a product with no integration at all shows a clearly-absent (not misleadingly "active") status. --- ### Edge Cases - What happens to a ticket whose SLA run was already marked `completed` (ticket resolved)? It still appears in the unfiltered SLA-run list (this is a monitoring view of everything that exists, not just "currently at risk") but is excluded by a `status=breached`/`running`/etc. filter unless it matches. - What happens for a ticket with no SLA run at all (no matching policy, or the run hasn't been created yet)? It simply doesn't appear in this list — this endpoint lists existing `SLARun` rows, it does not synthesize one for every ticket. ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: The system MUST provide an endpoint listing every `SLARun`, each including its owning ticket's id and code, optionally filtered by `status`. - **FR-002**: The system MUST provide an endpoint listing recent `EscalationEvent` rows across all tickets, most-recent-first, each including its owning ticket's id and code. - **FR-003**: The system MUST provide an endpoint listing the product catalog with each product's integration status included, distinguishing "has an active integration," "has a suspended integration," and "has no integration at all." - **FR-004**: All three endpoints are read-only (no new write capability) and reuse existing `SLARun`/`EscalationEvent`/`Product`/`ProductIntegration` data — no new persisted entity. ### Key Entities - **SLA Run List Item**: An `SLARun` projected with its ticket's `id`/`code` alongside its own existing fields. - **Escalation Event List Item**: An `EscalationEvent` projected with its ticket's `id`/`code` alongside its own existing fields. - **Product Catalog List Item**: A `Product` projected with its integration's `status`, or an explicit absence marker if it has none. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: Every ticket's SLA state is retrievable in a single request, filterable by status, with zero additional per-ticket requests needed. - **SC-002**: Recent escalation events across every ticket are retrievable in a single request. - **SC-003**: The product catalog with integration status is retrievable in a single request, with 0% of products showing a misleading status when they have no integration at all. ## Assumptions - **No pagination on the SLA-run or product-catalog lists** — matches 011-agent-ticket-queue's own precedent (bounded, realistic data volumes for this stage); the escalation-event list DOES cap at a default/maximum `limit` (most-recent-first), since that list only ever grows and has no other natural bound. - **These are read-only monitoring/catalog views, not a general search/filter API** — the SLA list's only filter is `status`; no additional filters (date range, product, priority) are added speculatively beyond what 001-agent-admin-ui's own User Story 6 spec asks for. - **Auth**: SLA-run and escalation-event lists are agent-usable (`fastify.authenticate` only, matching the existing single-ticket `GET /tickets/:id/sla-run`'s own agent-facing nature and 001-agent-admin-ui's "agents and admins" wording for User Story 6); the product-catalog list is admin-only (`requireRole('ADMIN')`), matching every other admin-configuration read in this codebase.