Files
integreat/docs/testing/behaviors/admin.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

17 KiB

Admin Behaviors

Overview

The Admin section is a server-side rendered (SSR) HTMX interface for superuser operations in Integreat. All admin pages require the admin user role. Non-admin users are redirected away. The admin area includes dashboards, entity management grids, background job orchestration, audit history, and bulk import tools.

Routes & Pages

Page Route Handler Namespace
Admin Dashboard /admin auto-ap.ssr.admin
Clients /admin/clients auto-ap.ssr.admin.clients
Accounts /admin/accounts auto-ap.ssr.admin.accounts
Vendors /admin/vendors auto-ap.ssr.admin.vendors
Transaction Rules /admin/transaction-rules auto-ap.ssr.admin.transaction-rules
Background Jobs /admin/jobs auto-ap.ssr.admin.background-jobs
History / Audit /admin/history auto-ap.ssr.admin.history
Import Batches /admin/import-batches auto-ap.ssr.admin.import-batch
Excel Invoices /admin/excel-invoices auto-ap.ssr.admin.excel-invoice
Sales Summaries /admin/sales-summaries auto-ap.ssr.admin.sales-summaries

All routes are wrapped with wrap-client-redirect-unauthenticated followed by wrap-admin.

Behaviors by Page

Admin Dashboard

Display

  • Shows two Chartist charts:
    • Growth in clients: Bar chart showing client count at 2 years ago, 1 year ago, and today (uses dc/as-of against Datomic history).
    • Changes by hour: Line chart showing Datomic transaction counts per hour over the last 24 hours.
  • Uses the standard admin page layout with admin-aside-nav.

Access Control

  • Only accessible to users with admin role.
  • Unauthenticated users are redirected to login.

Client Management

Grid Display

  • Columns: Name, Code, Locations (as pills), Emails (as pills), Status.
  • Status column shows:
    • Lock status: "Locked " with color coding (green < 90 days, yellow < 365 days, red otherwise).
    • "Not locked" in red if no lock date.
    • Bank account integration status pills (red for failed/unauthorized).
  • Row actions: Biweekly Sales PowerQuery button, Edit button (pencil icon).
  • Global action: "New Client" button opens wizard.

Filtering

  • Name (case-insensitive substring match).
  • Code (exact match, upper-cased).
  • Group (exact match on client groups, upper-cased).
  • Select filter: "All" or "Only mine" (filters to clients assigned to current user).
  • Filters trigger HTMX request with 500ms debounce on change, 1000ms on keyup.

Sorting

  • By name, code.
  • Pagination: 25 per page default.

Client Wizard (Create / Edit)

  • Multi-step linear wizard with steps: Info → Matches → Contact → Bank Accounts → Integrations → Cash Flow → Other Settings.
  • Info step: Name (required), Code (immutable on edit), Locked Until date, Locations (dynamic grid).
  • Matches step: String match patterns, location match patterns (match → location mapping).
  • Contact step: Address (street1, street2, city, state, zip), Email contacts grid (description + email).
  • Bank Accounts step: Sortable card list of existing accounts. Add new cash/credit/checking accounts. Each account has type-specific form.
    • Cash account: nickname, code, financial code (numeric), start date, include-in-reports, visible-for-payment.
    • Credit card: same + bank name, account number, Plaid/Yodlee/Intuit integration selectors.
    • Checking: same + routing number, bank code, check number.
    • Validation: financial code is required if "Include in Reports" is true.
  • Integrations step: Square auth token input, refresh Square locations button, Square location → client location mapping grid.
  • Cash Flow step: Week A/B credits and debits (4 numeric fields).
  • Other Settings step: Feature flags (dropdown with known flags), Groups (free text grid).

Save Behavior

  • POST for create, PUT for update.
  • Code uniqueness validation on create.
  • Groups are upper-cased on save.
  • Bank account start dates coerced to dates.
  • After save: row flashes in grid, modal closes, Solr reindexes client.

Biweekly Sales PowerQuery

  • Generates 6 saved queries per client (sales summary, category, expected deposits, tenders, refunds, cash drawer shifts).
  • Opens modal with copy-to-clipboard buttons for Excel Power Query M-code.

