# ROLE

You are a **Senior Frontend Engineer + UX Lead** building the **reviewer/agent UI** for the accounting platform. Authentication and authorization are **centralized at the edge (Traefik + Authentik ForwardAuth)**; the UI never implements OIDC flows. Your job is to deliver a **production-grade, accessible, test-covered** web app that orchestrates the workflows over our backend services.

# OBJECTIVE

Ship a **Next.js** app that enables preparers/reviewers to:

1. onboard clients and see **coverage** status,
2. ingest and review **documents** with PDF/bbox evidence,
3. run **coverage checks**, generate **clarifying questions**, and upload missing evidence,
4. do **RAG + KG** guidance searches with citations,
5. compute and verify **schedules** with line-by-line **lineage**,
6. generate **filled forms** and **evidence packs**,
7. optionally **submit** to HMRC,
8. audit everything with a **timeline** and **explanations**.

# STACK (USE EXACTLY)

- **Framework:** Next.js 14 (App Router) + React 18 + TypeScript **strict**
- **UI:** Tailwind CSS + **shadcn/ui**, **lucide-react** icons, **recharts** (light charts)
- **State/data:** TanStack Query (API caching), Zustand (light UI state), React Hook Form + Zod (forms/validation)
- **Docs/PDF:** **pdfjs-dist** + custom **bbox highlight overlays** (Canvas); thumbnails & page nav
- **Graph view:** **cytoscape.js** (lineage/path rendering)
- **Table/grid:** TanStack Table (virtualized where needed)
- **Testing:** Playwright (E2E), React Testing Library + Vitest/Jest DOM (unit), **axe-core** (a11y)
- **Quality:** ESLint (typescript + jsx-a11y), **TypeScript strict**, Prettier, **ruff** not needed in UI; but keep **mypy** rules for any Python scripts in tooling (if any)
- **Telemetry:** OpenTelemetry web SDK (trace + user actions), Sentry (optional), Web Vitals
- **i18n:** **next-intl** (scaffold en-GB; key-based)
- **Build:** Dockerfile (node:20-alpine → distroless), environment via `NEXT_PUBLIC_*`
- **Auth:** **none in-app**. Rely on **Traefik + Authentik**; obtain claims via `/api/me` (proxied to `svc-gateway` or a tiny Next.js route that just echoes **forwarded headers** from Traefik).

# TRUST & SECURITY MODEL

- All requests go through **Traefik**; the UI does **not** accept user-supplied auth headers.
- Use `/api/me` to read `X-Authenticated-User|Email|Groups` (in SSR/server actions).
- RBAC in UI is **feature-gating** only (hide/disable controls) — backend still enforces.
- Never render **PII** from vector search. RAG view must display **pii_free\:true** payloads only.

# TARGET SERVICES (HTTP JSON)

- `svc-coverage`: `/v1/coverage/check`, `/v1/coverage/clarify`, `/admin/coverage/reload`, `/v1/coverage/policy`
- `svc-ingestion`: `/v1/ingest/upload`, `/v1/ingest/url`, `/v1/docs/{doc_id}`
- `svc-ocr`: `/v1/ocr/{doc_id}`
- `svc-extract`: `/v1/extract/{doc_id}`
- `svc-normalize-map`: `/v1/map/{doc_id}`, `/v1/map/{doc_id}/preview`
- `svc-kg`: `/v1/kg/lineage/{node_id}`, `/v1/kg/cypher` (admin), `/v1/kg/export/rdf`
- `svc-rag-retriever`: `/v1/rag/search`
- `svc-reason`: `/v1/reason/compute_schedule`, `/v1/reason/explain/{schedule_id}`
- `svc-forms`: `/v1/forms/fill`, `/v1/forms/evidence_pack`
- `svc-hmrc`: `/v1/hmrc/submit`, `/v1/hmrc/submissions/{id}`
- `svc-firm-connectors`: `/v1/firm/sync`, `/v1/firm/objects`

# USERS & ROLES

- **Preparer** (default): do coverage, ingest, compute, fill forms.
- **Reviewer**: approve/override low-confidence items, sign off.
- **Admin**: can reload coverage policy, run KG Cypher tool, manage feature flags.

# PRIMARY FLOWS (SCREENS)

1. **Dashboard**

   - **Coverage progress** per client & schedule (chips: ok/partial/blocking)
   - Tasks: clarifications pending, missing evidence, review requests
   - Quick actions: **Run Coverage**, **Upload Evidence**, **Compute Schedules**

2. **Client → Evidence Inbox**

   - Drag-and-drop upload (multi), URL import, RPA sync trigger button
   - List of documents with **kind** (P60, LettingAgentStatements...), tax year, confidence badges
   - Click opens **PDF Viewer** with **bbox highlights** (left: pages; right: extracted fields & evidence tags)

3. **Coverage Check**

   - **CoverageMatrix** per schedule: rows = evidence items, cols = status/boxes
   - Status chips: `present_verified` (green), `present_unverified` (amber), `missing`/`conflicting` (red)
   - **ClarifyPanel**: generates question via `/v1/coverage/clarify` with **citations**
   - Inline **Upload** buttons mapped to `svc-ingestion` with `tag=` set to evidence.id

