4.1 KiB
4.1 KiB
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/terminalslists only terminals belonging to the authenticated merchant.POST /api/v1/analytics/runsaccepts an optional tenant-validatedterminalId.- Overview data adds a bounded daily payment-history series for the selected period and terminal.
GET /api/v1/analytics/session-detailsaddsALL, 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 safe404used 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|seasonterminal=all|<opaque-terminal-id>
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.