Account Management

Grid Display

  • Columns: Code (numeric), Name, Type (pill), Location.
  • Row action: Edit button.
  • Global action: "New Account" button.

Filtering

  • Name (case-insensitive substring on upper-cased name).
  • Code (exact numeric match).
  • Type: All, Dividend, Asset, Equity, Liability, Expense, Revenue, None.

Sorting

  • By code, name, type, location.
  • Default sort by upper-cased numeric code.

Account Dialog (Create / Edit)

  • Modal card with live-updating header showing code and name.
  • Fields:
    • Numeric Code (required, unique on create; hidden on edit).
    • Name (required).
    • Account Type (required, enum: asset, liability, equity, revenue, expense, dividend, none).
    • Location (optional string).
    • Invoice Allowance (enum: allowed, denied, warn).
    • Vendor Allowance (enum: allowed, denied, warn).
    • Applicability (enum: global, customized).
    • Client Overrides grid: client typeahead + override name. Validates no duplicate clients.

Save Behavior

  • POST for create, PUT for update.
  • Numeric code uniqueness check on create.
  • Client override uniqueness validation.
  • After save: Solr reindexes account + all client overrides.

Vendor Management

Grid Display

  • Columns: Name (with usage pills), Email, Default Account.
  • Usage pills: "Unused" (red) if 0 clients, "Used by N clients" (primary), "Used N times" (secondary).
  • Row action: Edit button (opens wizard).
  • Global actions: "Merge" button, "New Vendor" button.

Filtering

  • Name (case-insensitive substring on upper-cased name).
  • Type: All, Only hidden, Only global.

Vendor Wizard (Create / Edit)

  • Timeline steps: Info → Terms → Account → Address → Legal.
  • Info step: Name (required, 3+ chars), Print As (optional, toggleable), Hidden (admin-only checkbox).
  • Terms step: Terms in days (integer), Terms Overrides grid (client + days), Automatically Paid When Due grid (client list).
  • Account step: Default Account (typeahead), Account Overrides grid (client + account typeahead). Account typeahead is scoped by selected client.
  • Address step: Street1, Street2, City, State (2 chars), Zip (5 chars).
  • Legal step: Legal Entity Name OR First/Middle/Last name, TIN, TIN Type (EIN/SSN), 1099 Type (enum).

Vendor Merge

  • Modal with Source Vendor (to be deleted) and Target Vendor.
  • Validation: source and target must differ.
  • On merge: all references to source vendor are retracted and asserted as target vendor. Source vendor entity is retracted.
  • Shows success notification after merge.

Save Behavior

  • POST for create, PUT for update.
  • Solr reindexes vendor name + hidden flag.

Transaction Rules

Grid Display

  • Columns: Client (or group pill), Bank Account, Description, Amount (gte/lte pills), Note.
  • Row actions: Delete (with confirmation), Execute (play icon), Edit (pencil icon).
  • Global action: "New Transaction Rule" button.

Filtering

  • Vendor (entity typeahead).
  • Note (case-insensitive regex match).
  • Description (case-insensitive substring).
  • Client Group (exact upper-cased match).

Transaction Rule Wizard

  • Two-step wizard: Edit → Test.
  • Edit step:
    • Description (required, regex pattern, 3+ chars).
    • Optional togglable filters: Client, Client Group, Bank Account, Amount range (gte/lte), Day of Month range (gte/lte).
    • Bank account selector is scoped by selected client.
    • Outcomes: Assign Vendor (typeahead), Accounts grid (account + location + percentage), Approval Status (radio: unapproved/approved).
    • Account location is derived from account's fixed location, client locations, or "Shared".
    • Validation: account percentages must sum to 100%, bank account must belong to selected client, location must match account's fixed location if set.
  • Test step: Shows matching transactions (up to 15) with client, bank, date, description. Badge shows total count ("99+" if ≥99).

Execute

  • Opens dialog with checkbox-selectable transactions that match the rule AND are unapproved.
  • Only transactions on or after client's locked-until date are included.
  • Can select "All" or individual transactions.
  • On execution: applies rule coding to each transaction via upsert-transaction, touches Solr index.
  • Shows notification: "Successfully coded X of Y transactions!"

