docs(tasks): define dashboard implementation tasks

This commit is contained in:
2026-08-20 18:37:54 +03:30
parent 505ae5c04f
commit 8b168f7721
2 changed files with 805 additions and 1 deletions

View File

@@ -7,5 +7,6 @@ Current state: design/specification only. No frontend scaffold or runtime code h
- [`DESIGN.md`](DESIGN.md): visual language, interaction rules, responsive behavior, and current design-system state. - [`DESIGN.md`](DESIGN.md): visual language, interaction rules, responsive behavior, and current design-system state.
- [`docs/DASHBOARD-SPEC.md`](docs/DASHBOARD-SPEC.md): approved product requirements and acceptance criteria for implementation planning. - [`docs/DASHBOARD-SPEC.md`](docs/DASHBOARD-SPEC.md): approved product requirements and acceptance criteria for implementation planning.
- [`docs/DASHBOARD-UX-SPEC.md`](docs/DASHBOARD-UX-SPEC.md): detailed screen map, RTL layouts, async states, data presentation, accessibility, and authorized export workflows. - [`docs/DASHBOARD-UX-SPEC.md`](docs/DASHBOARD-UX-SPEC.md): detailed screen map, RTL layouts, async states, data presentation, accessibility, and authorized export workflows.
- [`tasks/plan.md`](tasks/plan.md): SDD Phase 2 dependency order, risk spikes, vertical slices, and approval gates; implementation remains unauthorized. - [`tasks/plan.md`](tasks/plan.md): approved SDD Phase 2 dependency order, risk spikes, vertical slices, and approval gates.
- [`tasks/todo.md`](tasks/todo.md): draft SDD Phase 3 task list awaiting review before implementation.
- [`AGENTS.md`](AGENTS.md): durable rules for future coding agents and contributors. - [`AGENTS.md`](AGENTS.md): durable rules for future coding agents and contributors.

803
tasks/todo.md Normal file
View File

