# AI Tax Agent — UX Spec & Journey Catalog (v1) > Audience: Product, Design, Frontend & QA. This document defines **all user interactions** and **end‑to‑end journeys** across personas (Individual, Accountant/Firm, Admin/Ops, RPA Operator, Cross‑Border/Expat). It aligns with the architecture: **Neo4j graph (completeness/lineage)** + **Qdrant vector search (guidance/fields/evidence)** + **RPA**. --- ## 0) Design Tenets - **Explainable by design**: Every decision references a rule/field/guidance citation. Lineage is one click away. - **Guided, not gated**: Wizard with a live “Completeness checklist”. Users can skip and return. - **Draft‑safe**: Everything is autosaved, idempotent, and recoverable. - **Privacy‑first**: PII masked by default; reveal is explicit and audited. - **Jurisdiction‑aware**: UI adapts labels, formats (en‑GB / el‑GR), deadlines, and required pages. - **Low‑friction evidence**: Upload anywhere; extraction & mapping run in the background with visible status. - **Keyboard & screen‑reader friendly**: WCAG 2.1 AA. --- ## 1) Personas & Primary Goals - **Individual (B2C)**: File accurately with minimal effort; understand what’s missing and why. - **Accountant / Firm (B2B)**: Triage portfolio, automate routine, keep audit trail, file at scale. - **Admin / Ops**: Configure jurisdictions, monitor health, manage catalogs/flags, ensure compliance. - **RPA Operator / Support**: Orchestrate robot sessions, handle MFA/DOM drift, capture artifacts. - **Cross‑Border / Expat**: Manage multi‑jurisdiction obligations in one place. --- ## 2) Information Architecture & Navigation **Top‑level navigation (role‑aware):** Dashboard · Profiles/Clients · Documents · Reconciliation · Build & QA · Submissions · Guidance · Admin (role gated) **Context switchers:** - **Firm selector** (Accountant) - **Jurisdiction & Tax Year** per profile **Global elements:** - Search bar (fields + guidance powered by vector search) - Notifications (jobs: OCR/extract/index/RPA) - Profile switcher - Help & audit log links --- ## 3) UI Patterns & Key Components - **Wizard** (Profile → Bank → State Data → Upload → Reconcile → Build → QA → Submit → Archive) - **Completeness checklist** (Graph): Required pages & missing fields, deep links. - **Lineage panel**: Field → Calculation → Rule → Guidance citation; copy citation. - **Document Inbox**: Upload, progress, OCR status, extraction results, evidence links. - **Reconciliation dashboard**: Rents vs deposits; interest deltas; exceptions with CTAs. - **Semantic search** (Vector): Results for fields/rules/guidance with facet chips (jurisdiction, year, form/page). - **Masking controls**: AFM/UTR/NINO hidden by default; “Reveal” with audit. - **Toasts & job status chips**: queued · running · succeeded · failed. --- ## 4) Journeys by Persona ### 4.1 Individual (B2C) #### I‑1 Sign‑in & Locale **Entry**: Landing → “Sign in” **Steps**: OIDC (PKCE) → consent → pick language (en‑GB/el‑GR) **System**: Session established; locale persisted **Exit**: Dashboard with “Start your {Jurisdiction} {Tax Year} filing” #### I‑2 Create/Select Profile **Entry**: Dashboard → “New filing” **Steps**: Choose Jurisdiction (UK/GR), Tax Year; add identifiers (AFM/UTR/NINO); save **System**: Creates `TaxpayerProfile`; graph completeness bootstraps **Exit**: Wizard step 1 with checklist #### I‑3 Connect Bank (optional) **Entry**: Wizard → “Connect bank” **Steps**: Redirect to bank consent → approve → back **System**: Accounts/transactions synced; recon pre‑computed **Exit**: Bank tiles; recon hints show #### I‑4 Fetch State Data (optional) **Entry**: Wizard → “Fetch from portal” **Steps**: Start RPA → MFA if needed → retrieve PDFs **System**: Files saved; OCR/extract jobs launched; lineage recorded **Exit**: Documents tab shows new items with status #### I‑5 Upload Documents **Entry**: Documents → “Upload” **Steps**: Drag & drop → progress → OCR → Extract **System**: Entities validated; `PROVIDED` edges to fields; evidence chunks indexed **Exit**: Completeness updates; toasts show results #### I‑6 Guidance & Field Search **Entry**: Global search **Steps**: Query “rental income” or “bank interest” **System**: Vector top‑k → mapped to fields/rules; open lineage/guidance **Exit**: User navigates directly to the correct field #### I‑7 Completeness & Fix‑ups **Entry**: Checklist panel **Steps**: Click missing item → form field view → enter value **System**: `provide` call; re‑run completeness **Exit**: Item disappears; checklist can reach “All set” #### I‑8 Build & QA **Entry**: Build page **Steps**: Click “Build return” → Review payload summary → “Run QA” **System**: Blocking vs warnings; deep link to issues **Exit**: QA green or remaining warnings acknowledged #### I‑9 Submission (Dry → Live) **Entry**: Submit **Steps**: Dry run (RPA) → review screenshots → confirm Live (if enabled) **System**: Archive bundle; receipt **Exit**: Success screen with download links #### I‑10 Archive & Support **Entry**: Submissions **Steps**: Download receipt; open lineage; contact support **System**: Audit log entries **Exit**: Filing closed **Edge cases**: Bank revoked; OCR low confidence; rule ambiguity → show explainers & next‑best action. --- ### 4.2 Accountant / Firm (B2B) #### F‑1 Login & Firm Context **Entry**: OIDC login **Steps**: Select Firm (if multi‑firm) **System**: `X‑Firm‑Id` header set **Exit**: Firm dashboard #### F‑2 Bulk Client Onboarding **Entry**: Clients → “Import CSV” **Steps**: Upload template; map columns (AFM/UTR, name, year) **System**: Profiles created/updated; errors inline **Exit**: Worklist populated #### F‑3 Portfolio Triage **Entry**: Dashboard **Steps**: Filters (jurisdiction/year/status); sort by due date/exception count **System**: Saved views; counts; SLA badges **Exit**: Prioritized queue #### F‑4 Document Intake at Scale **Entry**: Client detail → Documents **Steps**: Multi‑upload; run OCR/extract; monitor jobs **System**: Batch tasks; progress per client **Exit**: Completeness shrinks across profiles #### F‑5 State Data Fetch (Bulk RPA) **Entry**: Actions → “Fetch” **Steps**: Select clients; schedule; monitor **System**: Rate‑limited sessions; screenshots; retries **Exit**: Evidence attached for many clients #### F‑6 Reconciliation Dashboards **Entry**: Recon tab **Steps**: Rents vs deposits; interest deltas; export CSV **System**: Exceptions with direct CTAs to fields **Exit**: Reduced exception backlog #### F‑7 Completeness & NBA (Bulk) **Entry**: Worklist **Steps**: Open completeness per client; batch provide (defaults) **System**: Idempotent provides; audit trail **Exit**: Many files move to “Ready to build” #### F‑8 Build/QA/Submit (Per client or Bulk) **Entry**: Actions **Steps**: Build → QA → dry submit → (optionally) live submit **System**: Archive receipts; prevent duplicates via Idempotency‑Key **Exit**: Filed returns with artifacts #### F‑9 Audit & Explainability **Entry**: Client page **Steps**: Open lineage for totals; copy citations **System**: Graph traversal with guidance **Exit**: Audit‑ready documentation #### F‑10 Reporting & KPIs **Entry**: Analytics **Steps**: Throughput; auto‑complete %; exception rate **System**: Grafana panels embedded links **Exit**: Operational insights **Edge cases**: Conflicting docs; mismatched identifiers; consent expiry; rate limits. --- ### 4.3 Admin / Ops #### A‑1 Jurisdiction & Catalog Config **Entry**: Admin → Catalog **Steps**: Enable/disable forms; set tax‑year visibility; upload new schema versions **System**: Flags stored; migration checks **Exit**: UI reflects new scope #### A‑2 Health & Observability **Entry**: Admin → Health **Steps**: View /health, /metrics; error rates; queue lag **System**: Alerts linked; runbook links **Exit**: Acknowledged incidents #### A‑3 Access & Audit **Entry**: Admin → Security **Steps**: Roles; access logs; export audits **System**: PII redaction enforced **Exit**: Compliance evidence generated #### A‑4 Webhooks & Integrations **Entry**: Admin → Integrations **Steps**: Configure webhooks (upload, consent); test delivery **System**: Signed events; retries **Exit**: Integrations online --- ### 4.4 RPA Operator / Support #### R‑1 Session Control **Entry**: RPA Control Room **Steps**: Start session; observe steps; MFA pause → resume **System**: Screenshots, DOM selectors **Exit**: Jobs succeed or re‑queued #### R‑2 DOM Drift Recovery **Entry**: On error **Steps**: Edit selectors; retry step; file incident **System**: Config updated; audit trail **Exit**: Flow unblocked --- ### 4.5 Cross‑Border / Expat #### X‑1 Dual Profile Setup **Entry**: Profile → “Add jurisdiction” **Steps**: Add UK & GR profiles; link identifiers **System**: `Taxpayer` → `HAS_PROFILE` (UK, GR) **Exit**: Two scoped profiles #### X‑2 Foreign Income & Credits **Entry**: Income panel **Steps**: Declare foreign income; upload proof; run completeness both sides **System**: Rules trigger correct pages; lineage cites treaties/guidance **Exit**: Correct forms required #### X‑3 Dual Build & Submission **Entry**: Build/QA per jurisdiction **Steps**: Build UK + GR; QA; (dry) submit; archive both **System**: Two receipts; one evidence bundle **Exit**: Fully compliant filing --- ## 5) Screen Inventory & States - **Dashboard**: Cards by status; due dates; resume buttons; empty state with CTA. - **Profile Editor**: Identifiers (masked), jurisdiction/year pickers; validation errors inline. - **Documents Inbox**: Upload area; list with statuses; filters; preview with OCR text & entities; lineage tab. - **Evidence Browser** _(new)_: Global list of documents/evidence; filters (kind, source, year, linked/unlinked); batch attach to fields. - **Transaction Detail** _(new)_: View single transaction; related documents; link/unlink to fields. - **Search Results**: Tabs for Fields · Rules · Guidance; chips for jurisdiction/year/form; result actions: “Go to field”, “Open guidance”, “Copy citation”. - **Completeness Panel**: Required pages list; missing fields; “Provide” inline; progress meter. - **Form Builder**: Collapsible sections per page; computed fields badge; “Show lineage”. - **QA Report**: Blocking vs Warnings; deep links to fields; export. - **Submission**: Dry‑run gallery; confirm dialog; success screen with receipt links. - **Recon Dashboard**: Exceptions table; “Fix” CTAs; CSV export. - **Admin Panels**: Catalog, Health, Integrations, Security. - **RPA Control Room**: Job list; live viewer; pause/resume; step logs. **State management**: loading, empty, partial (draft), error; offline fallback where possible. --- ## 6) Interaction Details & Microcopy - **Mask toggle**: “Reveal for 30s” (tooltip: “AFM/UTR is sensitive. We log this event.”) - **Completeness empty**: “All set — you can build your return now.” - **QA blocking**: “You must resolve these before submission.” - **Retry UI**: “We’ll retry automatically in 30s” with timer on 429. - **Evidence chips**: “From: Bank_2024_May.pdf (p.3)” → opens preview at the exact chunk highlight. - **Lineage**: “Calculated via E2_NET from A1 and A2 — See guidance (Section 2).” --- ## 7) Accessibility & Internationalization - Keyboard access (tab order, skip‑to‑content, visible focus) - Labels/aria for dynamic panels (completeness, lineage) - Color contrast ≥ 4.5:1; no color‑only cues - Date, currency, and number formats per jurisdiction; translated microcopy (en‑GB/el‑GR) --- ## 8) Telemetry & KPIs (per journey) - **Funnel**: Upload → OCR → Extract → Provide → Build → QA → Submit - **Search**: query → click‑through → success (did they navigate to a field?) - **Completeness**: time to green; # of missing fields when user first opens - **RPA**: success rate; avg steps; DOM drift incidents - **Recon**: exceptions resolved per week All events include: `user_role`, `jurisdiction`, `tax_year`, `profile_id` (hashed), `correlation_id`. --- ## 9) Acceptance Criteria (UX) - Every journey above has a **happy path** that is keyboard‑accessible and screen‑reader friendly. - Each screen has **empty / loading / error** states and helpful recovery. - Completeness always matches graph results; lineage opens within 1s and shows rule + guidance. - Vector search returns actionable results with jurisdiction filters visible. - Sensitive identifiers masked by default; reveal audited. - i18n covers 100% of visible strings for en‑GB and el‑GR. --- ## 10) Mobile & Responsive - Breakpoints: sm (mobile), md (tablet), lg (desktop) - Documents inbox and wizard optimized for one‑column flow on mobile - Tables become stacked cards with key actions as primary buttons --- ## 11) Handoff Artifacts - Component library (shadcn/ui + Tailwind), tokens for spacing/typography - Figma (or equivalent) pages: Dashboard, Profile, Documents, Search, Completeness, Form Builder, QA, Submission, Recon, Admin, RPA - Copy deck for both locales; glossary for tax terms --- ## 12) Risks & Mitigations (UX) - **Overwhelm in completeness** → progressive disclosure, quick filters (page/mandatory/has evidence) - **Trust in automation** → surface citations + screenshots; allow explicit user confirmation before live submit - **Jurisdiction confusion** → consistent badge + sticky selector; scoped search and guidance ## 13) Detail Screens — Form Field, Page, and Form (UI Specs) ### 13.1 Form Field Detail View **Route:** `/profiles/:profileId/fields/:fieldId` **Purpose:** Single source of truth to **view/edit a field**, with **lineage, evidence, rules, validation, history**. **Layout (desktop):** - **Header bar:** Breadcrumbs (Profile → Form → Page → Field) · Jurisdiction/Year pills · Status chip (Missing / Provided / Computed / Overridden / N/A). - **Two‑column body:** - **Left (≈60%) — Value & Context** 1. **Field summary card** — `field_id`, box number, label/description, data type, mandatory badge, form/page IDs. 2. **Value editor** — component by type: - Currency/Number: locale formatting (en‑GB/£, el‑GR/€), thousand separators, min/max, negative allowed? - Date: datepicker with mask; timezone‑free. - Boolean: switch with Yes/No labels. - String: single line or textarea; max length. - **Computed fields**: read‑only pill; **Override** toggle (requires reason) → audit. - **N/A** toggle (where allowed by rule) → requires reason. - **Save** (primary), **Revert** (to last saved), inline validation messages. 3. **Validation & QA messages** — live validators + QA blockers/warnings relevant to this field. 4. **History & Audit** — timeline: created/updated, source (manual, OCR, RPA), actor, old→new values. - **Right (≈40%) — Explainability & Evidence** 1. **Lineage panel** — `Calculation` preview: formula, inputs (with current values & links), producing this field; recompute button. 2. **Governing rules** — list of `TaxRule` items with badges (Requirement/Eligibility/Exclusion); each has **Open guidance** (new tab) + **Copy citation**. 3. **Evidence** — linked `Document` chunks (title, page, snippet). Actions: _Attach existing_, _Find evidence_ (opens semantic search modal), _Preview_ (right‑side drawer with highlight), _Detach_. **Interactions & States** - Load: skeletons → data fetched; optimistic updates on save; toasts with correlation ID. - **Provide from Evidence**: select a snippet → auto‑parse value (LLM) → user confirms → value + lineage `(Document)-[:DERIVES]->(FormField)` persisted. - **Override computed**: require reason, show warning banner; audit entry created; can **Reset to computed**. - **Mark as N/A**: only if a governing rule allows exclusion; stores reason; removes from completeness. - **Keyboard**: all inputs tabbable; `Enter` to save; `Esc` to cancel edits. **API Contracts (used)** - `GET /catalog/fields/{field_id}` _(or)_ `GET /graph/field?field_id=&profile_id=` (metadata)\* - `POST /graph/provide` `{ profile_id, field_id, value, source, ts }` - `GET /graph/lineage?profile_id=&field_id=` → `{ calc, inputs[], rules[], guidance[] }` - `GET /search/guidance?q=&jurisdiction=&year=&field_id=` - `GET /files/{doc_id}` + signed download; evidence index via vector search > \*If `/graph/field` doesn’t exist yet, add a thin endpoint that returns field metadata joined with page/form labels for the header/breadcrumbs. **Acceptance Criteria (Field Detail)** - Mandatory field shows red badge; saving valid value removes it from completeness within 1s. - Computed field displays formula and input links; _Reset to computed_ restores derived value. - Evidence attach creates lineage link; preview opens at the correct page and highlights the chunk. - Audit timeline reflects user, timestamp, source; copy action logs a “reveal” only for identifiers. - i18n formatting for currency & date respects jurisdiction; screen reader labels present. #### 13.1.a Evidence Model & States **Graph/Data model** - `(:Document {doc_id, kind, year, source:'RPA'|'Upload'|'Webhook', s3_uri, checksum})` - `(:Transaction {txn_id, date, amount, currency, narrative, account_ref})` - `(:Document)-[:DERIVES {chunk_ref, extractor_id, confidence}]->(:FormField)` _(direct evidence)_ - `(:Document)-[:DERIVES]->(:Transaction)` and `(:Transaction)-[:SUPPORTS]->(:FormField)` _(indirect evidence → roll‑up)_ - `(:TaxpayerProfile)-[:PROVIDED {value, source:'manual'|'ocr'|'rpa'|'calc', confidence, ts, evidence_doc_id?, tx_ids?}]->(:FormField)` _(accepted value)_ **Evidence states** - **Attached (Accepted)** – currently backing the saved value (has lineage edge and is referenced in `PROVIDED`). - **Suggested** – candidate evidence with parsed value; not yet accepted. - **Conflicting** – multiple candidates disagree; show diff. - **Stale** – evidence outside tax year or superseded by newer doc. - **Official** badge – source = `RPA` (HMRC/AADE portal) vs `Upload`. **UI in Field Detail (Right column → Evidence card)** - Tabs: **Attached** · **Suggested** · **Upstream** · **Portal** - **Attached**: list of currently linked docs/transactions; badge (Official/Upload); quick actions: _Preview_, _Detach_, _Open in inbox_. - **Suggested**: ranked by confidence; each row → _Attach & Fill_ (writes value + lineage) or _Ignore_. - **Upstream**: when field is computed → shows inputs and their own attached evidence; when field is fed by transactions → shows aggregation group (e.g., “6 tx across 2 accounts → £412.50”). - **Portal**: latest HMRC/AADE downloads relevant to this field/page with scrape step & screenshot link. **Actions** - _Attach & Fill_: sets the editor value; persists `PROVIDED` + `DERIVES` edges; marks others as candidates. - _Attach (no fill)_: link evidence without updating value (for audit only). - _Preview_: right drawer → PDF page at `chunk_ref` or transaction list → click to view transaction detail. - _Find evidence_: opens semantic search modal scoped to page/field. #### 13.1.b Drill‑downs From a field you can: 1. **Open Document preview** → displays page with highlighted snippet; toolbar: zoom, copy citation, open original. 2. **Open Transaction detail** → `/transactions/:txn_id` modal or page: date, amount, account, categorization, source doc links. 3. **Open Portal session** → step timeline with screenshots; highlights the DOM region used for extraction. #### 13.1.c Auto‑provision from HMRC/AADE PDFs 1. R**PA fetch → store PDF (source=**`RPA`). 2. OCR/extract parses values → creates **Suggested** evidence with parsed values and confidence. 3. If confidence ≥ threshold AND rule marks field **auto‑fillable**, system performs _Attach & Fill_ automatically; otherwise it surfaces as **Suggested** for user approval. 4. Any auto‑fill is flagged with _Official_ badge and appears in History with extractor id. #### 13.1.d Conflicts & Versioning - If two **Suggested** values disagree (± tolerance), show **Conflicting** state with a diff (value, source, date). - Accepting one **Supersedes** others (kept for audit, marked inactive). - Newer portal downloads mark older **Attached** evidence **Stale** and propose an update. --- ### 13.2 Page Detail (SupplementaryPage) **Route:** `/profiles/:profileId/pages/:pageId` **Purpose:** Operate on a **coherent section** (e.g., SA105, E2) with progress and bulk actions. **Layout:** - Header: Page name/ID, form link, mandatory count, progress ring (completed/total), **Status** (Required/Optional/Excluded). - Tabs: **Fields** · **Calculated** · **Guidance** · **Evidence** - **Fields tab:** - Table (or cards on mobile): Field label, box no., status, current value, last source, actions (Edit, Lineage, Attach evidence). - Filters: Missing only · Mandatory only · Has evidence · Overridden. - Bulk: _Provide defaults_ (pre‑approved safe defaults), _Import CSV_ (for repeating groups), _Clear overrides_. - **Calculated tab:** lists computed outputs and their inputs with quick links. - **Guidance tab:** embedded results from `/search/guidance` scoped to page; open in new tab. - **Evidence tab:** documents linked to this page; unmatched chunks suggestions. **Interactions** - Clicking a field opens **Form Field Detail** (same view as 13.1). - “Mark page as N/A” only if all governing rules allow exclusion → confirmation modal with reason. **AC (Page Detail)** - Progress updates live when fields are saved. - Filters persist in URL params; back/forward browser works. - Bulk actions show diff modal before committing. --- ### 13.3 Form Detail (TaxForm) **Route:** `/profiles/:profileId/forms/:formId` **Purpose:** Overview for the entire return form; entry point to pages. **Layout:** - Header: Form name/ID, jurisdiction/year badges, due dates, filing mode (paper/online), status chips. - Sections: - **Required pages** (from completeness) with % complete. - **Optional/suggested pages** (based on rules). - **Summary**: totals & computed highlights; warnings (if any). - **Actions**: Build draft payload · Run QA · View QA report. **Interactions & AC** - Build runs `/forms/build`; shows summary diff vs last build. - QA runs `/forms/qa`; blocking items deep‑link to the specific field detail. - Required pages accordions reflect completeness counts. --- ### 13.4 Completeness Panel (Deep‑link behaviors) - From **Completeness**, clicking an item navigates to **Field Detail** with `?from=completeness` (so back action returns to checklist and scrolls to the item). - If a field is **computed**, the CTA becomes **“Review calculation”** and anchors the Lineage panel. --- ### 13.5 Mobile Variants - Single column; sticky footer with **Save** / **Reset** / **Find evidence**. - Page Detail fields render as stacked cards with quick actions. --- ## 14) UI API Mapping (Detail Pages) | UI Element | Endpoint | Notes | | --------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------- | | Field header metadata | `GET /catalog/fields/{field_id}` or `GET /graph/field?field_id=&profile_id=` | Include form/page labels, data type, mandatory flag | | Save value | `POST /graph/provide` | Idempotency‑Key header; returns new edge & updated completeness | | Lineage load | `GET /graph/lineage?profile_id=&field_id=` | Returns calculation + inputs + rules + citations | | Evidence search | `GET /search/guidance` + vector index of evidence | Scope by `jurisdiction`, `tax_year`, `field_id` | | Evidence attach | `POST /graph/link-evidence` | Create `(Document)-[:DERIVES]->(FormField)` (if not present) | | Page completeness | `GET /graph/completeness?profile_id=&page_id=` | Filtered to page context | | Build/QA | `/forms/build`, `/forms/qa` | For Form Detail actions | > If `link-evidence` is not yet defined, expose a small endpoint that creates the lineage edge with `{doc_id, profile_id, field_id, chunk_ref?, note?}`. --- ## 15) Test Cases (Field/Page/Form Detail) **T‑FD‑01 Save valid value (mandatory)** → Completeness decrements; toast success; audit entry added. **T‑FD‑02 Computed field reset** → Override → Reset to computed restores derived value. **T‑FD‑03 Provide from Evidence** → Pick chunk → parsed value filled → lineage edge created. **T‑FD‑04 N/A toggle** → Only enabled if allowed; requires reason; completeness updated. **T‑FD‑05 Guidance open/copy** → Opens HMRC/AADE page; copy puts citation on clipboard. **T‑PD‑01 Filter “Missing only”** → Only missing rows displayed; URL param persists on reload. **T‑FoD‑01 Build & QA from Form Detail** → Runs, renders results, deep‑links into field detail for blockers. --- ## 16) Component Inventory (Field Detail) - `FieldSummaryCard` - `FieldValueEditor` (Currency/Number/Date/Boolean/String variants) - `ComputedBadge` + `OverrideToggle` - `ValidationList` (live + QA) - `HistoryTimeline` - `LineagePanel` - `RulesList` (+Citation chips) - `EvidenceList` (+Preview drawer) --- ## 17) Analytics (Field/Page/Form Detail) - `field_view` (profile_id, field_id, jurisdiction, year) - `field_save` (source, value_hash, duration_ms) - `field_override_toggle` (on/off, reason_len) - `evidence_attach` (doc_id, chunk_ref) - `page_filter_change` (filter_set) - `form_build`, `form_qa` --- ## 18) Accessibility Notes (Detail Pages) - Announce validation errors via `aria-live` polite. - Associate inputs with labels and help text; include box number in label for screen readers. - Keyboard shortcuts: `g` to open Guidance list, `l` to focus Lineage. --- ## 19) Open Questions / TODOs - Should **N/A** be reversible without audit approver? (policy) - Do we allow **bulk overrides** on a page? (dangerous — likely flag‑guarded) - Add `/graph/field` and `/graph/link-evidence` if not present. ## 20) API Contracts — Evidence, Transactions, Field Metadata, Auto‑Provision Policies > All endpoints are under `/api/v1`. Auth via OIDC (Bearer). Firm scoping via `X‑Firm‑Id` (Accountant/Firm). Responses use **RFC7807 Problem+JSON** on errors. ### 20.1 Attach Evidence to a Field **POST** `/graph/link-evidence` **Purpose**: Link a document chunk and/or transactions as evidence for a field. Optionally **fill** the field value (and create lineage). **Headers** - `Authorization: Bearer ` - `Idempotency-Key: ` _(required)_ **Request (JSON)** ```json { "profile_id": "UK_PROFILE_001", "field_id": "SA105_b5", "doc_id": "HMRC-SA105-2024-PDF-001", "chunk_ref": "p12#bbox(120,340,510,420)", "txn_ids": ["txn_8a1", "txn_8a2"], "parsed_value": 6420.75, "source": "rpa", "confidence": 0.93, "attach_only": false, "note": "Official HMRC PDF May 2025" } ``` **Behavior** - Creates `(Document)-[:DERIVES {chunk_ref, extractor_id?, confidence}]->(FormField)` if `doc_id` present. - Creates `(Transaction)-[:SUPPORTS]->(FormField)` for each `txn_id`. - If `attach_only=false` and `parsed_value` present → upserts `(TaxpayerProfile)-[:PROVIDED {...}]->(FormField)` and re‑runs completeness. - Marks prior evidence **Superseded** if overwriting an attached value. **Response 200 (JSON)** ```json { "status": "attached", "field_id": "SA105_b5", "provided": true, "value": 6420.75, "evidence": { "doc_id": "HMRC-SA105-2024-PDF-001", "chunk_ref": "p12#bbox(120,340,510,420)", "txn_ids": ["txn_8a1", "txn_8a2"], "confidence": 0.93, "source": "rpa" }, "completeness": { "missing_count": 3 } } ``` **Errors** - `400` invalid payload (missing `profile_id`/`field_id`) - `403` forbidden (role/firm scope) - `404` profile/field/doc/txn not found or not owned by profile - `409` conflict (stale year, superseded doc, or field locked) - `422` validation (type mismatch for `parsed_value`) --- ### 20.2 List Evidence (with filters) **GET** `/evidence` **Query params** - `profile_id` _(required)_ - `field_id` | `page_id` _(optional scope)_ - `source` = `upload|rpa|webhook` _(optional)_ - `kind` = `document|transaction` _(optional)_ - `linked` = `true|false` _(optional)_ - `year` _(optional)_ - `q` _(optional search over doc title/snippet)_ - `limit` _(default 25)_, `cursor` **Response 200** ```json { "items": [ { "type": "document", "doc_id": "HMRC-SA105-2024-PDF-001", "title": "SA105 Notes 2024", "source": "rpa", "year": "2024-25", "linked_fields": ["SA105_b5"], "chunk_ref": "p12#bbox(120,340,510,420)", "parsed_value": 6420.75, "confidence": 0.93, "created_at": "2025-05-16T09:21:37Z" }, { "type": "transaction", "txn_id": "txn_8a1", "date": "2025-04-03", "amount": 412.5, "currency": "GBP", "narrative": "Rent April", "linked_fields": ["SA105_b5"], "doc_ids": ["BANK-STATEMENT-APRIL"], "created_at": "2025-04-04T12:10:00Z" } ], "next_cursor": null } ``` --- ### 20.3 Transaction Detail **GET** `/transactions/{txn_id}` **Response 200** ```json { "txn_id": "txn_8a1", "profile_id": "UK_PROFILE_001", "date": "2025-04-03", "amount": 412.5, "currency": "GBP", "account_ref": "uk_hsbc_main", "narrative": "Rent April", "doc_ids": ["BANK-STATEMENT-APRIL"], "linked_fields": [{ "field_id": "SA105_b5", "relation": "SUPPORTS" }], "year": "2024-25", "created_at": "2025-04-04T12:10:00Z" } ``` **Errors**: `404` if not visible under caller’s scope. --- ### 20.4 Field Metadata (for detail header) **GET** `/graph/field?profile_id={pid}&field_id={fid}` **Response 200** ```json { "field": { "field_id": "SA105_b5", "form_id": "SA100", "page_id": "SA105", "box_number": "5", "description": "Total rents and other income", "data_type": "Currency", "mandatory": true }, "profile": { "profile_id": "UK_PROFILE_001", "jurisdiction": "UK", "tax_year": "2024-25" }, "status": "missing|provided|computed|overridden|na", "current_value": 6420.75, "source": "rpa|manual|ocr|calc", "last_updated": "2025-05-16T09:22:01Z" } ``` --- ### 20.5 Auto‑Provision Policies **GET** `/policies/autoprovision` **Response 200** ```json { "defaults": { "confidence_threshold": 0.85, "numeric_tolerance": 0.01, "allow_auto_fill": false }, "overrides": { "SA105_b5": { "allow_auto_fill": true, "confidence_threshold": 0.9 }, "E2_A1": { "allow_auto_fill": true } }, "rules": { "UK_PROP_NEEDS_SA105": { "auto_attach_only": true } } } ``` **PUT** `/policies/autoprovision` _(Admin required)_ **Request** ```json { "defaults": { "confidence_threshold": 0.88, "allow_auto_fill": true }, "overrides": { "SA105_b7": { "allow_auto_fill": false } }, "rules": { "GR_E2_NET_GOVERN": { "auto_attach_only": true } } } ``` **Response 200** ```json { "status": "updated", "version": "2025-08-19T10:00:00Z" } ``` **Notes** - Policies are versioned; changes are logged to audit. - Worker reads latest policy snapshot before extraction/auto‑provision. --- ### 20.6 Problem+JSON Error Shape ```json { "type": "https://api.example.com/errors/validation", "title": "Unprocessable Entity", "status": 422, "detail": "parsed_value must be a number for Currency fields", "instance": "/graph/link-evidence", "errors": { "parsed_value": "not a number" } } ``` --- ### 20.7 Security, Idempotency, Rate Limits - **RBAC**: roles `individual`, `accountant`, `admin`. Firm scope required for accountant via `X‑Firm‑Id`. - **Idempotency**: `POST /graph/link-evidence` and `POST /graph/provide` require `Idempotency-Key`. - **Rate limits**: `GET /evidence` and `GET /transactions/:id` 60 rpm/user; bursts allowed via token bucket. - **Audit**: Every attach/fill/override emits audit events with before/after diffs and evidence references. --- ## 21) cURL Examples **Attach & Fill from portal PDF** ```bash curl -X POST "$API/graph/link-evidence" \ -H "Authorization: Bearer $TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "profile_id":"UK_PROFILE_001", "field_id":"SA105_b5", "doc_id":"HMRC-SA105-2024-PDF-001", "chunk_ref":"p12#bbox(120,340,510,420)", "parsed_value":6420.75, "source":"rpa", "confidence":0.93, "attach_only":false }' ``` **List suggested evidence for a page** ```bash curl "$API/evidence?profile_id=UK_PROFILE_001&page_id=SA105&linked=false&source=rpa&limit=50" \ -H "Authorization: Bearer $TOKEN" ``` **Transaction detail** ```bash curl "$API/transactions/txn_8a1" -H "Authorization: Bearer $TOKEN" ``` --- ## 22) Acceptance Criteria — APIs - `POST /graph/link-evidence` creates lineage edges and (optionally) provided value; idempotent retry returns same result. - `GET /evidence` filters work in combination; pagination stable via cursor; performance p95 < 300ms. - `GET /transactions/{id}` includes related docs and linked fields; 404 on cross‑tenant access. - Policy GET/PUT round‑trips; worker consumes updated policies within 60s. --- ## 23) QA Test Matrix — Evidence & Transactions - **E1** Attach‑only (no fill) → evidence listed as Attached; field value unchanged. - **E2** Attach & Fill (manual upload) → value saved; completeness decremented; lineage present. - **E3** Attach & Fill (RPA) with low confidence → remains Suggested; no auto‑fill. - **E4** Conflict: two values disagree → Conflicting state shown; accept one supersedes other. - **E5** Transaction roll‑up supports field → Upstream tab shows group; unlink removes support edge. - **E6** Policy change → enabling auto‑fill for SA105_b5 leads to automatic fill on next extraction. — End —