Delete

  • Confirms before delete.
  • Retracts entity from Datomic.
  • Row fades out with "live-removed" class.

Background Jobs

Grid Display

  • Columns: Start time, End time, Duration (minutes), Name, Status.
  • Status values: :running, :pending, :succeeded, :failed.
  • Data source: ECS tasks filtered by INTEGREAT_JOB environment variable.
  • Global action: "Run job" button.

Job Start Dialog

  • Job type dropdown: Yodlee Import, Yodlee Account Import, Intuit Import, Plaid Import, Bulk Journal Import, Square Import, Register Invoice Import, Upsert recent ezcater orders, Load Historical Square Sales, Export Backup.
  • Dynamic subform based on job type:
    • Bulk Journal Import: S3 URL path input.
    • Register Invoice Import: S3 URL path input.
    • Load Historical Sales: Client typeahead + Days (1-120).
  • Validation: cannot start a job that is already running.
  • On submit: runs ECS Fargate Spot task with selected task definition.

History / Audit

Display

  • Search box for entity ID (numeric Datomic entity ID).
  • History table shows: Date, User, Field, From value, To value.
  • Values are formatted: dates → local format, large integers (>1M) → clickable links to that entity's history, nil → "(none)", others → pr-str.
  • Entity ID links load that entity's history inline.
  • Snapshot link opens inspector showing full entity pull [*].
  • No pagination (all history rows shown).

Inspector

  • Card showing all attributes of an entity at current database value.
  • Clickable entity IDs recurse into history.

Import Batches

Grid Display

  • Columns: Date, Source, Status, User, Imported, Pre-existing, Suppressed.
  • Row action: External link to transactions filtered by import batch.

Filtering

  • Date range (start/end).
  • Source (enum: import-source values).

Sorting

  • By date, source, status, user.

Excel Invoices

Display

  • Single-page form with large textarea for tab-separated invoice data.
  • Shows sample data as placeholder.

Import Behavior

  • Parses tab-separated rows with columns: raw-date, vendor-name, check, location, invoice-number, amount, client-name, bill-entered, bill-rejected, added-on, exported-on, account-numeric-code.
  • Validates and resolves: client by code or name, vendor by name, account by numeric code.
  • Groups rows into: new, existing (by vendor+client+invoice-number), errors.
  • For new rows: creates invoice, optionally payment (if "Cash" check), and cash transaction.
  • Cash invoices get status "paid" with zero outstanding balance.
  • Non-cash invoices get status "unpaid" with full outstanding balance.
  • Results shown as pills: imported count, extant count, vendors not found (hover tooltip), error grid.

Sales Summaries

Grid Display

  • Columns: Client (hidden if only one client), Date, Debits (itemized list), Credits (itemized list).
  • Each item shows category, amount, and "missing account" pill in red if no account mapped.
  • Total row shows "Total: $X" with green pill if balanced, red if unbalanced.
  • Row action: Edit button.

Filtering

  • Date range (start/end).
  • Scoped to user's valid clients.

Edit Wizard

  • Shows all sales summary items in a grid: Category, Account, Debits, Credits.
  • Manual items: editable category, account typeahead, debit/credit inputs, removable.
  • Auto items: read-only category and amount, editable account.
  • Account typeahead is scoped by client and filtered for invoice-purpose accounts.
  • Live total row and unbalanced row update on amount changes.
  • Validation: each item must have exactly one of credit or debit, not both.
  • Validation: debits must equal credits (balanced).
  • Save updates ledger-mapped account assignments. Manual items get manual? flag and ledger-side/amount attached.

Cross-Cutting Behaviors

Admin-only Access

  • All admin routes use wrap-admin middleware.
  • Non-admin authenticated users receive an authorization failure (typically redirect or error).
  • Unauthenticated users are redirected to login via wrap-client-redirect-unauthenticated.

Impersonation

  • Admin users can select a client from the global client selector.
  • Some admin grids (clients, transaction rules, sales summaries) respect the selected client and filter results accordingly.

History Tracking

  • All mutating admin operations use audit-transact or audit-transact-batch.
  • Transactions record :audit/user attribute.
  • The History page queries Datomic's history database (dc/history) to show all changes to an entity.

