Files
support_frontend/specs/001-agent-admin-ui/plan.md
T
saqib mirandClaude Sonnet 5 95b5a1e03d feat(001-agent-admin-ui): Setup + Foundational + User Story 0 (sign-in)
Configures both previously-empty test runners (vitest.config.ts,
playwright.config.ts) and adds the typed lib/api client layer (axios +
interceptors), the session-cookie plumbing (lib/auth), TanStack Query
infrastructure (lib/query, providers), and a real sign-in flow consuming
supporthub-api's own login (010-identity-auth) - the true foundation
every other user story in this feature depends on.

Two structural fixes to the existing scaffold, both found only by
running the app rather than by inspection: middleware.ts belongs at
src/middleware.ts under this project's src/ layout, not the repo root;
and next.config.mjs's output:'export' is incompatible with Next.js
Middleware outright (the dev server refuses to start it), so this app
now runs as a standard Next.js server - confirmed with the user before
making that deployment-mode change.

Verified end-to-end with a real, locally-running supporthub-api: all 5
Playwright scenarios (unauthenticated redirect, sign-in, wrong-password
generic error, non-admin role gating, sign-out) pass against a live
backend, not a mock.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 14:27:06 +05:30

167 lines
11 KiB
Markdown

# Implementation Plan: Agent and Admin UI
**Branch**: `001-agent-admin-ui` | **Date**: 2026-09-07 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `specs/001-agent-admin-ui/spec.md`
## Summary
Builds the `(support)`/`(admin)` portals against the existing Next.js scaffold: a sign-in flow
consuming supporthub-api's own login (010-identity-auth, User Story 0 — this feature's true
foundation), an agent dashboard and ticket workbench (011-agent-ticket-queue plus the existing
ticketing/problem-resolution endpoints), and admin configuration screens for support
organization, SLA/calendars, escalation, and (P3) catalog/knowledge governance. Every screen
reads and writes through one typed API client layer (`lib/api`) via TanStack Query — no business
logic is computed client-side (Constitution Principle II).
## Technical Context
**Language/Version**: TypeScript 5.5, Node.js 22 (per `package.json` `engines`), Next.js 14
(App Router), React 18. `next.config.mjs`'s `output: 'export'` (static HTML export) is removed
by this feature — Next.js Middleware, which FR-000's sign-in guard requires, cannot run under
static export (confirmed by the dev server itself refusing to start it); this app now runs as a
standard Next.js server (`next build && next start`), a deployment-mode change, not just a code
change.
**Primary Dependencies**: `@tanstack/react-query` (server state), `axios` (wrapped by `lib/api`),
`tailwindcss` (styling, already configured), `clsx`/`tailwind-merge` (already present),
`lucide-react` (icons, already present). New: `js-cookie` (small, typed cookie read/write for
the session token — the codebase has no cookie helper today) and `jose` (Edge-runtime-safe JWT
payload decode for `middleware.ts``jsonwebtoken` depends on Node APIs `middleware.ts` cannot
use).
**Storage**: N/A (server state is supporthub-api's; the only client-side state is the session
cookie itself, `research.md`).
**Testing**: Vitest (unit — hooks, `lib/api` functions, the query-state helper; integration —
per-portal critical flows against a mocked API layer) + Playwright (E2E — the two journeys
Constitution Principle VII names, plus this feature's own: an agent signing in and resolving a
ticket end-to-end, User Stories 0-2). `vitest.config.ts` and `playwright.config.ts` are both
currently empty stubs — this feature is the first to configure either.
**Target Platform**: Browser (desktop-first, responsive down to a reasonable minimum per
Principle VI), served by the existing Next.js app.
**Project Type**: Web frontend — single Next.js project, consuming a separately-deployed
supporthub-api.
**Performance Goals**: SC-001 — dashboard-open to message-post in under 15 seconds of active use
(excluding backend response time), meaning the UI itself must not introduce avoidable extra
round trips or re-renders on that path.
**Constraints**: FR-012/Principle II — no business decision (transition validity, SLA due
dates, most-specific-policy resolution, escalation matching) is computed client-side, only
rendered from what the API returns. FR-000/Principle I — this frontend never verifies a JWT
signature itself (research.md); the unverified middleware decode is UX-only.
**Scale/Scope**: Eight user stories (US0 sign-in + US1-US7), against ~30 existing placeholder
`page.tsx` files across four route groups, all of `lib/api`/`lib/auth`/`lib/query`/`hooks`/
`stores`/`providers`/`features/*` currently empty. Given the size, this plan's own Project
Structure section scopes Phase 1 (Setup) and User Stories 0-3 (the P1 MVP: sign-in, dashboard,
ticket workbench, support-org admin) as the immediate implementation target; User Stories 4-7
(P2/P3) follow the identical pattern once the MVP is verified, per the Implementation Strategy
below — matching this project's own established phase-by-phase, checkpoint-then-continue
discipline (mirrors supporthub-api's own MVP-first pattern, e.g. 010's own tasks.md).
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Principle | Check | Result |
|---|---|---|
| I. Each Identity Has Exactly One Authority | US0 consumes supporthub-api's own login (010) for agent/admin identity, never re-implementing or re-deriving it; the `(public)`/`(customer)` portals (SaaS-delegated identity) are explicitly out of scope for this feature (Assumptions), so no conflict between the two identities' authorities arises here. | PASS |
| II. The Backend Is the Sole Source of Business Logic | FR-012 is this principle restated as a testable requirement; every user story's Acceptance Scenarios that touch a business-rule rejection (US2 scenario 2, US3 scenario 3, US5 scenario 3) exist specifically to keep it enforced. | PASS |
| III. Strict Portal Boundaries | This feature only touches `(support)`/`(admin)``(public)`/`(customer)` are untouched (Assumptions). Shared primitives stay in `components/ui`; portal-specific composition lives in `features/*` and each route group. | PASS |
| IV. Typed API Boundary, No Ad Hoc Fetching | `lib/api` is the single client layer (research.md); every `features/*` module consumes it only through TanStack Query hooks. | PASS |
| V. Configuration Over Hardcoding | Support hierarchy, SLA policies, escalation rules, and skills are rendered/edited generically from what the API returns — no frontend-duplicated enum for root-cause types, verification methods, escalation trigger types, etc. | PASS |
| VI. Accessible, Responsive, Enterprise-Grade UI | Existing `components/ui` primitives (already built, this session's earlier scaffold work) are the basis for every new screen; density/keyboard-usability is a per-task acceptance bar, not a separate follow-up. | PASS |
| VII. Testing Gates | This plan's Testing section above configures both currently-empty test runners as part of Setup, not deferred — Vitest unit/integration plus the two Playwright E2E journeys (one of which, agent resolving an escalated ticket, is this feature's own US0-US2). | PASS |
No violations requiring Complexity Tracking justification.
## Post-Design Constitution Re-check
All gates above remain PASS after Phase 1 design (data-model.md, contracts, quickstart.md). One
principle is worth restating post-design: Principle I's redefinition (this session's own
constitution amendment, 1.0.0 → 1.1.0) is what makes User Story 0 exist at all — without it, this
plan would have wrongly assumed no sign-in screen was needed.
## Project Structure
### Documentation (this feature)
```text
specs/001-agent-admin-ui/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
```
### Source Code (repository root)
```text
supporthub-web/
├── src/middleware.ts # MODIFIED (was an empty file at repo root — moved
│ under src/, required by this project's src/
│ directory layout) — session presence + role
│ redirect for (support)/(admin), FR-000/research.md
├── vitest.config.ts # MODIFIED (was empty) — first real test config
├── playwright.config.ts # MODIFIED (was empty) — first real E2E config
├── src/
│ ├── lib/
│ │ ├── env/index.ts # MODIFIED (was empty) — typed env accessor
│ │ ├── auth/ # MODIFIED (was empty) — session cookie read/write/
│ │ │ │ clear, decode-for-display helpers
│ │ │ └── (session.ts, use-session.ts)
│ │ ├── api/ # MODIFIED (was empty) — axios instance + interceptors
│ │ │ │ (client.ts) + one file per domain (auth.ts,
│ │ │ │ agents.ts, tickets.ts, teams.ts, hierarchy.ts,
│ │ │ │ sla.ts, escalation.ts, problems.ts, ...)
│ │ │ └── types/ # response/request shapes, kept in sync with
│ │ │ supporthub-api's own contracts/*.md
│ │ └── query/ # MODIFIED (was empty) — QueryClient config,
│ │ │ query-state.ts (research.md's discriminated union)
│ │ └── keys.ts # centralized TanStack Query key factory
│ ├── providers/ # MODIFIED — QueryClientProvider, SessionProvider
│ ├── hooks/ # MODIFIED — use-session, use-query-state re-exports
│ ├── features/
│ │ ├── auth/ # NEW — sign-in form + its own mutation hook (US0)
│ │ ├── tickets/ # MODIFIED (was empty) — dashboard list, workbench
│ │ │ detail, message thread, status/escalate actions
│ │ ├── problems/ # MODIFIED — investigation/root-cause/solution/
│ │ │ verification/resolution recording (US2)
│ │ ├── teams/ # MODIFIED — team/agent/skill admin (US3)
│ │ ├── orchestration/ # MODIFIED — hierarchy-node admin (US3)
│ │ ├── settings/ # MODIFIED — SLA/calendar admin (US4, deferred)
│ │ └── ... # escalation/reports/knowledge/products: US5-US7,
│ │ deferred past this plan's immediate MVP scope
│ └── app/
│ ├── (support)/
│ │ ├── layout.tsx # MODIFIED — session-aware shell (nav, sign-out)
│ │ └── support/
│ │ ├── dashboard/page.tsx # MODIFIED (was a placeholder) — US1
│ │ └── agent-tickets/[ticketId]/page.tsx # MODIFIED — US2
│ └── (admin)/
│ ├── layout.tsx # MODIFIED — admin-only shell
│ └── admin/
│ ├── teams/page.tsx # MODIFIED — US3
│ └── hierarchy/page.tsx # MODIFIED — US3
└── tests/
├── unit/ # lib/api functions, query-state, session helpers
├── integration/ # per-portal critical flows (mocked API layer)
└── e2e/ # Playwright — Principle VII's two journeys
```
**Structure Decision**: Single Next.js project, built entirely against the existing scaffold
(no new route groups or top-level directories) per the constitution's own Development Workflow
rule — replacing placeholder pages, not restructuring the route tree. This plan's own immediate
implementation scope is Setup + User Stories 0-3 (P1 MVP); `features/` subdirectories for
US4-US7 are named above for completeness but not built until those stories' own turn.
## Complexity Tracking
*No constitution violations — table intentionally omitted.*