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

38 KiB
Raw Blame History

Phase 3 Task List — Merchant Analytics Dashboard

  • Status: Draft for human review
  • SDD phase: 3 — Tasks
  • Source plan: 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.