Files
integreat/docs/testing/behaviors/pos.md
Bryce b499d460f3 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.
2026-05-04 12:15:20 -07:00

10 KiB

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.