# Approved Amendment: Routed ZarinPal Merchant Experience - Status: Approved by the user on 2026-08-20 - Delivery branch: `feature/zarinpal-dashboard-redesign` - Mode: Operate ## Objective Replace the single long dashboard with a recognizable ZarinPal-style merchant shell and routed analytics experience backed by the real local dataset. ## Direction contract - **World:** crisp ZarinPal merchant console—white working surfaces, compact outlined controls, restrained radii, quiet gray canvas, blue active states, and a small yellow brand accent. - **First viewport:** a useful overview, not a wall of KPIs: a plain-language finding, payment-flow chart with inspectable points, four key outcomes, and recent transactions. - **Navigation:** persistent top utility bar plus a right sidebar that collapses to icons on desktop and becomes an accessible drawer on mobile. - **Signature interaction:** terminal and period changes update the URL and recompose the payment-flow visualization; chart points reveal exact values on hover and keyboard focus. - **Cross-surface reach:** the same filter bar, table language, metric help, statuses, spacing, and motion apply on overview, transactions, payment performance, fees, peers, and methodology pages. - **Honest risk:** dense financial data can become visually noisy. The implementation leads with one written takeaway per section, keeps exact evidence nearby, and moves full tables to their own routes. ## API additions - `GET /api/v1/analytics/terminals` lists only terminals belonging to the authenticated merchant. - `POST /api/v1/analytics/runs` accepts an optional tenant-validated `terminalId`. - Overview data adds a bounded daily payment-history series for the selected period and terminal. - `GET /api/v1/analytics/session-details` adds `ALL`, status, and amount bounds while preserving cursor pagination and merchant scope. - `GET /api/v1/analytics/sessions/{sessionId}` returns one merchant-owned session and its ordered attempt history, or the same safe `404` used for absent resources. ## Routes and URL state Authenticated routes are `/dashboard`, `/transactions`, `/transactions/[sessionId]`, `/payments`, `/fees`, `/peers`, and `/methodology`. Every analytical page uses: - `range=day|week|month|season` - `terminal=all|` The transactions page additionally uses optional `status`, `minAmount`, and `maxAmount` parameters. Invalid values fall back safely and are never sent as authorization inputs. ## Acceptance criteria - The supplied logo is visually cropped to its light/dark wordmark variant in the top bar without displaying the source sheet. - Sidebar labels disappear when collapsed; icons are unwrapped and neutral except for the active item, which uses blue icon/text plus a subtle active surface. - Each sidebar section is a real SvelteKit route and deep-link refresh works through the existing static fallback. - Daily, weekly, monthly, and seasonal choices are visible on every analytical route and copied URLs restore the view. - Terminal selection changes merchant-owned aggregates and detail rows. - The overview chart exposes exact daily amount/count through pointer and keyboard interaction and includes a textual summary. - Tables use status/date/amount filters, readable rows, and transaction links; no search field is present. - Transaction detail shows the session facts and ordered attempt history without payer tokens or invented failure causes. - Important metrics have a keyboard-reachable formula tooltip. - Peer messaging uses factual, supportive Persian and never reveals peer identities or rows. - Motion is functional, bounded to 120–220 ms, and disabled by `prefers-reduced-motion`. - The feature runs beside the current local instance and is not merged without explicit user confirmation. ## Verification - Backend: `go test ./...`, `go vet ./...`, focused authenticated HTTP smoke tests. - Frontend: `npm test`, `npm run check`, `npm run build`. - Browser: login, terminal switch, all routes, URL-restored filters, chart hover/focus, transaction drill-down, sidebar collapse, mobile drawer, console/network errors, and desktop/mobile screenshots.