diff --git a/DESIGN.md b/DESIGN.md index d572256..5d13295 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,7 +1,7 @@ # Design System — ZarinPal Merchant Analytics - Status: Approved baseline — implementation authorized 2026-08-20 -- Version: 0.3.3 +- Version: 0.4.0 - Last updated: 2026-08-20 - Direction: Persian-first RTL @@ -79,8 +79,8 @@ Light and dark modes are first-class variants of the same semantic token system. - Base spacing unit: 4 px; common sequence `4, 8, 12, 16, 24, 32, 48, 64`. - Control height: 40 px desktop; interactive touch target at least 44×44 px on touch layouts. -- Card radius: 12 px for dense dashboard cards; 16–20 px for feature/empty-state surfaces. -- Button/input radius: 8–10 px; pill radius only for compact statuses and segmented controls. +- Card radius: 8 px for dense dashboard cards and tables; 12 px only for spacious explanatory or empty-state surfaces. +- Button/input radius: 6–8 px; pill radius only for compact statuses and segmented controls. - Card border is preferred over shadow. Default elevation is subtle (`0 1px 3px rgb(25 25 26 / 0.08)`); overlays may use stronger elevation. - Content width is bounded for scanning; tables/charts may use the full available dashboard column. @@ -88,8 +88,8 @@ Light and dark modes are first-class variants of the same semantic token system. ### Desktop (≥ 1024 px) -- Fixed right sidebar, approximately 248–272 px wide. -- Top utility bar remains visually quiet. +- Fixed right sidebar, 256 px expanded and 72 px collapsed, with icon-only collapse matching the supplied panel reference. +- A 56 px top utility bar spans the viewport and carries the supplied ZarinPal wordmark, sidebar trigger, theme, notification, and account actions. - Main content uses a centered, fluid container with 24–32 px gutters. - Overview uses a 12-column grid. Primary analytics get 8 columns; secondary summaries get 4 where useful. - Do not create large empty regions merely to mimic the reference screenshot; use the density required by real content. @@ -109,15 +109,16 @@ Light and dark modes are first-class variants of the same semantic token system. ## Navigation and information architecture -Initial authenticated routes: +Authenticated routes: 1. ورود (login) -2. پیشخوان (overview) -3. عملکرد پرداخت (success, retries, failures, timing) -4. کارمزد و درآمد (real merchant fee amounts and rates in Rial) -5. مقایسه با هم‌گروه‌ها (anonymized category/cohort benchmark) -6. کیفیت داده / درباره شاخص‌ها (definitions, freshness, limitations) -7. حساب کاربری / خروج +2. پیشخوان (`/dashboard`) +3. تراکنش‌ها (`/transactions` and `/transactions/[sessionId]`) +4. عملکرد پرداخت (`/payments`) +5. کارمزد و درآمد (`/fees`) +6. مقایسه با هم‌گروه‌ها (`/peers`) +7. کیفیت داده / درباره شاخص‌ها (`/methodology`) +8. حساب کاربری / خروج Navigation labels should describe merchant tasks, not internal database concepts. Active location is conveyed by color plus a bar/background and `aria-current`. @@ -184,6 +185,7 @@ Navigation labels should describe merchant tasks, not internal database concepts | Version | Date | Decision | |---|---|---| +| 0.4.0 | 2026-08-20 | Adopted the supplied current ZarinPal panel as the closer interaction reference: added the top wordmark bar, 256/72 px collapsible right sidebar, less-rounded 8 px data surfaces, routed sections, URL-backed period/terminal filters, payment-history chart, filtered transaction table, routed attempt history, formula help, and supportive human-readable insights. | | 0.3.3 | 2026-08-20 | Replaced merchant/cohort revision freshness language with the approved immutable completed-import dataset snapshot. This changes trace labels only; cache age still does not imply stale data. | | 0.3.2 | 2026-08-20 | Made the licensed Iran Yekan X FaNum variable WOFF2 and its required license file Git-tracked frontend assets, eliminating a separate private build-injection path. | | 0.3.1 | 2026-08-20 | Verified the purchased Iran Yekan X Professional FaNum variable assets and required a private, reproducible injection path for public repositories. Added merchant-owned detail CSV export as an MVP component contract. | diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..3c9d4e3 --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,62 @@ +# Product + + + +## Platform + +web + +## Users + +ZarinPal merchants and the teams responsible for monitoring their payment gateways. A merchant may own multiple terminals and needs to understand both the selected terminal and the merchant-wide picture without reading raw analytical output. + +## Product Purpose + +Turn imported payment-session data into a Persian-first dashboard that helps a merchant understand payment flow, diagnose failed or retried transactions, follow fees, and compare performance with a privacy-safe cohort. Success means a merchant can sign in, select a terminal and reporting window, understand the result in plain language, and open the evidence behind it. + +## Positioning + +The product joins ZarinPal's familiar merchant-panel interaction model with session-grain payment analytics, attempt history, transparent formulas, and privacy-preserving peer context. + +## Operating Context + +- Authenticated desktop and mobile web dashboard used repeatedly during merchant operations. +- PostgreSQL is the authority for the imported immutable dataset; the Go API owns authentication, tenant scope, and metrics. +- Reporting is filtered by daily, Iranian weekly, Jalali-monthly, and Persian-season windows. +- A merchant may switch among their own payment terminals. The active period and terminal remain in the URL so a view can be copied and revisited. + +## Capabilities and Constraints + +- Separate routed pages cover the overview, transactions, payment performance, fees, peer comparison, and methodology. +- Transaction rows open a routed detail view with the ordered history of attempts. +- Tables provide status, date-window, and amount-range filters without free-text search. +- Important metrics expose formulas and safe denominators without revealing payer identifiers or peer rows. +- Human-readable insights summarize performance with encouraging, factual language. They never fabricate causes or reveal another merchant's data. +- The frontend is SvelteKit 2, Svelte 5, strict TypeScript, and Tailwind CSS v4; the backend remains Go and PostgreSQL. +- The feature is previewed on an isolated local instance and is not merged without explicit user confirmation. + +## Brand Commitments + +- Product name and supplied ZarinPal wordmark remain recognizable. +- The supplied current ZarinPal panel screenshots are the binding interaction and density reference. +- ZarinPal blue is the principal action and active-navigation color; yellow is a small brand accent. +- Persian is the primary product language and the interface is RTL. + +## Evidence on Hand + +- Supplied ZarinPal panel screenshots showing the top utility bar, expanded/collapsed right sidebar, terminal selector, chart, filtered tables, and transaction detail layout. +- Supplied logo sheet at `../(challenge)/zarinpal-logo.jpg`. +- Imported local payment dataset with merchant, terminal, session, and attempt records. +- Existing approved analytics, identity, privacy, and data-quality specifications in the frontend and backend repositories. + +## Product Principles + +1. Explain the result before exposing the raw detail. +2. Keep every number traceable to a formula, period, unit, and merchant-owned record. +3. Preserve the fast scan patterns merchants already recognize from ZarinPal. +4. Make terminal scope and time scope obvious and shareable. +5. Encourage improvement without shaming or overstating causality. + +## Accessibility & Inclusion + +Target WCAG 2.2 AA. Navigation, filters, chart values, tooltips, terminal selection, tables, and transaction history must remain keyboard-operable and understandable without relying on color or pointer hover. diff --git a/docs/ZARINPAL-REDESIGN-AMENDMENT.md b/docs/ZARINPAL-REDESIGN-AMENDMENT.md new file mode 100644 index 0000000..1956232 --- /dev/null +++ b/docs/ZARINPAL-REDESIGN-AMENDMENT.md @@ -0,0 +1,58 @@ +# 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. diff --git a/tasks/plan.md b/tasks/plan.md index 7a96c88..3bd3c2b 100644 --- a/tasks/plan.md +++ b/tasks/plan.md @@ -453,3 +453,17 @@ Resolved external contracts: the production Problem Details base URI is owned by - [Playwright installation and test runner](https://playwright.dev/docs/intro) - [WCAG 2.2](https://www.w3.org/TR/WCAG22/) - [WHATWG server-sent events](https://html.spec.whatwg.org/multipage/server-sent-events.html) + +## 17. Approved feature-branch redesign delivery + +The user approved `docs/ZARINPAL-REDESIGN-AMENDMENT.md` on 2026-08-20 and required the work to remain on `feature/zarinpal-dashboard-redesign` until a separately running preview is reviewed. + +Build order: + +1. Extend the backend contract for four latest complete period windows, terminal-scoped runs, payment history, and routed transaction evidence. +2. Generate the TypeScript contract and add shadcn-svelte/Lucide foundations. +3. Replace the single-page dashboard with the shared routed shell and URL-backed controls. +4. Deliver overview, transaction, performance, fee, peer, methodology, and detail routes as thin vertical slices. +5. Verify the isolated feature instance on alternate ports, then wait for explicit merge approval. + +The current instance remains untouched while the feature preview uses API port `8081` and frontend port `5174`. diff --git a/tasks/todo.md b/tasks/todo.md index 0db4844..b7e4241 100644 --- a/tasks/todo.md +++ b/tasks/todo.md @@ -804,3 +804,25 @@ Commands named below are established by Task 4. Before then, verification uses t - [ ] 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. + +## Approved redesign increment — 2026-08-20 + +- [ ] Task 38: Add the shadcn-svelte/Lucide foundation and ZarinPal design tokens. + - Acceptance: generated local UI primitives, cropped logo treatment, 8 px data surfaces, and semantic blue/yellow tokens pass `npm run check`. + - Verify: focused component tests plus `npm run check`. +- [ ] Task 39: Deliver the persistent top bar, right collapsible sidebar, mobile drawer, terminal selector, and URL-backed period control. + - Acceptance: active icons alone are blue, desktop collapses to icons, and copied URLs restore range/terminal. + - Verify: shell tests plus keyboard and responsive browser checks. +- [ ] Task 40: Deliver `/dashboard` with supportive insight copy, formula help, payment-history chart, and recent transactions. + - Acceptance: chart points are hover/focus inspectable and exact values remain available in text. + - Verify: transformation tests and browser chart interaction. +- [ ] Task 41: Deliver `/transactions` and `/transactions/[sessionId]`. + - Acceptance: status/date/amount filters are URL-backed, rows are links, and attempt history is ordered and sensitive-field free. + - Verify: filter tests and authenticated drill-down smoke. +- [ ] Task 42: Deliver `/payments`, `/fees`, `/peers`, and `/methodology` with one written takeaway and meaningful Lucide icons per surface. + - Acceptance: every route handles ready/empty/error states and important formulas are keyboard reachable. + - Verify: route tests, `npm test`, `npm run check`, and `npm run build`. +- [ ] Task 43: Run the isolated feature preview and collect desktop/mobile evidence. + - Acceptance: login and critical journeys work at `http://127.0.0.1:5174` against API `8081` with no console/network errors. + - Verify: real-browser login, route, filter, terminal, collapse, and detail checks. +- [ ] Checkpoint R1: Commit all verified increments on `feature/zarinpal-dashboard-redesign` and wait for explicit user confirmation before merge.