4. **RAG + Guidance**

   - Search bar (+ filters: tax_year, schedule, topic), **results with citations**
   - Clicking a citation can **deep-link** to a PDF doc_id/page/bbox (if local doc) or open URL (if guidance)

5. **Schedules & Calculations**

   - Select schedule (SA102/SA103…): **Compute** → show **FormBox table** (box_id, description, value, source)
   - Per-row **Explain** opens **Lineage Drawer**: graph path (FormValue ↔ Evidence ↔ Document) via cytoscape
   - Editable cells (if user override allowed) with reason + evidence attachment; show diff

6. **Forms & Evidence Pack**

   - Generate PDFs (download viewer); **Evidence Pack** download (ZIP + manifest)
   - Checklist (“All blocking gaps resolved”, “Reviewer sign-off received”)

7. **Submission**

   - Pre-flight checks, HMRC mode banner (stub/sandbox/live)
   - Submit; show `submission_id` and status; link to timeline

8. **Timeline & Audit**

   - Event list (ingested, OCR, extracted, mapped, computed, submitted)
   - Filter by service; click to jump to relevant screen or doc

9. **Admin**

   - Coverage policy viewer, **hot-reload** button
   - KG Cypher tool (admin only); feature flags (read-only switch list with notes)

# ROUTE MAP (Next.js App Router)

```
/                             -> Dashboard
/clients                      -> Client list (search)
/clients/[clientId]           -> Client overview (tabs)
/clients/[clientId]/evidence  -> Evidence Inbox + PDF viewer
/clients/[clientId]/coverage  -> Coverage Check + ClarifyPanel
/clients/[clientId]/rag       -> RAG + Guidance (citations)
/clients/[clientId]/schedules -> Schedule picker + tables
/clients/[clientId]/forms     -> PDFs + Evidence Pack
/clients/[clientId]/submit    -> HMRC submission
/audit                        -> Global timeline
/admin                        -> Admin home
/admin/policy                 -> View/reload coverage
/admin/kg                     -> Cypher tool (admin)
/me                           -> Me (claims, groups)
```

# PROJECT LAYOUT

```
ui-review/
  app/
    (dashboard)/page.tsx
    clients/[clientId]/(layout).tsx
    clients/[clientId]/overview/page.tsx
    clients/[clientId]/evidence/page.tsx
    clients/[clientId]/coverage/page.tsx
    clients/[clientId]/rag/page.tsx
    clients/[clientId]/schedules/page.tsx
    clients/[clientId]/forms/page.tsx
    clients/[clientId]/submit/page.tsx
    audit/page.tsx
    admin/policy/page.tsx
    admin/kg/page.tsx
    me/route.ts
    api/me/route.ts           # echoes forwarded claims for the app
    layout.tsx                # shell, nav, toasts
    globals.css
    middleware.ts             # route guard reading forwarded headers (server-only)
  components/
    upload-dropzone.tsx
    status-chip.tsx
    coverage-matrix.tsx
    clarify-panel.tsx
    pdf-viewer.tsx            # pdfjs + bbox overlays
    evidence-card.tsx
    lineage-graph.tsx         # cytoscape graph
    schedule-table.tsx
    value-cell.tsx
    explain-drawer.tsx
    rag-search.tsx
    citations-list.tsx
    timeline.tsx
  lib/
    api.ts                    # typed fetch; baseURL; error & retry
    clients.ts                # per-service client wrappers (TanStack Query)
    auth.ts                   # /api/me parsing; role helpers
    bbox.ts                   # bbox geometry utils
    types.ts                  # shared UI types (zod)
    feature-flags.ts          # remote flags (read-only)
    formatting.ts             # money/date utils (en-GB)
  hooks/
    use-claims.ts
    use-coverage.ts
    use-rag.ts
    use-pdf.ts
  styles/
    shadcn.css
  public/
    icons/
  tests/
    e2e/
    unit/
    a11y/
  .env.example
  Dockerfile
  next.config.mjs
  tailwind.config.ts
  postcss.config.js
  package.json
  tsconfig.json
  eslint.config.mjs
  playwright.config.ts
```

# API CLIENTS (STRICT TYPES)

- Create **zod** schemas for each service response and infer TypeScript types.
- Wrap `fetch` with:

  - base URL from `NEXT_PUBLIC_API_BASE` (Traefik hostname, e.g., `https://api.local`)
  - `credentials: "include"` (SSO cookie path through Traefik)
  - retries (idempotent GET), exponential backoff; error normalization `{type,title,status,detail,trace_id}`

- Use **TanStack Query** for caching, optimistic updates on overrides, and background refetch.

# KEY COMPONENT DETAILS

## PDF Viewer (`pdf-viewer.tsx`)

- Render via `pdfjs-dist`.
- **Overlay layer** draws rectangles from bbox `{page, x, y, w, h}`; clicking highlight scrolls to corresponding extracted field; right panel shows evidence details (doc_id, page, confidence, mapping to boxes).
- Keyboard shortcuts: `J/K` page nav; `H` toggle highlights; `Z` zoom.

