13 KiB
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:
- onboard clients and see coverage status,
- ingest and review documents with PDF/bbox evidence,
- run coverage checks, generate clarifying questions, and upload missing evidence,
- do RAG + KG guidance searches with citations,
- compute and verify schedules with line-by-line lineage,
- generate filled forms and evidence packs,
- optionally submit to HMRC,
- 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 tosvc-gatewayor 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/meto readX-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/policysvc-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}/previewsvc-kg:/v1/kg/lineage/{node_id},/v1/kg/cypher(admin),/v1/kg/export/rdfsvc-rag-retriever:/v1/rag/searchsvc-reason:/v1/reason/compute_schedule,/v1/reason/explain/{schedule_id}svc-forms:/v1/forms/fill,/v1/forms/evidence_packsvc-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)
-
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
-
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)
-
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/clarifywith citations - Inline Upload buttons mapped to
svc-ingestionwithtag=set to evidence.id
-
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)
-
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
-
Forms & Evidence Pack
- Generate PDFs (download viewer); Evidence Pack download (ZIP + manifest)
- Checklist (“All blocking gaps resolved”, “Reviewer sign-off received”)
-
Submission
- Pre-flight checks, HMRC mode banner (stub/sandbox/live)
- Submit; show
submission_idand status; link to timeline
-
Timeline & Audit
- Event list (ingested, OCR, extracted, mapped, computed, submitted)
- Filter by service; click to jump to relevant screen or doc
-
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
fetchwith:- 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}
- base URL from
-
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/Kpage nav;Htoggle highlights;Zzoom.
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.tsxwhich calls/v1/coverage/clarifyand 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.tsxwhich 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.localNEXT_PUBLIC_APP_BASE=https://ui.localNEXT_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-forwardauthandrate-limit
- Router rule
-
The UI calls backend at
https://api.local/*via Traefik.
TESTING (MANDATORY)
-
Unit (React Testing Library):
coverage-matrixstatus rendering and actionsclarify-panelformatting with alternatives and citationspdf-viewerhighlight click → scroll and selection statelineage-graphnode 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-corechecks on major pages; fix violations.
QUALITY GATES (CI)
-
ESLint (
eslint.config.mjswith@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)
README.md(local run with Traefik SSO; env vars; routes; role matrix)package.json(scripts: dev, build, start, lint, typecheck, test, e2e, a11y, lighthouse)tsconfig.json(strict true; noUncheckedIndexedAccess true)eslint.config.mjs+.prettier*next.config.mjs(headers passthrough; image domains)tailwind.config.ts+postcss.config.jsapp/layout.tsx,app/(dashboard)/page.tsx, route pages listed aboveapp/api/me/route.ts(server only: echo forwarded claims)middleware.ts(SSR gate: if no forwarded claims, show “Not Authenticated”)components/*(all listed)lib/*(typed API, bbox utils, auth helpers, formatting)hooks/*(coverage, rag, pdf, claims)tests/unit/*,tests/e2e/*,tests/a11y/*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.