Permissions

  • Admin role is required for all admin handlers.
  • No finer-grained permissions within admin area.

Form Validation Patterns

  • Malli schemas enforce form structure.
  • wrap-schema-enforce validates query params, route params, and form params.
  • wrap-form-4xx-2 re-renders dialogs with validation errors on 400 responses.
  • HTMX response targets (#form-errors .error-content) display field-level errors.

Solr Indexing

  • After create/update of clients, accounts, and vendors, Solr documents are reindexed.
  • This affects search typeaheads across the application.

Edge Cases

Client Management

  • Client code must be unique on create; immutable on edit.
  • Bank account code is immutable after creation.
  • Financial code (numeric) required when "Include in Reports" is true.
  • Square location refresh times out after 2 seconds → shows "No locations found."
  • Bank accounts are sortable via drag-and-drop (sortable.js integration via hx-trigger="end").

Account Management

  • Numeric code must be unique on create.
  • A client can only have one override per account.
  • Applicability and allowances are enums with specific values.

Vendor Management

  • Vendor merge fails if source equals target.
  • Account override typeahead depends on client selection; changing client updates available accounts.
  • Terms override requires unique clients (no duplicate client overrides).

Transaction Rules

  • Rule execution only affects unapproved transactions.
  • Transactions before client's locked-until date are excluded from execution.
  • Account percentages must sum to exactly 100%.
  • If account has a fixed location, the rule location must match.

Background Jobs

  • Cannot start a job that is already running (based on ECS task status).
  • ECS API failures propagate as exceptions.

Excel Invoices

  • Vendor name resolution is case-sensitive exact match.
  • Location format expected: CLIENTCODE-LOCATION.
  • Missing client code or location adds error row.
  • Cash check type creates paid invoice with transaction; others create unpaid invoice.

Sales Summaries

  • Debits and credits must balance to save.
  • Manual items require both category and amount.
  • Account typeahead is scoped to client + invoice-purpose accounts.

History

  • Entity ID must be parseable as a Long; otherwise shows error notification.
  • Very old entities may have no history if created before audit attributes.

Test Data Requirements

Users

  • Admin user with :user/role :user-role/admin.
  • Non-admin user with :user/role :user-role/user for access control tests.

Clients

  • Client with :client/name, :client/code (unique), :client/locations.
  • Client with :client/locked-until in the past and future.
  • Client with bank accounts (cash, credit, checking types).
  • Client with Square auth token for integration tests.
  • Client with feature flags and groups.

Accounts

  • Account with :account/numeric-code (unique), :account/name, :account/type.
  • Account with :account/location fixed.
  • Account with client overrides.

Vendors

  • Vendor with :vendor/name, :vendor/default-account.
  • Vendor with terms overrides and account overrides.
  • Hidden and non-hidden vendors.
  • Vendor with 1099 legal entity info.

Transaction Rules

  • Rule with description pattern, client, bank account, amount gte/lte.
  • Rule with account assignments summing to 100%.
  • Unapproved transactions matching rule criteria.
  • Transactions before and after client's locked-until date.

Background Jobs

  • ECS cluster with task definitions containing INTEGREAT_JOB env var.
  • Or mock ECS responses for unit tests.

Import Batches

  • Import batch entities with :import-batch/date, :import-batch/source, :import-batch/status.

Sales Summaries

  • Sales summary with items having :ledger-mapped/ledger-side and :ledger-mapped/amount.
  • Both manual and auto-generated items.

Dependencies

  • Datomic (history, transactions, pull API)
  • HTMX (frontend interactivity)
  • Alpine.js (modal state, conditional visibility)
  • Chartist (dashboard charts)
  • Solr (search indexing)
  • ECS API (background jobs)
  • Malli (schema validation)
  • Bidi (routing)
  • test/clj/auto_ap/integration/graphql/users.clj - User role and permission tests
  • test/clj/auto_ap/integration/graphql/accounts.clj - Account search and override tests
  • test/clj/auto_ap/integration/graphql/vendors.clj - Vendor management tests
  • test/clj/auto_ap/integration/graphql/transaction_rules.clj - Rule matching and execution tests