@@ -0,0 +1,803 @@
# Phase 3 Task List — Merchant Analytics Dashboard
- Status: Draft for human review
- SDD phase: 3 — Tasks
- Source plan: [`plan.md`](plan.md)
- Implementation authorization: Not granted
- Last updated: 2026-08-20
Tasks are ordered by dependency. Each implementation task must satisfy its acceptance criteria plus the Definition of Done in `tasks/plan.md`. Likely files are planning targets and may be adjusted before work begins, but a task must be split if it would exceed approximately five files or one focused session.
Commands named below are established by Task 4. Before then, verification uses the scaffold's generated commands and read-only contract checks.
## Phase A — Contract and executable foundation
## Task 1: Freeze the merchant API contract
**Description:** Confirm the provider-owned API specification and OpenAPI artifact are approved, versioned, and no longer marked draft before frontend transport code is generated.
**Acceptance criteria:**
- [ ] Backend `API-SPEC.md` and `openapi.yaml` identify an approved matching version.
- [ ] Approved CSV defaults, 30-day analytics/export audit retention, opaque terminal reference, and stable Problem Details base URI are recorded by the provider.
- [ ] A checksum or immutable commit hash is recorded for frontend generation.
**Verification:**
- [ ] Validate OpenAPI 3.1 with the provider's contract command.
- [ ] Manually compare approved operations/schemas with `tasks/plan.md` Gate A.
**Dependencies:** None
**Files likely touched:** External backend contract artifacts; no frontend source files.
**Estimated scope:** XS — external gate
## Task 2: Freeze the static Nginx routing contract
**Description:** Obtain the deployment-owned rules for SPA deep-link fallback, immutable assets, `static/fonts`, and same-origin `/api/v1` HTTP/SSE/CSV proxy behavior.
**Acceptance criteria:**
- [ ] Deep-link fallback never intercepts `/api/v1` or static assets.
- [ ] SSE buffering/compression and CSV streaming headers follow the approved API contract.
- [ ] The target development and production origins are documented without frontend secrets.
**Verification:**
- [ ] Review the deployment contract against SvelteKit `adapter-static` fallback requirements.
- [ ] Record the approved deployment commit/reference in `tasks/plan.md`.
**Dependencies:** Task 1
**Files likely touched:** `tasks/plan.md`; external deployment artifacts.
**Estimated scope:** XS — external gate
## Task 3: Scaffold the pinned SvelteKit project
**Description:** Create the minimal SvelteKit 2/Svelte 5 strict-TypeScript project with npm, Tailwind CSS v4's Vite plugin, and the static adapter using current verified versions.
**Acceptance criteria:**
- [ ] Exact production/dev dependencies and Node/npm requirements are pinned in the lockfile/manifests.
- [ ] Tailwind's Vite plugin precedes SvelteKit and strict TypeScript extends generated SvelteKit config.
- [ ] No server endpoint, database dependency, secret, or placeholder auth token is introduced.
**Verification:**
- [ ] Run dependency install from the lockfile.
- [ ] Run the generated typecheck and production build.
**Dependencies:** Tasks 1–2
**Files likely touched:** `package.json`, `package-lock.json`, `svelte.config.js`, `vite.config.ts`, `tsconfig.json`
**Estimated scope:** M — 5 files
### Checkpoint A1 — Contract and scaffold
- [ ] Tasks 1–3 are complete and reviewed.
- [ ] No draft OpenAPI artifact is consumed by frontend code.
- [ ] The minimal project installs and builds reproducibly.
## Task 4: Establish frontend quality commands
**Description:** Configure deterministic formatting, linting, `svelte-check`, Vitest, and Playwright commands used by every later task.
**Acceptance criteria:**
- [ ] `format:check`, `lint`, `check`, `test:unit`, `test:e2e`, and `build` scripts are documented and executable.
- [ ] Unit/component tests use a browser-like environment appropriate for Svelte components.
- [ ] Playwright has desktop/mobile projects without embedding credentials.
**Verification:**
- [ ] Run every new command against the empty scaffold.
- [ ] Confirm a deliberately failing sample test/check fails, then remove it.
**Dependencies:** Task 3
**Files likely touched:** `package.json`, `eslint.config.js`, `.prettierrc`, `vitest.config.ts`, `playwright.config.ts`
**Estimated scope:** M — 5 files
## Task 5: Configure the static application root
**Description:** Establish the Persian RTL document root, route fallback settings, error boundary, and minimal auth/app route groups without feature UI.
**Acceptance criteria:**
- [ ] Root markup declares `lang="fa" dir="rtl"` and permits browser zoom.
- [ ] Static fallback and trailing-slash behavior match Task 2.
- [ ] `/login` and one protected-shell placeholder deep-link correctly after refresh.
**Verification:**
- [ ] Run `npm run check` and `npm run build`.
- [ ] Serve the build through the target Nginx topology and refresh both routes.
**Dependencies:** Tasks 2–4
**Files likely touched:** `src/app.html`, `src/routes/+layout.svelte`, `src/routes/+layout.ts`, `src/routes/+error.svelte`, `svelte.config.js`
**Estimated scope:** M — 5 files
## Task 6: Generate OpenAPI transport types
**Description:** Add reproducible generation from the approved OpenAPI commit and a drift check that prevents handwritten or stale DTOs.
**Acceptance criteria:**
- [ ] Generated schemas preserve decimal strings, integer Rial values, discriminated section states, Problem Details, and SSE payloads.
- [ ] Generated files carry provenance and are never manually edited.
- [ ] CI/local check fails when approved OpenAPI and generated output differ.
**Verification:**
- [ ] Run generation twice and confirm no diff.
- [ ] Run the contract-drift command against a deliberate schema change, then restore it.
**Dependencies:** Tasks 1, 3–4
**Files likely touched:** `package.json`, `scripts/generate-api.mjs`, `src/lib/api/generated/schema.ts`, `docs/API-CONTRACT.md`
**Estimated scope:** M — 4 files
### Checkpoint A2 — Executable contract foundation
- [ ] Tasks 4–6 pass all configured checks.
- [ ] Static deep links and generated contract drift are proven.
- [ ] Human review confirms no server authority moved into the browser.
## Phase B — Design, transport, and identity
## Task 7: Implement the typed HTTP client boundary
**Description:** Build one same-origin fetch boundary for generated JSON operations, RFC 9457 errors, request ids, CSRF mutations, `Retry-After`, and session termination.
**Acceptance criteria:**
- [ ] UI code can branch on stable status/code without parsing server prose.
- [ ] Cookies use browser credentials policy while auth tokens never enter storage or headers.
- [ ] `401`, safe `404`, `429`, retryable `503`, and validation field errors map to typed results.
**Verification:**
- [ ] Run focused unit tests for success/error/header mappings.
- [ ] Run `npm run check` and inspect logs/storage for sensitive values.
**Dependencies:** Task 6
**Files likely touched:** `src/lib/api/client.ts`, `src/lib/api/problem.ts`, `src/lib/api/client.test.ts`, `src/lib/api/problem.test.ts`
**Estimated scope:** M — 4 files
## Task 8: Implement tokens, font, and pre-paint theme
**Description:** Translate `DESIGN.md` `0.3.2` into global semantic CSS, load the tracked FaNum variable font, and apply system/explicit theme before paint.
**Acceptance criteria:**
- [ ] Components can consume semantic light/dark roles without raw palette values.
- [ ] `IRANYekanXVFaNumVF.woff2` loads from `static/fonts` with the approved fallback and weights.
- [ ] Theme choice persists as presentation-only state with no first-paint flash.
**Verification:**
- [ ] Run build plus focused theme bootstrap tests.
- [ ] Manually inspect first paint in light/dark/system modes and verify the license remains adjacent.
**Dependencies:** Tasks 3–5
**Files likely touched:** `src/app.css`, `src/app.html`, `src/routes/+layout.svelte`, `src/lib/components/ui/ThemeControl.svelte`, `src/lib/components/ui/ThemeControl.test.ts`
**Estimated scope:** M — 5 files
## Task 9: Create contract-safe fixture builders
**Description:** Create synthetic builders for sessions, periods, all run/section states, problems, detail pages, and SSE events without copying source data.
**Acceptance criteria:**
- [ ] Fixtures cover zero, null, empty, unavailable comparison, suppression, failure, rate limit, and replay reset.
- [ ] Builders typecheck against generated schemas and use distinct synthetic merchants.
- [ ] Forbidden payer/credential/peer-row fields are absent and scanned.
**Verification:**
- [ ] Run fixture type tests and forbidden-field scan.
- [ ] Regenerate API types and confirm fixture compilation detects drift.
**Dependencies:** Tasks 6–7
**Files likely touched:** `src/lib/testing/fixtures.ts`, `src/lib/testing/events.ts`, `src/lib/testing/problems.ts`, `src/lib/testing/fixtures.test.ts`
**Estimated scope:** M — 4 files
### Checkpoint B1 — Design and transport primitives
- [ ] Tasks 7–9 pass focused tests and production build.
- [ ] Theme/font work matches `DESIGN.md` without new system decisions.
- [ ] Fixtures contain no sensitive or peer-level source data.
## Task 10: Implement Persian financial formatters
**Description:** Centralize Persian digits, Rial-only money, exact decimal percentages, Jalali/Tehran dates, units, and LTR isolation metadata.
**Acceptance criteria:**
- [ ] Integer Rial/count values and decimal strings format without unintended floating-point changes.
- [ ] Dates use Jalali/`Asia/Tehran`; technical ids remain canonical and bidi-safe.
- [ ] Zero, null, undefined, and unavailable states have distinct typed output.
**Verification:**
- [ ] Run table-driven unit tests for boundary, long, mixed-direction, and negative comparison values.
- [ ] Manually review representative Persian output with the FaNum font.
**Dependencies:** Tasks 8–9
**Files likely touched:** `src/lib/format/number.ts`, `src/lib/format/date.ts`, `src/lib/format/bidi.ts`, `src/lib/format/format.test.ts`
**Estimated scope:** M — 4 files
## Task 11: Deliver the login vertical slice
**Description:** Build the accessible Persian login screen and connect it to `createAuthSession` with generic, throttled, pending, and service-error states.
**Acceptance criteria:**
- [ ] Visible labels, password-manager autocomplete, paste, and generic credential failure match the UX spec.
- [ ] Pending submission prevents duplicates; `429` honors `Retry-After` without a retry loop.
- [ ] Successful login stores only the session summary/CSRF value in memory and navigates to the dashboard.
**Verification:**
- [ ] Run component/integration tests for success, invalid credentials, throttle, and dependency failure.
- [ ] Run keyboard and accessible-name checks at 360 px and desktop.
**Dependencies:** Tasks 7–10
**Files likely touched:** `src/routes/(auth)/login/+page.svelte`, `src/lib/components/auth/LoginForm.svelte`, `src/lib/features/auth/session.svelte.ts`, `src/lib/components/auth/LoginForm.test.ts`, `tests/e2e/login.spec.ts`
**Estimated scope:** M — 5 files
## Task 12: Deliver session restoration and logout
**Description:** Restore authorized session context on refresh, revoke it on logout, and clear merchant/run state on expiry or revocation.
**Acceptance criteria:**
- [ ] Refresh calls `getAuthSession` and renders only the server-returned merchant scope.
- [ ] Logout sends CSRF/origin evidence, clears memory after server revocation, and returns to login.
- [ ] `401` from HTTP or later stream recovery produces the approved generic session-ended flow.
**Verification:**
- [ ] Run focused auth-state tests and Playwright refresh/logout/expiry flows.
- [ ] Inspect storage, URL, and logs for session/CSRF/auth-token leakage.
**Dependencies:** Task 11
**Files likely touched:** `src/lib/features/auth/session.svelte.ts`, `src/routes/(app)/+layout.svelte`, `src/lib/components/auth/LogoutButton.svelte`, `src/lib/features/auth/session.test.ts`, `tests/e2e/session.spec.ts`
**Estimated scope:** M — 5 files
### Checkpoint B2 — Identity slice
- [ ] Tasks 10–12 pass all checks and runtime verification.
- [ ] Two synthetic/demo users remain tenant-isolated.
- [ ] Human review approves Persian login copy and session transitions.
## Phase C — Shell, periods, and partial analytics
## Task 13: Deliver the authenticated app shell
**Description:** Implement the RTL desktop sidebar, tablet/mobile drawer, utility header, skip link, merchant display name, theme control, and active navigation.
**Acceptance criteria:**
- [ ] `merchant.displayName` is identity context, never a selector.
- [ ] Drawer traps/restores focus, closes with Escape/backdrop, and locks background scroll.
- [ ] Navigation order, landmarks, `aria-current`, touch targets, and safe areas match the UX spec.
**Verification:**
- [ ] Run component tests plus Playwright keyboard navigation at 360/768/1024/1440.
- [ ] Run axe-equivalent checks in both themes.
**Dependencies:** Tasks 8, 12
**Files likely touched:** `src/lib/components/layout/AppShell.svelte`, `src/lib/components/layout/Sidebar.svelte`, `src/lib/components/layout/Drawer.svelte`, `src/routes/(app)/+layout.svelte`, `src/lib/components/layout/AppShell.test.ts`
**Estimated scope:** M — 5 files
## Task 14: Deliver reporting-period URL state
**Description:** Render server-allowlisted periods, select the backend default, and synchronize applied period state with navigation/history without client-computed boundaries.
**Acceptance criteria:**
- [ ] Default uses `isDefault`; options show `jalaliLabelFa` and approved types only.
- [ ] Apply/reset and Back/Forward restore valid URL state without fetching on pending edits.
- [ ] Unknown/stale period ids fail safely and never broaden scope.
**Verification:**
- [ ] Run unit/component tests for default, apply, reset, invalid URL, and history restoration.
- [ ] Run Playwright period flow with Persian labels.
**Dependencies:** Tasks 7, 10, 13
**Files likely touched:** `src/lib/features/periods/periods.svelte.ts`, `src/lib/components/analytics/PeriodFilter.svelte`, `src/routes/(app)/dashboard/+page.svelte`, `src/lib/features/periods/periods.test.ts`, `tests/e2e/periods.spec.ts`
**Estimated scope:** M — 5 files
## Task 15: Resolve the SSE transport spike
**Description:** Test native `EventSource` against the approved contract and compare fetch streaming only where typed status/header behavior requires it.
**Acceptance criteria:**
- [ ] The chosen transport proves cookie auth, named heartbeats, replay/reset, cleanup, and one reconnect owner.
- [ ] Handling for connection limits, session end, liveness timeout, and duplicate event ids is documented.
- [ ] No third-party SSE dependency is added without measured need and approval.
**Verification:**
- [ ] Run a focused browser harness against scripted SSE fixtures for disconnect/replay/reset.
- [ ] Record the decision and rejected alternative in `docs/SSE-TRANSPORT.md`.
**Dependencies:** Tasks 1, 7, 9, 12
**Files likely touched:** `src/lib/api/analytics-stream.ts`, `src/lib/api/analytics-stream.test.ts`, `tests/e2e/fixtures/sse.ts`, `tests/e2e/sse-spike.spec.ts`, `docs/SSE-TRANSPORT.md`
**Estimated scope:** M — 5 files
### Checkpoint C1 — Shell, periods, and SSE decision
- [ ] Tasks 13–15 pass responsive, keyboard, and transport tests.
- [ ] Human review approves the SSE decision before run orchestration begins.
- [ ] No reconnect duplication or merchant-scope state survives logout.
## Task 16: Implement the analytics run reducer
**Description:** Create a pure, typed state reducer for run snapshots and all named SSE events, preserving independent ready sections and ignoring duplicates/regressions.
**Acceptance criteria:**
- [ ] All four sections support queued/calculating/ready/failed and peer suppression.
- [ ] Duplicate/replayed/out-of-order events cannot duplicate or erase valid ready results.
- [ ] Overall progress derives from section state without animation dependence.
**Verification:**
- [ ] Run exhaustive reducer tests for every state transition and duplicate event.
- [ ] Run generated-schema typecheck.
**Dependencies:** Tasks 9, 15
**Files likely touched:** `src/lib/features/analytics-run/model.ts`, `src/lib/features/analytics-run/reducer.ts`, `src/lib/features/analytics-run/reducer.test.ts`
**Estimated scope:** M — 3 files
## Task 17: Deliver run start, snapshot, and stream orchestration
**Description:** Connect applied period state to idempotent run creation, current snapshot recovery, the chosen stream, heartbeat watchdog, and authorized teardown.
**Acceptance criteria:**
- [ ] One applied period intent produces a stable idempotency key and no duplicate equivalent starts.
- [ ] Ready snapshot sections render immediately while unfinished siblings stream independently.
- [ ] Replay reset, stream close, period change, logout, and component teardown preserve correct ownership.
**Verification:**
- [ ] Run integration tests for `200`/`202`, replay, reset, period change, and teardown.
- [ ] Run Playwright with different section completion orders.
**Dependencies:** Tasks 14–16
**Files likely touched:** `src/lib/features/analytics-run/controller.svelte.ts`, `src/lib/components/analytics/RunStatus.svelte`, `src/routes/(app)/dashboard/+page.svelte`, `src/lib/features/analytics-run/controller.test.ts`, `tests/e2e/partial-run.spec.ts`
**Estimated scope:** M — 5 files
## Task 18: Deliver the overview vertical slice
**Description:** Render headline KPIs in approved order, exact comparisons, empty/undefined states, provenance, and stable loading/ready layout.
**Acceptance criteria:**
- [ ] Amount, count, success, and verification KPIs use correct semantics, Persian formatting, unit, period, and definitions.
- [ ] Unavailable baseline and undefined denominator never display as zero or trend.
- [ ] Overview becomes useful without waiting for other sections and does not steal focus.
**Verification:**
- [ ] Run component tests across queued/calculating/ready/empty/unavailable/failed fixtures.
- [ ] Run visual checks at four viewports in both themes.
**Dependencies:** Tasks 10, 17
**Files likely touched:** `src/lib/features/overview/OverviewSection.svelte`, `src/lib/components/analytics/MetricCard.svelte`, `src/lib/components/analytics/SectionFrame.svelte`, `src/lib/features/overview/OverviewSection.test.ts`, `src/routes/(app)/dashboard/+page.svelte`
**Estimated scope:** M — 5 files
### Checkpoint C2 — First complete analytics slice
- [ ] Tasks 16–18 pass focused tests, Playwright, check, and build.
- [ ] Idempotent start plus independently ready overview works end to end.
- [ ] Human review approves stable layout and restrained live announcements.
## Task 19: Deliver deterministic overview insights
**Description:** Render action cards only when the server comparison and approved evidence thresholds make the insight eligible.
**Acceptance criteria:**
- [ ] Insight copy includes observation, exact evidence, relevant sessions, possible action, and limitation.
- [ ] Below-threshold, zero-baseline, missing, or undefined comparisons never create action claims.
- [ ] Language remains observational and uses correct Persian percentage-point terminology.
**Verification:**
- [ ] Run table-driven component tests at 99/100 sessions and threshold boundaries.
- [ ] Manually review all Persian insight variants for causality and نیم‌فاصله.
**Dependencies:** Task 18
**Files likely touched:** `src/lib/features/overview/InsightCard.svelte`, `src/lib/features/overview/insights.ts`, `src/lib/features/overview/InsightCard.test.ts`
**Estimated scope:** M — 3 files
## Task 20: Deliver payment-performance outcomes and retry
**Description:** Render final outcomes, verification gap, observed stages, retry sessions, and recovery rate without misclassifying `Paid`, `NoAttempt`, or `InBank`.
**Acceptance criteria:**
- [ ] `Paid` and `Verified` are bank-paid while only `Verified` is finalized.
- [ ] Stage and retry values use session grain, exact denominators, and approved safe language.
- [ ] Chart/table alternatives expose the same labeled values without color-only meaning.
**Verification:**
- [ ] Run component tests for every status/stage and undefined retry rate.
- [ ] Run keyboard/table-equivalence and both-theme checks.
**Dependencies:** Tasks 17–18
**Files likely touched:** `src/lib/features/payment-performance/OutcomeSummary.svelte`, `src/lib/features/payment-performance/RetrySummary.svelte`, `src/lib/components/analytics/AccessibleChart.svelte`, `src/lib/features/payment-performance/payment-performance.test.ts`, `src/routes/(app)/payments/+page.svelte`
**Estimated scope:** M — 5 files
## Task 21: Deliver processing-time analysis
**Description:** Render init/verify p50 and p95 with sample and non-null coverage using an accessible paired visualization and table.
**Acceptance criteria:**
- [ ] Missing timing remains unavailable, never zero.
- [ ] Milliseconds are primary and readable seconds may only supplement them.
- [ ] Exact p50/p95/sample/coverage is available without hover or pointer precision.
**Verification:**
- [ ] Run component tests for null, zero, sparse, and full-coverage fixtures.
- [ ] Verify chart/table equivalence, Persian digits, and mobile height.
**Dependencies:** Tasks 10, 20
**Files likely touched:** `src/lib/features/payment-performance/TimingSummary.svelte`, `src/lib/features/payment-performance/TimingChart.svelte`, `src/lib/features/payment-performance/TimingSummary.test.ts`
**Estimated scope:** M — 3 files
### Checkpoint C3 — Payment performance
- [ ] Tasks 19–21 pass metric-semantic and accessibility checks.
- [ ] No actionable claim appears below approved thresholds.
- [ ] Human review confirms status/stage copy does not invent causes.
## Task 22: Deliver the fees vertical slice
**Description:** Render real session-grain paid fees, paid amount denominator, fee rate, comparison, and accessible trend/table in Rial only.
**Acceptance criteria:**
- [ ] Fee totals are labeled real merchant fees and never multiplied by attempts.
- [ ] Rial and percentage never share an ambiguous axis; undefined fee rate is explicit.
- [ ] Period, denominator, comparison, definition version, and calculation time are visible.
**Verification:**
- [ ] Run tests with duplicate attempts, zero denominator, unavailable baseline, and large Rial amounts.
- [ ] Run responsive/light/dark chart-table review.
**Dependencies:** Tasks 17–18
**Files likely touched:** `src/lib/features/fees/FeesSection.svelte`, `src/lib/features/fees/FeesChart.svelte`, `src/lib/features/fees/FeesSection.test.ts`, `src/routes/(app)/fees/+page.svelte`
**Estimated scope:** M — 4 files
## Task 23: Deliver the peer-comparison vertical slice
**Description:** Render approved merchant-weighted medians and direction-aware percentiles or the privacy-safe suppressed state.
**Acceptance criteria:**
- [ ] Higher displayed percentile always means better, with lower-is-better metrics explained.
- [ ] Suppression exposes no peer values/rows/identities and does not hide merchant analytics.
- [ ] Chart/table/labels cannot imply an individual peer distribution or rank.
**Verification:**
- [ ] Run ready/suppressed boundary fixtures and sensitive-field absence tests.
- [ ] Run accessible-name, keyboard, both-theme, and mobile checks.
**Dependencies:** Tasks 17–18
**Files likely touched:** `src/lib/features/peer-comparison/PeerSection.svelte`, `src/lib/features/peer-comparison/PeerMetric.svelte`, `src/lib/features/peer-comparison/PeerSection.test.ts`, `src/routes/(app)/peers/+page.svelte`
**Estimated scope:** M — 4 files
## Task 24: Deliver failure, retry, and recovery integration
**Description:** Integrate section-local failure/manual retry, rate limits, heartbeat loss, replay/reset, and overall status across all analytics pages.
**Acceptance criteria:**
- [ ] Manual retry targets one exhausted failed section and preserves ready siblings.
- [ ] `Retry-After` and connection recovery never create a tight loop or competing announcements.
- [ ] Heartbeats are silent while meaningful progress/recovery uses one restrained live region.
**Verification:**
- [ ] Run integration/Playwright tests for mixed terminal states, retry conflicts, `429`, disconnect, and reset.
- [ ] Screen-reader check confirms no heartbeat/countdown announcement spam.
**Dependencies:** Tasks 19–23
**Files likely touched:** `src/lib/features/analytics-run/controller.svelte.ts`, `src/lib/components/analytics/SectionError.svelte`, `src/lib/components/analytics/RunStatus.svelte`, `src/lib/features/analytics-run/recovery.test.ts`, `tests/e2e/recovery.spec.ts`
**Estimated scope:** M — 5 files
### Checkpoint C4 — Complete partial analytics
- [ ] Tasks 22–24 pass all section-state and recovery scenarios.
- [ ] All four sections are independently useful in any completion order.
- [ ] Human review approves charts/tables, suppression, rate-limit, and recovery UX.
## Phase D — Merchant-owned evidence and CSV
## Task 25: Implement the cursor-detail client and table foundation
**Description:** Build typed detail queries, opaque-cursor URL state, server pagination, semantic desktop table, and mobile priority-row disclosure.
**Acceptance criteria:**
- [ ] View/period/allowlisted filters come from URL while cursor changes cannot broaden scope.
- [ ] Page size follows the contract and no browser-side total/fake pagination is invented.
- [ ] Table captions, headers, row disclosures, sort/order statement, and LTR ids are accessible.
**Verification:**
- [ ] Run integration tests for next cursor, invalid cursor, filter change, empty, and `404`.
- [ ] Run 320/360 px reflow plus keyboard/screen-reader table checks.
**Dependencies:** Tasks 10, 13–14, 24
**Files likely touched:** `src/lib/features/session-details/client.ts`, `src/lib/features/session-details/state.svelte.ts`, `src/lib/components/details/DetailTable.svelte`, `src/lib/components/details/DetailRow.svelte`, `src/lib/features/session-details/details.test.ts`
**Estimated scope:** M — 5 files
## Task 26: Deliver the unverified-paid detail view
**Description:** Provide read-only merchant-owned `Paid` evidence with accurate bank-paid/unverified language and empty/error states.
**Acceptance criteria:**
- [ ] Only the approved `UNVERIFIED_PAID` view/fields are requested and rendered.
- [ ] `Paid` is never styled or announced as failure.
- [ ] Period, result context, amounts in Rial, ids, attempts, and export eligibility are explicit.
**Verification:**
- [ ] Run focused route/component tests for rows, empty, cursor, and session expiry.
- [ ] Reconcile fixture rows with the unverified aggregate.
**Dependencies:** Task 25
**Files likely touched:** `src/routes/(app)/payments/unverified/+page.svelte`, `src/lib/features/session-details/UnverifiedPaidView.svelte`, `src/lib/features/session-details/UnverifiedPaidView.test.ts`
**Estimated scope:** M — 3 files
## Task 27: Deliver the failed-session detail view
**Description:** Provide read-only failed-session evidence with allowlisted observed-stage filters and no invented bank/PSP causes.
**Acceptance criteria:**
- [ ] Only `NO_ATTEMPT`, `REACHED_BANK`, and `OTHER_OBSERVED` filters are available.
- [ ] `NoAttempt` and `InBank` copy preserves approved observed-stage meaning.
- [ ] Filter/cursor manipulation returns safe typed errors without cross-tenant hints.
**Verification:**
- [ ] Run focused tests for each stage, empty, invalid cursor/filter, and safe `404`.
- [ ] Manually review Persian stage copy against the metric catalogue.
**Dependencies:** Task 25
**Files likely touched:** `src/routes/(app)/payments/failed/+page.svelte`, `src/lib/features/session-details/FailedView.svelte`, `src/lib/components/details/FailureStageFilter.svelte`, `src/lib/features/session-details/FailedView.test.ts`
**Estimated scope:** M — 4 files
### Checkpoint D1 — First detail views
- [ ] Tasks 25–27 pass cursor, responsive-table, and privacy checks.
- [ ] Aggregates remain reconciliation source; no unbounded client count query exists.
- [ ] Human review confirms row priority and observed-stage language.
## Task 28: Deliver the retried-session detail view
**Description:** Provide read-only retried-session evidence with bounded ordered attempt summaries and eventual payment outcome.
**Acceptance criteria:**
- [ ] Attempt sequences are ordered, bounded, and never depend on source row order.
- [ ] Payer tokens, response codes, and undocumented causes remain absent.
- [ ] `Paid` or `Verified` eventual recovery is represented accurately.
**Verification:**
- [ ] Run tests for multiple attempts, long bounded history, null timing, and recovered/unrecovered outcomes.
- [ ] Reconcile fixture rows with retry aggregates.
**Dependencies:** Task 25
**Files likely touched:** `src/routes/(app)/payments/retried/+page.svelte`, `src/lib/features/session-details/RetriedView.svelte`, `src/lib/components/details/AttemptHistory.svelte`, `src/lib/features/session-details/RetriedView.test.ts`
**Estimated scope:** M — 4 files
## Task 29: Resolve synchronous CSV delivery behavior
**Description:** Measure and document direct navigation versus authenticated fetch/Blob at the approved cap, including typed errors and interrupted streams.
**Acceptance criteria:**
- [ ] Selected approach handles `413`, `429`, `504`, session expiry, and pre-byte failures truthfully.
- [ ] Memory/mobile behavior is measured at representative and maximum approved sizes.
- [ ] UX “requesting/downloading/failed” copy is amended if separate generating/ready states are not observable.
**Verification:**
- [ ] Run browser tests against success, Problem Details, and interrupted CSV fixtures.
- [ ] Record the decision and measurements in `docs/CSV-DELIVERY.md` before export UI work.
**Dependencies:** Tasks 1, 7, 25
**Files likely touched:** `src/lib/features/export/csv-spike.ts`, `src/lib/features/export/csv-spike.test.ts`, `tests/e2e/csv-spike.spec.ts`, `docs/CSV-DELIVERY.md`, `docs/DASHBOARD-UX-SPEC.md`
**Estimated scope:** M — 5 files
## Task 30: Deliver the authorized CSV export slice
**Description:** Add scope preflight and server-owned synchronous CSV download to the three eligible detail views using the Task 29 decision.
**Acceptance criteria:**
- [ ] Preflight states merchant display name, view, period, filters, Rial unit, and sensitive-field exclusion.
- [ ] Export always reauthorizes the server endpoint and never assembles hidden browser rows.
- [ ] Empty, requesting/downloading, rate-limited, too-large, timeout, interrupted, and session-ended states are distinct.
**Verification:**
- [ ] Run component/Playwright tests for all three views and every typed export outcome.
- [ ] Scan downloaded fixtures for BOM/header/timestamp/Rial policy and forbidden fields/formulas.
**Dependencies:** Tasks 26–29
**Files likely touched:** `src/lib/features/export/ExportDialog.svelte`, `src/lib/features/export/download.ts`, `src/lib/features/export/ExportDialog.test.ts`, `tests/e2e/export.spec.ts`, `src/lib/components/details/DetailTable.svelte`
**Estimated scope:** M — 5 files
### Checkpoint D2 — Evidence and export
- [ ] Tasks 28–30 pass reconciliation, cap/error, interruption, and privacy checks.
- [ ] Finance/legal handoff copy and synchronous behavior receive human approval.
- [ ] No payer token, peer row, credential, or other-merchant value reaches DOM/download/logs.
## Phase E — Completion and hardening
## Task 31: Deliver methodology and account screens
**Description:** Implement metric/period/lifecycle/coverage/peer/insight explanations plus account identity, theme, logout, and demo merchant-switch guidance.
**Acceptance criteria:**
- [ ] Definitions are linkable, versioned, keyboard reachable, and consistent with approved contracts.
- [ ] Account uses `merchant.displayName` and explains switching only by logout/new login.
- [ ] No profile editing, roles, registration, recovery, peer detail, or AI claims appear.
**Verification:**
- [ ] Run route/component tests and broken-anchor checks.
- [ ] Manually proofread Persian copy and mixed-direction identifiers.
**Dependencies:** Tasks 12–14, 19–24
**Files likely touched:** `src/routes/(app)/methodology/+page.svelte`, `src/lib/features/methodology/MetricDefinitions.svelte`, `src/routes/(app)/account/+page.svelte`, `src/lib/features/methodology/MetricDefinitions.test.ts`
**Estimated scope:** M — 4 files
## Task 32: Harden shell responsiveness and themes
**Description:** Complete shell/header/navigation/filter responsiveness, long Persian content handling, safe areas, focus visibility, and semantic dark-mode states.
**Acceptance criteria:**
- [ ] Shell/filter/navigation work at 360/768/1024/1440 and 320 CSS px reflow.
- [ ] Light/dark cover focus, hover, pressed, disabled, skeleton, scrim, status, and native controls.
- [ ] No sticky/fixed UI obscures focus or content.
**Verification:**
- [ ] Run responsive Playwright screenshots/interactions in both themes.
- [ ] Manually test 200% zoom, long merchant names, keyboard drawer, and reduced motion.
**Dependencies:** Tasks 13–14, 31
**Files likely touched:** `src/lib/components/layout/AppShell.svelte`, `src/lib/components/layout/Drawer.svelte`, `src/lib/components/analytics/PeriodFilter.svelte`, `src/app.css`, `tests/e2e/responsive-shell.spec.ts`
**Estimated scope:** M — 5 files
## Task 33: Harden analytics and detail responsiveness
**Description:** Complete KPI/chart/table/detail/export layout behavior, stable async footprints, content overflow, and mobile disclosure patterns.
**Acceptance criteria:**
- [ ] Section completion order causes no material layout shift or focus movement.
- [ ] Charts remain at least 240 px with exact value/table first-class alternatives.
- [ ] Detail/export tasks remain usable at 320 CSS px without hidden critical fields/actions.
**Verification:**
- [ ] Run visual regression and interaction checks across all routes/viewports/themes.
- [ ] Manually test long ids, maximum formatted values, empty/error/suppressed states.
**Dependencies:** Tasks 18–30
**Files likely touched:** `src/lib/components/analytics/SectionFrame.svelte`, `src/lib/components/analytics/AccessibleChart.svelte`, `src/lib/components/details/DetailTable.svelte`, `src/lib/features/export/ExportDialog.svelte`, `tests/e2e/responsive-data.spec.ts`
**Estimated scope:** M — 5 files
### Checkpoint E1 — Complete responsive product
- [ ] Tasks 31–33 pass all route, viewport, theme, and copy checks.
- [ ] No new design-system decision was introduced without `DESIGN.md` changelog.
- [ ] Human review approves the complete visual/interaction hierarchy.
## Task 34: Complete accessibility verification
**Description:** Close WCAG 2.2 AA gaps across authentication, shell, filters, async statuses, charts, tables, dialogs, and errors.
**Acceptance criteria:**
- [ ] Critical flows are keyboard complete with visible/restored/unobscured focus.
- [ ] Screen readers receive headings, labels, chart tables, associated errors, and restrained status messages.
- [ ] Automated checks have no serious/critical violations in both themes.
**Verification:**
- [ ] Run the full accessibility Playwright suite at acceptance viewports.
- [ ] Perform manual keyboard, screen-reader, 200% zoom/reflow, and reduced-motion checks.
**Dependencies:** Tasks 30–33
**Files likely touched:** `tests/e2e/accessibility.spec.ts`, `tests/e2e/keyboard.spec.ts`, `docs/ACCESSIBILITY-REPORT.md`, plus at most two focused defect files per implementation increment.
**Estimated scope:** M — split fixes into separate tasks if more than 5 files
## Task 35: Complete security and privacy negative tests
**Description:** Verify frontend behavior under manipulated ids/cursors/filters/events, session changes, hostile CSV/text content, and sensitive-field attempts.
**Acceptance criteria:**
- [ ] Cross-tenant/absent resources remain indistinguishable and clear no valid sibling data unexpectedly.
- [ ] Payer tokens, peer rows, cookies, CSRF/auth values, credentials, and internal keys never reach DOM/storage/URL/log/download.
- [ ] CSV formula prefixes and hostile bidi/long content remain safely presented.
**Verification:**
- [ ] Run security-focused unit/integration/Playwright tests and forbidden-field scans.
- [ ] Inspect browser storage/network/log artifacts for both demo merchants.
**Dependencies:** Tasks 24–34
**Files likely touched:** `tests/e2e/security.spec.ts`, `src/lib/testing/forbidden-fields.ts`, `src/lib/testing/forbidden-fields.test.ts`, `docs/SECURITY-VERIFICATION.md`
**Estimated scope:** M — 4 files
## Task 36: Verify the production static artifact
**Description:** Build the release candidate and exercise it behind the approved Nginx config with real proxy semantics for HTTP, SSE, CSV, fonts, and deep links.
**Acceptance criteria:**
- [ ] Lockfile install and all quality commands pass from a clean checkout.
- [ ] Deep-link refresh, immutable assets/font, `/api/v1`, SSE replay, and CSV download work through Nginx.
- [ ] No source map, env value, credential, generated secret, or unintended artifact is shipped.
**Verification:**
- [ ] Run the complete CI-equivalent command sequence and target-topology Playwright suite.
- [ ] Inspect build contents, response headers, caching, compression, and fallback routing.
**Dependencies:** Tasks 2, 34–35
**Files likely touched:** `tests/e2e/production.spec.ts`, `docs/PRODUCTION-VERIFICATION.md`, and up to three focused config/test files if defects are found.
**Estimated scope:** M — split defects if needed
### Checkpoint E2 — Release candidate
- [ ] Tasks 34–36 and the full Definition of Done pass.
- [ ] Product, accessibility, security, finance/legal export, and deployment evidence are reviewed.
- [ ] No deployment or release occurs without separate authorization.
## Task 37: Finalize implementation documentation
**Description:** Reconcile README, specs, plan, completed checklist, commands, source structure, transport decisions, and verification reports with the implemented state.
**Acceptance criteria:**
- [ ] Documentation describes current behavior and exact commands without stale draft assumptions.
- [ ] Durable SSE/CSV/chart/static decisions are linked and surprising decisions receive ADRs where required.
- [ ] Completed tasks and remaining limitations are accurate; no secret or private operational value is documented.
**Verification:**
- [ ] Run markdown/link/diff checks and compare every acceptance criterion with evidence.
- [ ] Obtain final human review before merge/release handoff.
**Dependencies:** Task 36
**Files likely touched:** `README.md`, `docs/DASHBOARD-SPEC.md`, `docs/DASHBOARD-UX-SPEC.md`, `tasks/plan.md`, `tasks/todo.md`
**Estimated scope:** M — 5 files
## Final implementation gate
- [ ] Human approves this Phase 3 task list.
- [ ] Tasks 1–2 are complete before Task 3 begins.
- [ ] Implementation proceeds one task at a time with tests first where behavior/logic changes.
- [ ] Every completed increment is verified and committed atomically without pushing unless separately requested.