docs: add comprehensive test behavior documentation for all pages

Add behavior documentation covering all SSR and legacy SPA pages:
- Testing strategy and type definitions (unit/integration/UI)
- Dashboard, Invoice, Payment, Transaction, Ledger pages
- Company/Settings, POS, Admin, Search, Auth pages
- Legacy SPA behavior docs (no UI tests until migrated)
- Edge cases, test data requirements, and dependencies per subsystem

Total: 3,600+ lines of behavior documentation to guide test authorship.
This commit is contained in:
2026-05-04 12:15:20 -07:00
parent 2993da5c82
commit b499d460f3
13 changed files with 3785 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
# POS Behaviors
## Overview
The POS (Point of Sale) module provides SSR (HTMX-driven) grid pages for viewing sales data imported from payment processors. All pages share a common grid layout with filters, sortable columns, and pagination. Data is read-only except for the admin Sales Summaries edit wizard.
## Routes & Pages
| Page | Route (GET) | Table Route (GET) | Source File |
|------|-------------|-------------------|-------------|
| Sales Orders | `/pos/sales` | `/pos/sales/table` | `src/clj/auto_ap/ssr/pos/sales_orders.clj` |
| Expected Deposits | `/pos/expected-deposit` | `/pos/expected-deposit/table` | `src/clj/auto_ap/ssr/pos/expected_deposits.clj` |
| Tenders | `/pos/tenders` | `/pos/tenders/table` | `src/clj/auto_ap/ssr/pos/tenders.clj` |
| Refunds | `/pos/refunds` | `/pos/refunds/table` | `src/clj/auto_ap/ssr/pos/refunds.clj` |
| Cash Drawer Shifts | `/pos/cash-drawer-shifts` | `/pos/cash-drawer-shifts/table` | `src/clj/auto_ap/ssr/pos/cash_drawer_shifts.clj` |
| Sales Summaries (Admin) | `/pos/summaries` | `/pos/summaries/table` | `src/clj/auto_ap/ssr/admin/sales_summaries.clj` |
All POS pages appear under the **Sales** section in the main sidebar navigation. Sales Summaries uses the admin sidebar and is restricted to admin users.
## Behaviors by Page
### Sales Orders
**Purpose**: Display individual sales orders with line items, charges, and payment breakdowns.
**Filters**:
- Date range (start date / end date)
- Total amount range (min / max)
- Payment Method radio cards: All, Cash, Card, Gift Card, Other
- Processor radio cards: All, Square, Doordash, Uber Eats, Grubhub, Koala, EZCater, No Processor
- Category text input (filters by order line item category)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Source (rendered as a pill badge)
- Total
- Tax
- Tip
- Payment Methods (pills for each unique charge type: cash, card, gift card, other)
**Sortable by**: client, date, total, tax, tip, source, processor
**Action Buttons** (above grid): Total $ and Tax $ pills summarizing the currently filtered result set.
**Row Buttons**: External link icon when `:sales-order/reference-link` exists.
**Special Behaviors**:
- Filter by payment method matches against `charge/type-name` on the order's charges.
- Filter by processor matches against `charge/processor`.
- Filter by category matches against `order-line-item/category`.
- Summation in action buttons uses `auto-ap.datomic.sales-orders/summarize-orders`.
### Expected Deposits
**Purpose**: Display expected deposit records from payment processors, with links to transactions.
**Filters**:
- Date range
- Exact match ID (shows a removable pill when active)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Sales Date
- Total
- Fee
**Sortable by**: client, location, date, total, fee
**Row Buttons**:
- External link icon when `:expected-deposit/reference-link` exists
- "Transaction" button linking to the associated transaction (if `transaction/_expected-deposit` exists)
**Special Behaviors**:
- Hydration computes a `:totals` breakdown per expected deposit, aggregating charges by sales date with count and amount.
### Tenders
**Purpose**: Display individual charge/tender records (payments).
**Filters**:
- Date range
- Processor (same radio options as Sales Orders)
- Total amount range (min / max)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Total
- Processor (rendered as a pill badge)
- Tip
- Links
**Sortable by**: client, date, total, tip, processor
**Row Buttons**: External link icon when `:charge/reference-link` exists.
**Special Behaviors**:
- Links column shows an "expected deposit" pill linking to the associated expected deposit if one exists.
### Refunds
**Purpose**: Display refund records.
**Filters**:
- Date range
- Total amount range (min / max)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Total
- Type
- Fee
**Sortable by**: client, date, total, fee, type
**Row Buttons**: None.
### Cash Drawer Shifts
**Purpose**: Display cash drawer shift records.
**Filters**:
- Date range
- Total amount range (min / max)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Paid in
- Paid out
- Expected cash
- Opened cash
**Sortable by**: client, date, paid-in, paid-out, expected-cash, opened-cash
**Row Buttons**: None.
### Sales Summaries
**Purpose**: Admin-only daily sales summary view with ledger-mapped debit/credit breakdowns. Supports editing account mappings and manual adjustments.
**Access**: Admin sidebar, wrapped with `wrap-admin` middleware.
**Filters**:
- Date range (currently commented out in UI but schema supports it)
**Columns**:
- Client (hidden when viewing a single client)
- Date
- Debits (list of debit-line items with category, amount, and "missing account" warning pill if unmapped)
- Credits (list of credit-line items with category, amount, and "missing account" warning pill if unmapped)
**Sortable by**: client, date, debits, credits
**Row Buttons**: Edit (pencil) icon opens the edit wizard modal.
**Edit Wizard Behaviors**:
- Modal dialog titled "New invoice" (legacy title).
- Displays a data grid of summary items with columns: Category, Account, Debits, Credits.
- **Auto items** (non-manual): Category and amount are read-only; only Account is editable via typeahead.
- **Manual items**: Category (text input), Account (typeahead), Debit amount, Credit amount are all editable.
- New manual items can be added via "New Summary Item" row.
- Manual items can be removed via X button.
- Validation: an item cannot have both credit and debit amounts.
- **Total row**: shows running totals for debits and credits.
- **Unbalanced row**: shows the difference when debits ≠ credits.
- Account typeahead searches accounts scoped to the client with purpose "invoice".
- Items missing an account mapping display a red "missing account" pill in the grid view.
- Balanced summaries show a green "Total" pill; unbalanced show a red "Total" pill.
- Save submits an upsert of `:sales-summary/items`, persisting only `ledger-mapped/account` for auto items and full ledger mapping for manual items.
- After save, the row flashes and the modal closes.
## Cross-Cutting Behaviors
### Filtering, Sorting, Pagination
**HTMX Live Filtering**:
- All filter forms use `hx-trigger="change delay:500ms, keyup changed from:.hot-filter delay:1000ms"`.
- Form changes POST to the table route and target the table container.
- The table route swaps the grid contents and updates the browser URL via `hx-push-url`.
**Date Range**:
- All pages support `start-date` and `end-date` query params.
- The date range filter is rendered by `auto-ap.ssr.pos.common/date-range-field*`.
**Total Range**:
- Most pages support `total-gte` and `total-lte` (money inputs).
**Exact Match ID**:
- Most pages support `exact-match-id` to jump to a specific record.
**Sorting**:
- Click a sortable column header to toggle ascending/descending.
- Multi-sort is supported; active sorts appear as removable pills above the grid.
- Remove a sort by clicking the X on its pill.
- Default sort is by date descending for most pages.
**Pagination**:
- Default 25 rows per page.
- Controls include first/previous/next/last and per-page selector.
- Total count is displayed above the grid.
**Client Scoping**:
- All queries are scoped to the user's accessible clients (trimmed to max 20).
- Client column is automatically hidden when only one client is in scope.
- URL may include `client-id` or `client-code` params.
### Permissions
- POS pages require `(can? identity {:subject :sales :activity :read})`.
- Sales Summaries requires admin access (`wrap-admin`).
- All routes redirect unauthenticated users.
## Edge Cases
- **No results**: Grid displays "Total X: 0" with empty rows.
- **Single client view**: Client column is hidden; filters and summaries apply to that client's data only.
- **Missing reference links**: External link buttons are omitted when no URL exists.
- **Missing expected deposit link on Tenders**: Links cell is empty when no associated expected deposit exists.
- **Missing transaction on Expected Deposits**: Transaction button is omitted when no linked transaction exists.
- **Sales Summaries missing accounts**: Red "missing account" pills appear; totals show red when debits ≠ credits.
- **Manual item credit/debit both filled**: Form validation rejects with "Must choose one of credit/debit".
- **Date range with no start or end**: Query uses `scan-*` ion functions with nil boundaries.
- **Category filter on Sales Orders**: Empty string or nil category param is treated as no filter.
## Test Data Requirements
- Clients with `db/id`, `client/name`, `client/code`.
- Sales orders with: `:sales-order/date`, `:sales-order/total`, `:sales-order/tax`, `:sales-order/tip`, `:sales-order/source`, `:sales-order/charges` (with `charge/type-name`, `charge/processor`), `:sales-order/line-items` (with `order-line-item/category`).
- Expected deposits with: `:expected-deposit/date`, `:expected-deposit/total`, `:expected-deposit/fee`, `:expected-deposit/client`, optional `transaction/_expected-deposit`.
- Tenders (charges) with: `:charge/date`, `:charge/total`, `:charge/tip`, `:charge/processor`, optional `expected-deposit/_charges`.
- Refunds with: `:sales-refund/date`, `:sales-refund/total`, `:sales-refund/fee`, `:sales-refund/type`.
- Cash drawer shifts with: `:cash-drawer-shift/date`, `:cash-drawer-shift/paid-in`, `:cash-drawer-shift/paid-out`, `:cash-drawer-shift/expected-cash`, `:cash-drawer-shift/opened-cash`.
- Sales summaries with: `:sales-summary/date`, `:sales-summary/client`, `:sales-summary/items` (with `ledger-mapped/ledger-side`, `ledger-mapped/amount`, `sales-summary-item/category`, optional `ledger-mapped/account`).
## Dependencies
- **Grid system**: `auto-ap.ssr.grid-page-helper` provides `build`, `page-route`, `table-route`, `row*`, `table*`.
- **Components**: `auto-ap.ssr.components` for data grids, pills, buttons, inputs.
- **Querying**: `auto-ap.datomic` for `query2`, `pull-many`, `apply-pagination`, `apply-sort-3`.
- **Ions**: `iol-ion.query/scan-sales-orders`, `scan-expected-deposits`, `scan-charges`, `scan-sales-refunds`, `scan-cash-drawer-shifts`.
- **Permissions**: `auto-ap.permissions/can?`.
- **Time**: `auto-ap.time` for date formatting and localization.
- **Schema validation**: Malli schemas enforce query params on every request.