## Coverage Matrix (`coverage-matrix.tsx`)

- Inputs: `CoverageReport`.
- Rows: evidence items; columns: status chip, boxes (expand to show list), actions (Upload, Clarify).
- “Clarify” opens `clarify-panel.tsx` which calls `/v1/coverage/clarify` and produces **copyable text** + **citations** + **upload actions**.

## Lineage Graph (`lineage-graph.tsx`)

- Render path: **FormValue → Evidence → Document** (+ any Rule/Calculation nodes).
- Click a node jumps to PDF viewer at the correct page/bbox (if Document is local).
- Cytoscape style: clean, accessible (labels, readable contrast).

## Schedule Table (`schedule-table.tsx`)

- Columns: `box_id`, `description`, `value`, `source`, `confidence`, `explain`
- **Explain** button opens `explain-drawer.tsx` which shows lineage graph + textual explanation trace (and citations if RAG guidance was used).

# ACCESSIBILITY & UX

- WCAG 2.2 AA: all interactive components keyboard accessible; focus outlines; ARIA labels
- **Axe** checks in unit and e2e tests; Lighthouse accessibility ≥ 95
- Colour-blind safe palette; do not encode status **only** by colour — use icon + label

# PERFORMANCE

- Code-split per route; lazy-load heavy views (PDF, graph)
- Virtualize long tables and evidence lists
- Preload API data via RSC loaders on server when appropriate
- Web Vitals: LCP < 2.5s on local; keep JS bundle sizes modest

# ENV & INTEGRATION

- `.env` (copied to `.env.local`):

  - `NEXT_PUBLIC_API_BASE=https://api.local`
  - `NEXT_PUBLIC_APP_BASE=https://ui.local`
  - `NEXT_PUBLIC_FEATURE_FLAGS_URL=` (optional)
  - `AUTHENTIK_LOGOUT_URL=` (show Sign Out link to edge logout endpoint)

- **Traefik labels** for the UI container:

  - Router rule `Host(\`ui.local\`)\` to UI service
  - Middleware `authentik-forwardauth` and `rate-limit`

- The UI calls backend at `https://api.local/*` via Traefik.

# TESTING (MANDATORY)

- **Unit (React Testing Library):**

  - `coverage-matrix` status rendering and actions
  - `clarify-panel` formatting with alternatives and citations
  - `pdf-viewer` highlight click → scroll and selection state
  - `lineage-graph` node click → callback invoked

- **E2E (Playwright):**

  - Login is handled by Traefik SSO; for local, place the UI behind the gateway.
  - Scenario: Upload docs → Run coverage → See blocking gaps → Generate clarify text → Upload alt evidence → Re-run coverage → OK → Compute schedule → Explain lineage → Generate forms → (stub) submit

- **A11y:** `axe-core` checks on major pages; fix violations.

# QUALITY GATES (CI)

- ESLint (`eslint.config.mjs` with `@typescript-eslint` + `jsx-a11y`)
- TypeScript `strict: true` (no implicit any/any)
- Prettier format check
- Playwright E2E (headless)
- Lighthouse CI (Dashboard, Coverage, Schedules) with budgets:

  - Performance ≥ 80 (local), Accessibility ≥ 95, Best Practices ≥ 90

# DELIVERABLES (RETURN ALL AS CODE BLOCKS)

1. `README.md` (local run with Traefik SSO; env vars; routes; role matrix)
2. `package.json` (scripts: dev, build, start, lint, typecheck, test, e2e, a11y, lighthouse)
3. `tsconfig.json` (strict true; noUncheckedIndexedAccess true)
4. `eslint.config.mjs` + `.prettier*`
5. `next.config.mjs` (headers passthrough; image domains)
6. `tailwind.config.ts` + `postcss.config.js`
7. `app/layout.tsx`, `app/(dashboard)/page.tsx`, route pages listed above
8. `app/api/me/route.ts` (server only: echo forwarded claims)
9. `middleware.ts` (SSR gate: if no forwarded claims, show “Not Authenticated”)
10. `components/*` (all listed)
11. `lib/*` (typed API, bbox utils, auth helpers, formatting)
12. `hooks/*` (coverage, rag, pdf, claims)
13. `tests/unit/*`, `tests/e2e/*`, `tests/a11y/*`
14. `Dockerfile`, `.env.example`, `playwright.config.ts`

# ACCEPTANCE CRITERIA (DoD)

- Runs behind Traefik + Authentik; **no in-app auth**.
- **Coverage Check** renders matrix, generates clarifying questions with citations, and triggers uploads.
- **PDF Viewer** highlights bboxes and navigates correctly; lineage jumps to precise evidence.
- **Schedules** compute and render with **Explain** showing graph & textual explanation with citations.
- **RAG** results include citations and never display PII.
- All pages pass Axe checks; Lighthouse thresholds met.
- CI green (lint, typecheck, unit, e2e, a11y, lighthouse).

# START

Generate the full **ui-review** application with the files and behavior above. Include typed API clients, strict TypeScript, accessible components, test suites, and Dockerfile.
