--- description: "Task list for 012-admin-list-views" --- # Tasks: Admin List Views **Input**: Design documents from `specs/012-admin-list-views/` **Prerequisites**: [plan.md](./plan.md), [spec.md](./spec.md), [research.md](./research.md), [data-model.md](./data-model.md), [contracts/admin-list-views-contract.md](./contracts/admin-list-views-contract.md), [quickstart.md](./quickstart.md) **Organization**: Tasks are grouped by user story (US1 = P1 SLA runs, US2 = P1 escalation events, US3 = P2 product catalog). All three are independent of each other. ## Format: `[ID] [P?] [Story] Description` All file paths are relative to `supporthub-api/` (repo root). --- ## Phase 1: User Story 1 - SLA runs across every ticket (Priority: P1) **Independent Test**: Quickstart Scenario 1. - [x] T001 [P] [US1] Add `SLARunRepository.findAll(status?)` in `src/modules/orchestration/sla/repository/sla-run.repository.ts` — `include: { ticket: { select: { id: true, code: true } } }`, optional `where: { status }` - [x] T002 [US1] Add `SLAService.listAll(status?)` (or directly on the controller if no service method is warranted — check existing pattern) validating `status` against `SLA_RUN_STATUSES` (400 on an invalid value) in `src/modules/orchestration/sla/service/sla.service.ts` (depends on T001) - [x] T003 [US1] Add `GET /admin/sla-runs` (`fastify.authenticate` only) in `src/modules/orchestration/sla/controller/` + `routes/`, projecting each row to `SlaRunListItem` (data-model.md) (depends on T002) - [x] T004 [US1] Integration test covering Quickstart Scenario 1 (unfiltered returns all; `status=breached` filters correctly; an invalid status is 400) in `tests/integration/admin-list-views.test.ts` - [x] T005 [US1] Run Quickstart Scenario 1 locally and confirm all 3 steps pass --- ## Phase 2: User Story 2 - Recent escalation events across every ticket (Priority: P1) **Independent Test**: Quickstart Scenario 2. - [x] T006 [P] [US2] Add `EscalationEventRepository.findRecent(limit)` in `src/modules/orchestration/escalation/repository/escalation-event.repository.ts` — `include: { ticket: { select: { id: true, code: true } } }`, `orderBy: { createdAt: 'desc' }`, `take: limit` - [x] T007 [US2] Add `GET /admin/escalation-events` (`fastify.authenticate` only, `limit` query param `z.coerce.number().int().positive().max(200).default(50)`) in `src/modules/orchestration/escalation/controller/` + `routes/`, projecting to `EscalationEventListItem` (depends on T006) - [x] T008 [US2] Integration test covering Quickstart Scenario 2 (both events appear, most- recent-first, automatic vs manual distinguished by `ruleId`) in `tests/integration/admin-list-views.test.ts` (same file as T004) - [x] T009 [US2] Run Quickstart Scenario 2 locally and confirm it passes --- ## Phase 3: User Story 3 - Product catalog with integration status (Priority: P2) **Independent Test**: Quickstart Scenario 3. - [x] T010 [P] [US3] Add `ProductsRepository.findAllWithIntegrationStatus()` in `src/modules/catalog/products/repository/products.repository.ts` — `include: { integration: { select: { status: true } } }`, `orderBy: { name: 'asc' }` - [x] T011 [US3] Add `GET /admin/products` (`fastify.authenticate` + `requireRole('ADMIN')`) in `src/modules/catalog/products/controller/` + `routes/`, projecting each row to `ProductCatalogListItem` (`integrationStatus: product.integration?.status ?? null` — never the full `ProductIntegration` row, research.md) (depends on T010) - [x] T012 [US3] Integration test covering Quickstart Scenario 3 (active + no-integration products both correct; non-admin gets 403) in `tests/integration/admin-list-views.test.ts` (same file as T004/T008) - [x] T013 [US3] Run Quickstart Scenario 3 locally and confirm both steps pass --- ## Phase 4: Polish & Cross-Cutting Concerns - [x] T014 [P] Update `specs/012-admin-list-views/checklists/requirements.md` Notes with any implementation-time findings - [x] T015 Run `npx tsx scripts/check-architecture.ts` and `npm run lint`/`npm run typecheck` - [x] T016 Full regression: `npm run test:unit` then the full integration suite against real Docker-provisioned Postgres/Redis, confirming nothing outside this feature regressed --- ## Dependencies & Execution Order - **User Stories 1-3**: Fully independent of each other and of any Foundational phase (no shared prerequisite beyond the existing schema) — parallelizable in any order - **Polish (Phase 4)**: Depends on all three user stories