E2E retail roadmap and checklist
Document control
Section titled “Document control”| Version | Date (UTC) | Notes |
|---|---|---|
| 1.0.0 | 2026-05-21 | Initial roadmap: P0/P1/P2 screen checklist, phased work packages, links to existing specs. Implementation schedule: TBD (owner fills dates when planning). |
Owner / scheduling: Add a row below when you commit to a phase (start date, target exit, responsible).
| Phase | Planned start | Target exit | Owner | Status |
|---|---|---|---|---|
| Phase 0 — Foundation | TBD | TBD | TBD | Not started |
| Phase 1 — P0 POS & orders | TBD | TBD | TBD | Not started |
| Phase 2 — P0 inventory & catalog | TBD | TBD | TBD | Not started |
| Phase 3 — Admin P0 | TBD | TBD | TBD | Not started |
| Phase 4 — P1 expansion | TBD | TBD | TBD | Not started |
| Phase 5 — P2 & maintenance | TBD | TBD | TBD | Ongoing |
Purpose
Section titled “Purpose”Retail operations require correct money, stock, and scope (store, zone, role). This page is the single backlog for:
- Which screens and flows need browser E2E (Playwright) or API E2E (Jest).
- What to build in each phase (fixtures, specs, CI).
- How to know P0 is done before calling a release gate.
This does not replace:
- Per-module scenario sheets under System test cases (index).
- Vendor testing and screenshots index (per-screen unit + E2E + docs PNG).
- Colocated unit tests (
*.spec.tsinsrc/andapps/backend).
Accuracy model: Unit tests prove logic; API E2E proves HTTP contracts and totals; browser E2E proves critical UI paths call those APIs correctly. No approach guarantees 100% correctness—this roadmap minimizes regression on tier-A revenue paths.
Current state (as-is)
Section titled “Current state (as-is)”| Area | Tooling | Browser E2E today | Notes |
|---|---|---|---|
| vendor-web | Playwright (apps/vendor-web/playwright.config.cjs) | ✅ e2e/login.spec.ts only | global-setup.ts waits for GET /api/v1/health |
| vendor-web | Same | ⚠️ “E2E” folder mostly not browser | Files like pos-place-order-surfaces.spec.ts read src/ (contract tests)—move to Vitest over time |
| admin-web | Vitest only | ⛔ No Playwright yet | See Admin web test cases |
| backend | Jest test/*.e2e-spec.ts | N/A (HTTP) | Auth, health, OpenAPI smoke, partial POS admin |
Commands:
# Vendor browser E2E (backend must be up)cd apps/backend && npm run start:dev # or DB_ENABLED=false for in-memory seedscd apps/vendor-web && npm run test:e2e:installnpm run vendor:test:e2e # from repo rootEnv vars: PLAYWRIGHT_VENDOR_OWNER_EMAIL, PLAYWRIGHT_VENDOR_OWNER_PASSWORD, PLAYWRIGHT_API_BASE_URL — see Frontend applications.
Priority legend
Section titled “Priority legend”| Priority | Meaning | Release gate |
|---|---|---|
| P0 | Revenue-critical: wrong behavior loses money, stock, or trust | Required for “retail E2E ready” |
| P1 | Important operations; schedule soon after P0 | Recommended before major releases |
| P2 | Lower traffic or hardware-dependent | Backlog |
Automation columns: Unit | API-E2E | Browser-E2E | Manual — check when done; add spec path in Notes.
A. Vendor — sales & orders (P0)
Section titled “A. Vendor — sales & orders (P0)”Routes use VENDOR_ROUTES in apps/vendor-web/src/lib/vendor-routes.ts.
| ID | Route / screen | Flow to automate | Min assertions | Unit | API-E2E | Browser-E2E | Notes |
|---|---|---|---|---|---|---|---|
| A1 | /login | Owner + employee sign-in | URL /dashboard, shell visible; login POST 200 | [x] e2e/login.spec.ts | Extend forgot-password later (P2) | ||
| A2 | /dashboard/pos or /point-of-sale/sale | Open shift (if required) → select store/lane → add SKU → pay cash | place-order 200, order_id, totals match API (minor units) | [ ] | [ ] | [ ] | Golden path #1 |
| A3 | Same | Cart with % discount + tax | Subtotal, discount, tax, grand total = API body | [ ] | [ ] | [ ] | Pair with API fixture cart |
| A4 | Same | CRM customer (non-guest) + membership preview price | Line price matches catalog preview API | [ ] | [ ] | [ ] | See pos-catalog-member-preview util tests |
| A5 | Same | Debt / BNPL tender | No terminal modal; order status correct | [ ] | [ ] | [ ] | isPosTerminalPaymentBlocking contract exists |
| A6 | /dashboard/orders/create | Manual retail order | Same as A2 via postVendorPlaceOrder | [ ] | [ ] | [ ] | usePosPlaceOrder on 3 surfaces |
| A7 | /dashboard/orders | List → detail; filters; pagination URL | page, limit, tab in URL; detail fields | [ ] | [ ] | [ ] | |
| A8 | Returns tab / /point-of-sale/returns | Partial refund | Refund amount + stock restored | [ ] | [ ] | [ ] | Backend: vendor-refund-restock.util |
| A9 | /dashboard/orders/shifts | Open / close shift | Block or warn place-order when policy requires shift | [ ] | [ ] | [ ] | P1 if shift not mandatory in seed |
Linked sheets: POS & payments, Vendor orders & checkout, Vendor POS workspace, POS guide.
B. Vendor — catalog & pricing (P0 / P1)
Section titled “B. Vendor — catalog & pricing (P0 / P1)”| ID | Route | Flow | Min assertions | Unit | API-E2E | Browser-E2E | Notes |
|---|---|---|---|---|---|---|---|
| B1 | /dashboard/items/list | Search, sort, pagination URL | Query params stable after reload | [ ] | [ ] | [ ] | P0 list accuracy |
| B2 | /dashboard/items/create | Create simple item | Appears on list; POS menu can load it | [ ] | [ ] | [ ] | P0 |
| B3 | /dashboard/items/:id/edit | Change retail price | POS menu price updates | [ ] | [ ] | [ ] | P0 |
| B4 | /dashboard/items/price-approvals | Approve price batch | Status transition | [ ] | [ ] | [ ] | P1 if workflow enabled |
| B5 | Items list column popover | Toggle optional columns + persist | Visible columns + storage key | [ ] | [ ] | P1; admin has similar pattern |
Linked: Catalog products (vendor), Vendor web test cases.
C. Vendor — inventory (P0)
Section titled “C. Vendor — inventory (P0)”| ID | Route | Flow | Min assertions | Unit | API-E2E | Browser-E2E | Notes |
|---|---|---|---|---|---|---|---|
| C1 | /dashboard/inventory/stocks | View stock for store | Qty matches API before/after sale | [ ] | [ ] | [ ] | P0 |
| C2 | /dashboard/inventory/adjustments | Post adjustment (+/−) | Delta = form; audit row | [ ] | [ ] | [ ] | P0 |
| C3 | /dashboard/inventory/lots | Lot detail (if used) | Lot qty consistent | [ ] | [ ] | [ ] | P1 if lots enabled |
| C4 | /dashboard/inventory/inter-store-borrow | Transfer between stores | Source ↓ dest ↑ | [ ] | [ ] | [ ] | P1 pick one transfer type |
Linked: Inventory (vendor), Vendor inventory test cases.
D. Vendor — customers & receivables (P0 / P1)
Section titled “D. Vendor — customers & receivables (P0 / P1)”| ID | Route | Flow | Min assertions | Unit | API-E2E | Browser-E2E | Notes |
|---|---|---|---|---|---|---|---|
| D1 | /dashboard/customers/list | Create / edit customer | Selectable on POS | [ ] | [ ] | [ ] | P0 |
| D2 | /dashboard/finance/receivables | Receivable from BNPL order (A5) | Balance = order debt | [ ] | [ ] | [ ] | P0 |
| D3 | Same | Record partial payment | Balance decreases correctly | [ ] | [ ] | [ ] | P0 |
Linked: Finance (vendor), Vendor finance test cases, Sales & receivables procedures.
E. Vendor — finance & reports (P1)
Section titled “E. Vendor — finance & reports (P1)”| ID | Route | Flow | Browser-E2E |
|---|---|---|---|
| E1 | /dashboard/finance/transactions | Filter by date range | [ ] |
| E2 | /dashboard/finance/expenses | Create expense | [ ] |
| E3 | /point-of-sale/report | Revenue matches P0 orders | [ ] |
F. Vendor — config affecting sales (P1)
Section titled “F. Vendor — config affecting sales (P1)”| ID | Route | Flow | Browser-E2E |
|---|---|---|---|
| F1 | /dashboard/settings/checkout-lanes | Multi-lane: lane required before POS | [ ] |
| F2 | /dashboard/settings/devices | Device row saved (mock terminal in CI) | [ ] Manual for real pinpad |
| F3 | /dashboard/orders/create-wholesale | Wholesale order + price list | [ ] |
G. Admin platform (P0 / P1) — Playwright not set up yet
Section titled “G. Admin platform (P0 / P1) — Playwright not set up yet”Routes: ADMIN_ROUTES in apps/admin-web/src/lib/admin-routes.ts.
| ID | Route | Flow | Min assertions | API-E2E | Browser-E2E | Notes |
|---|---|---|---|---|---|---|
| G1 | Admin login | Login + module in JWT | Dashboard shell | [ ] | [ ] | Mirror vendor Playwright config |
| G2 | /dashboard/products | Zone-scoped list + batch status | 403 out of zone; batch cap 200 | [ ] | [ ] | P0 |
| G3 | /dashboard/products/create | Create platform item | Visible in list | [ ] | [ ] | P1 |
| G4 | /dashboard/stores | Store in admin zone | Detail / edit guard | [ ] | [ ] | P0 |
| G5 | /dashboard/vendors | Vendor list + package | [ ] | [ ] | P1 | |
| G6 | /dashboard/orders | Platform orders list/detail | [ ] | [ ] | P1 | |
| G7 | /dashboard/inventory/stocks | Cross-vendor stock (zone) | [ ] | [ ] | P1 | |
| G8 | /dashboard/tickets | Support Kanban / list | [ ] | P2 |
Linked: Admin catalog test cases, Admin web.
H. Backend API E2E (Jest) — P0 complements
Section titled “H. Backend API E2E (Jest) — P0 complements”Add or extend under apps/backend/test/. These prove money and stock without UI.
| ID | API / area | Scenarios | File (proposed) | Status |
|---|---|---|---|---|
| H1 | Vendor POS place-order | Cash cart fixture → totals, tax, discount, stock delta | vendor-place-order.e2e-spec.ts | [ ] |
| H2 | Admin products batch status | Cap, zone deny, success count | extend admin products tests | [ ] |
| H3 | Inventory adjustment | Qty after adjust | vendor-inventory-adjust.e2e-spec.ts | [ ] |
| H4 | Receivable payment | Ledger balance after payment | vendor-receivable-payment.e2e-spec.ts | [ ] |
| H5 | Admin products list | Zone filter on list/get | extend existing service e2e or HTTP | [ ] |
Existing: auth.e2e-spec.ts, vendor-auth.e2e-spec.ts, auth-admin.e2e-spec.ts, openapi-routes.e2e-spec.ts, pos-admin.e2e-spec.ts, http-security.e2e-spec.ts.
Out of scope (do not browser-E2E)
Section titled “Out of scope (do not browser-E2E)”- Real PAX / CodePay hardware and bridge payment capture (POS terminal docs).
- Bulk marketing, translation admin, low-traffic settings (SMTP, withdrawals).
- Docs-only screenshots (
e2e/docs-screenshots.spec.ts) — keep separate from retail gate. - Snapshot-testing entire pages (brittle; prefer numeric API asserts).
Implementation phases (work packages)
Section titled “Implementation phases (work packages)”Use the Phase schedule table at the top to record dates when ready.
Phase 0 — Foundation
Section titled “Phase 0 — Foundation”Goal: Reliable CI + shared fixtures; clarify what is “browser E2E” vs unit.
| # | Task | Done |
|---|---|---|
| 0.1 | Document seed strategy: retail-e2e vendor, 2 stores, fixed SKUs/prices/stock (script or migration seed) | [ ] |
| 0.2 | Playwright fixtures: loginAsVendorOwner, loginAsVendorEmployee, selectStore, gotoPosSale in apps/vendor-web/e2e/fixtures/ | [ ] |
| 0.3 | Move non-browser specs from e2e/*.spec.ts → src/**/*.spec.ts (Vitest) | [ ] |
| 0.4 | CI job: MySQL (or documented DB_ENABLED=false) + vendor:test:e2e smoke (login + health) | [ ] |
| 0.5 | Assert convention doc: money in minor units from JSON, not parsed UI text | [ ] |
| 0.6 | Add data-testid on POS Pay / Place order (minimal, stable) | [ ] |
Exit criteria: npm run vendor:test:e2e green on CI; login spec + health; seed documented.
Phase 1 — P0 vendor sales
Section titled “Phase 1 — P0 vendor sales”| # | Task | IDs | Done |
|---|---|---|---|
| 1.1 | API E2E place-order totals | H1 | [ ] |
| 1.2 | Browser: cash sale | A2 | [ ] |
| 1.3 | Browser: discount + tax | A3 | [ ] |
| 1.4 | Browser: debt tender | A5 | [ ] |
| 1.5 | Browser: create order page | A6 | [ ] |
| 1.6 | Browser: order list + detail | A7 | [ ] |
| 1.7 | Browser: partial return | A8 | [ ] |
Exit criteria: Golden path “sell → list → partial refund” green locally and CI.
Phase 2 — P0 inventory & catalog (vendor)
Section titled “Phase 2 — P0 inventory & catalog (vendor)”| # | Task | IDs | Done |
|---|---|---|---|
| 2.1 | Stock before/after sale | C1 + H1 | [ ] |
| 2.2 | Adjustment | C2 + H3 | [ ] |
| 2.3 | Items list/create/edit price | B1–B3 | [ ] |
| 2.4 | Customer + receivable from debt order | D1–D3 + H4 | [ ] |
Exit criteria: Stock and receivable numbers match API after P0 sale flow.
Phase 3 — Admin P0
Section titled “Phase 3 — Admin P0”| # | Task | IDs | Done |
|---|---|---|---|
| 3.1 | Scaffold apps/admin-web/playwright.config + e2e/global-setup | G1 | [ ] |
| 3.2 | Admin login E2E | G1 | [ ] |
| 3.3 | Products list + batch status | G2 + H2/H5 | [ ] |
| 3.4 | Stores zone scope | G4 | [ ] |
Exit criteria: Admin smoke on CI; products batch covered.
Phase 4 — P1 expansion
Section titled “Phase 4 — P1 expansion”| # | Task | IDs | Done |
|---|---|---|---|
| 4.1 | Shifts, wholesale, lanes | A9, F1, F3 | [ ] |
| 4.2 | Finance transactions, expenses, POS report | E1–E3 | [ ] |
| 4.3 | Price approvals, column popover | B4, B5 | [ ] |
| 4.4 | CI: @smoke tag for PR (~15 min); nightly full suite | [ ] |
Phase 5 — P2 & maintenance
Section titled “Phase 5 — P2 & maintenance”- Admin tickets Kanban (G8), marketing, permission matrix (owner vs employee).
- Flaky test budget: < 2% over 50 CI runs before enforcing PR gate.
- Optional: 3–5 visual snapshots (not whole-app).
P0 “retail E2E ready” definition
Section titled “P0 “retail E2E ready” definition”Before treating E2E as a release gate, all must be true:
- CI smoke runs on every PR: A1 + A2 + C2 + G1 + G2 (or documented subset with issue link).
- Money asserts use API JSON integers (cents), not OCR from UI.
- Seed data is deterministic (
E2E_SKU_001, fixed prices)—no “today’s date” dependence. - Unit coverage remains for services (
admin-products.service.spec.ts,PosService, refund restock utils, etc.). - Flaky rate under agreed threshold; quarantined tests marked
test.fixmewith ticket id.
Effort reference (for planning — not commitments)
Section titled “Effort reference (for planning — not commitments)”Rough engineering weeks with one FTE focused on E2E (backend support for seeds part-time):
| Phase | Calendar weeks | New browser specs (order of magnitude) | New API e2e specs |
|---|---|---|---|
| 0 | 2 | 2 | 0 |
| 1 | 3 | 8–12 | 4–6 |
| 2 | 3 | 10–14 | 4 |
| 3 | 3 | 6–8 | 3 |
| 4 | 4 | 15–20 | 5 |
Adjust when you fill the Phase schedule table.
Traceability
Section titled “Traceability”When a spec lands:
- Check the row in sections A–H (Unit / API-E2E / Browser-E2E).
- Add TC- id in the matching system test cases sheet; mark E2E✓ + path.
- Update Vendor testing and screenshots index for vendor screens.
- Bump Document control version on this page if priorities change.