Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled
320 lines
13 KiB
Markdown
320 lines
13 KiB
Markdown
# 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.
|