Files
zarinpal-analytics-frontend/tasks/todo.md

39 KiB
Raw Blame History

Phase 3 Task List — Merchant Analytics Dashboard

  • Status: Approved task list — implementation explicitly paused
  • SDD phase: 3 — Tasks approved; Phase 4 not authorized
  • Source plan: plan.md
  • Implementation authorization: Not granted
  • Approved by user: 2026-08-20
  • 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.

Approval of this task list closes the SDD Phase 3 review gate only. It does not authorize starting any task, scaffolding the application, installing dependencies, editing application code, or otherwise entering Phase 4. Implementation begins only after a separate explicit user instruction.

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.