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.
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-nameon 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-linkexists - "Transaction" button linking to the associated transaction (if
transaction/_expected-depositexists)
Special Behaviors:
- Hydration computes a
:totalsbreakdown 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 onlyledger-mapped/accountfor 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-dateandend-datequery params. - The date range filter is rendered by
auto-ap.ssr.pos.common/date-range-field*.
Total Range:
- Most pages support
total-gteandtotal-lte(money inputs).
Exact Match ID:
- Most pages support
exact-match-idto 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-idorclient-codeparams.
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(withcharge/type-name,charge/processor),:sales-order/line-items(withorder-line-item/category). - Expected deposits with:
:expected-deposit/date,:expected-deposit/total,:expected-deposit/fee,:expected-deposit/client, optionaltransaction/_expected-deposit. - Tenders (charges) with:
:charge/date,:charge/total,:charge/tip,:charge/processor, optionalexpected-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(withledger-mapped/ledger-side,ledger-mapped/amount,sales-summary-item/category, optionalledger-mapped/account).
Dependencies
- Grid system:
auto-ap.ssr.grid-page-helperprovidesbuild,page-route,table-route,row*,table*. - Components:
auto-ap.ssr.componentsfor data grids, pills, buttons, inputs. - Querying:
auto-ap.datomicforquery2,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.timefor date formatting and localization. - Schema validation: Malli schemas enforce query params on every request.