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

15 KiB

Company Behaviors

Overview

The Company section provides company-level settings and reporting for Integreat users. It is implemented as SSR pages using HTMX and is accessed via the left navigation sidebar under "My Company". All pages require authentication and enforce client-level access controls. Most pages react to client selection changes by refreshing their content via HTMX.

Routes & Pages

Route Path Description
:company /company Company profile, downloads, signature
:company-1099 /company/1099 1099 vendor report grid
:company-reports /company/reports Generated reports list
:company-expense-report /company/reports/expense Expense breakdown and vendor totals
:company-reconciliation-report /company/reports/reconciliation Bank reconciliation report
:company-plaid /company/plaid Plaid bank account linking
:company-yodlee /company/yodlee Yodlee bank account linking

Sub-routes

  • /company/1099/table - 1099 vendor data grid (HTMX)
  • /company/1099/vendor-dialog/:vendor-id - Edit vendor 1099 info modal
  • /company/1099/vendor-dialog/:vendor-id (POST) - Save vendor 1099 info
  • /company/reports/table - Reports data grid (HTMX)
  • /company/reports/expense/card - Expense breakdown chart (HTMX)
  • /company/reports/expense/invoice-total-card - Invoice totals grid (HTMX)
  • /company/reports/reconciliation/card - Reconciliation data (HTMX)
  • /company/plaid/table - Plaid accounts grid (HTMX)
  • /company/plaid/link (POST) - Link new Plaid account
  • /company/plaid/relink (PUT) - Initiate Plaid relink
  • /company/yodlee/table - Yodlee accounts grid (HTMX)
  • /company/yodlee/fastlink - Yodlee Fastlink dialog
  • /company/yodlee/reauthenticate (PUT) - Reauthenticate Yodlee account
  • /company/yodlee/refresh (PUT) - Refresh Yodlee provider account (admin only)
  • /company/signature/put - Save drawn signature
  • /company/signature/post - Upload signature file

Behaviors by Page

Company Profile

Route: /company

Client Selection State

  • If no client is selected: Displays a "Please select a company" placeholder card instead of profile content.
  • If a client is selected: Displays the company profile with name, address, downloads, and (if permitted) signature section.

Profile Content

  • Company Name: Displayed as a heading. Pulled from client/name.
  • Address Block: Displays street1, street2, city, state, and zip if address data exists. Address fields are optional — missing fields are omitted without error.

Downloads

  • Shows a "Download vendor list" button.
  • Clicking downloads a CSV/Excel export via /api/vendors/company/export?client=<client-code>.
  • Button is always visible regardless of permissions.

Signature Upload

  • Permission-gated: Only visible if user has {:subject :signature :activity :edit}.
  • Existing Signature: If client/signature-file exists, displays the saved signature image (696x261px).
  • Draw Signature:
    • "New signature" button enables drawing mode on a canvas.
    • "Clear" button clears the canvas while in drawing mode.
    • "Accept" button converts the canvas to a PNG data URL and submits it via HTMX PUT to /company/signature/put.
    • Invalid image data (not starting with data:image/png;base64,) is rejected with a validation error.
  • File Upload:
    • Drag-and-drop zone for JPEG files (recommended 696x261 pixels).
    • Hover states change background color from blue to green.
    • File selected via input or drop triggers form submission via HTMX POST to /company/signature/post.
    • On success, the signature section refreshes with the uploaded image.
  • Storage: Uploaded signatures are stored in S3 bucket integreat-signature-images with public-read ACL. The public URL is saved to client/signature-file.

1099 Reports

Route: /company/1099

Vendor Grid

  • Displays vendors who received $600 or more in check payments during calendar year 2025 (payments dated Jan 1, 2025 - Jan 1, 2026).
  • Grid columns:
    • Client: Client code
    • Vendor Name: Vendor name with legal entity name (or first/middle/last name) as subtitle. Shows a 1099 type pill badge if set.
    • TIN: Tax ID number with TIN type pill (EIN/SSN)
    • Expense Account: Default expense account name
    • Address: Full address or "No address" placeholder
    • Paid: Total amount paid as a pill badge (rounded to nearest dollar)
  • Row has an edit (pencil) icon button.

Vendor Edit Dialog

  • Opens in a modal via HTMX GET.
  • Address Section: Street 1, Street 2, City, State, ZIP. ZIP validated as 5 digits or empty.
  • Legal Entity Section:
    • Legal Entity Name (full width) — OR —
    • First Name, Middle Name, Last Name (2-col layout each)
  • TIN Section:
    • TIN input
    • TIN Type dropdown: EIN / SSN
    • 1099 Type dropdown: populated from legal-entity-1099-type enum
  • Save Behavior:
    • Validates via Malli schema.
    • Address is nulled if all address fields are empty and no db/id exists.
    • On success: modal closes, row refreshes with updated data and flash highlight.

Filtering & Sorting

  • Supports standard grid query params (sort, pagination, search).
  • Default sort is by client code then amount.

Expense Reports

Route: /company/reports/expense

Expense Breakdown Chart

  • Bar chart showing expenses grouped by top 20 expense accounts over the last 8 weeks.
  • X-axis: Week ranges (Monday-Sunday) formatted as dates.
  • Data sourced from non-voided invoices with expense account allocations.
  • Filters:
    • Vendor typeahead (filters to specific vendor's invoices)
    • Account typeahead (filters to specific expense account)
  • Filters trigger HTMX GET to /company/reports/expense/card with change event.
  • Chart rendered via Chart.js on canvas element with Alpine.js init.

Invoice Totals by Vendor

  • Grid showing total invoice amounts per vendor per company.
  • Date Range Filters: Start date and End date inputs.
  • Default range: last 30 days.
  • Grid columns: Vendor name (sticky left), then one column per company with total amount or "-" for zero.
  • Filters trigger HTMX GET to /company/reports/expense/invoice-total-card.
  • URL query params are pushed to browser history on filter change.

Reconciliation Reports

Route: /company/reports/reconciliation

Access Control

  • Navigation link only visible if user has {:subject :reconciliation-report} permission.

Report Display

  • Compares external bank transactions (from Intuit/QuickBooks) against Integreat transactions.
  • Date Range: Start and End date inputs. Must be submitted via "Run" button.
  • Grid Columns:
    • Bank Account name
    • Source count (external transactions)
    • Synced count (found in Integreat)
    • Approved transactions
    • Unapproved transactions
    • Requires feedback transactions
    • Missing transactions
  • Row Styling:
    • Green background (bg-primary-200) if external count equals synced count.
    • Red background (bg-red-200) if counts mismatch.
  • Missing Transactions: Shown as a count with tooltip button. Clicking reveals a popup table of missing transaction dates and amounts.

Data Sources

  • Fetches Intuit bank accounts and transactions for selected clients.
  • Matches transactions by transaction/id in Datomic.
  • Categorizes found transactions by approval status.

Plaid Bank Linking

Route: /company/plaid

Account Grid

  • Displays all Plaid-linked items for the selected clients.
  • Columns:
    • Plaid Item: External item ID
    • Integreat ↔ Plaid Status: Shows integration state. If any linked bank account has failed/unauthorized integration status, displays red pill with error message tooltip. Otherwise green "Success".
    • Plaid ↔ Bank Status: Plaid item status (e.g., "SUCCESS") with last updated date.
    • Accounts: List of linked accounts with name, masked number, last synced date, and identicon.
  • Supports sorting by external ID, Plaid bank status.
  • "Link [client-code] account" button opens Plaid Link modal.
  • Button only appears when a client is selected.
  • On successful Plaid Link, HTMX POSTs public token to /company/plaid/link.
  • Link Handler:
    • Exchanges public token for access token.
    • Fetches accounts from Plaid.
    • Creates plaid-item entity with client reference, external ID, access token, status, and timestamp.
    • Creates plaid-account entities for each account with external ID, masked number, name, and balance.
    • Redirects back to /company/plaid on success.

Re-authenticate

  • Each row has a "Reauthenticate" button.
  • Generates a relink token and opens Plaid Link in update mode for the existing item.

Yodlee Bank Linking

Route: /company/yodlee

Account Grid

  • Displays Yodlee provider accounts for selected clients.
  • Columns:
    • Client: Client code (hidden if user has only one client)
    • Provider Account: Yodlee provider account ID
    • Status: Success (green pill) or other (yellow pill)
    • Detailed Status: Raw status string
    • Last Updated: Formatted date
    • Accounts: List of linked accounts with name and number
  • Supports sorting by status, client, provider account, last updated.
  • "Link new account" button opens Yodlee Fastlink modal.
  • Button is disabled if no client is selected, with a note: "Please select a specific customer to link a new account."
  • Fastlink opens with config "Aggregation" and access token for the selected client.
  • Error handling: if Yodlee returns an error, displays a notification and closes modal after 3 seconds.

Re-authenticate

  • "Reauthenticate" button per row opens Fastlink in edit mode for the specific provider account.

Refresh (Admin Only)

  • Admin users see a refresh icon button on each row.
  • Triggers Yodlee account refresh and refreshes the row.

Reports List

Route: /company/reports

Grid

  • Lists previously generated reports.
  • Columns:
    • Name: Report name
    • Created by: Creator name as pill badge
    • Created: Formatted creation date
  • Row actions:
    • Download: Link to S3-hosted report file
    • Delete: Admin-only trash icon. Deletes S3 object and retracts entity.
  • Supports filtering by date range and client.
  • Supports sorting by client, created, creator, name.

Cross-Cutting Behaviors

Client Switching

  • All company pages listen for clientSelected from:body event.
  • On client switch, HTMX GET refreshes #app-contents with a 300ms swap animation.
  • Pages that require a specific client (Yodlee link, signature, downloads) show appropriate empty/placeholder states when no client is selected.

Bank Account Management

  • Bank Account Search: /company/:db-id/bank-account/search provides typeahead data for bank accounts belonging to a specific client.
  • Bank Account Typeahead: Component used across the app (e.g., in transaction forms) that shows a search field or "Please select a client" message.

Permissions

Feature Required Permission
All company pages Authenticated user with client access
Signature upload {:subject :signature :activity :edit}
Bank Sync Report nav {:subject :reconciliation-report}
Delete reports Admin role
Yodlee refresh Admin role (is-admin?)

Role Access Summary

  • Admin: Full access to all features.
  • Power-user / Manager / User: Can access all company pages (subject to client assignment), can edit signatures (user role), can view reports.
  • Read-only: Can view ledger pages only; no access to company settings.

Edge Cases

No Client Selected

  • Company profile shows "Please select a company" placeholder.
  • Yodlee "Link new account" button is disabled with helper text.
  • Plaid "Link account" button is hidden (only shown when client-code exists).
  • 1099, reports, and other grids operate on trimmed-clients (all visible clients) when no single client is selected.

Invalid Signature Data

  • Drawing signature data that does not start with data:image/png;base64, throws validation error.
  • File upload errors are caught and logged but currently do not display user-facing error messages (commented-out error UI).

Date Range Filters

  • Expense breakdown defaults to last 65 days of data but displays last 8 weeks.
  • Invoice totals default to last 30 days.
  • Reconciliation report requires explicit date range — shows "Please choose a time range to run the report" if none selected.

Empty States

  • 1099 grid: Empty if no vendors received $600+ in checks during 2025.
  • Reports grid: Empty if no reports have been generated.
  • Plaid/Yodlee grids: Empty if no bank accounts are linked.
  • Reconciliation: Missing transactions tooltip only appears when count > 0.

Concurrent Client Filtering

  • 1099 report sums payments per vendor per client. Vendors shared across multiple clients appear in each client's context.
  • Report list filters to ensure report's clients intersect with user's visible clients.

Test Data Requirements

Clients

  • At least 2 clients with different codes, names, and addresses.
  • One client with a complete address (street1, street2, city, state, zip).
  • One client with no address.
  • One client with an existing signature file URL.
  • One client with no signature file.

Vendors

  • Vendors with 1099 data (legal entity name, TIN, TIN type, 1099 type, address).
  • Vendors with and without addresses.
  • Vendors who received $600+ in check payments in 2025.
  • Vendors who received less than $600 (should not appear in 1099 grid).
  • Vendors shared across multiple clients.

Payments

  • Check payments dated within 2025 (Jan 1 - Dec 31) for 1099 testing.
  • Payments of different types (check, ACH, etc.) — only checks count toward 1099.
  • Payments to vendors across multiple clients.

Invoices

  • Non-voided invoices with expense account allocations for expense report testing.
  • Invoices with different vendors and expense accounts.
  • Invoices dated across multiple weeks for 8-week breakdown.

Bank Accounts

  • Plaid-linked accounts with various statuses (SUCCESS, error states).
  • Yodlee-linked accounts with various statuses.
  • Bank accounts with integration status (failed, unauthorized, success).

Reports

  • At least one generated report with name, creator, created date, and S3 URL.
  • Reports belonging to different clients.

Users

  • Admin user (full access).
  • User with signature :edit permission.
  • User with reconciliation-report permission.
  • User with single client access.
  • User with multiple client access.
  • Read-only user (should not see company nav).

Dependencies

Backend

  • Datomic for all entity storage and queries.
  • Amazonica S3 for signature image storage and report file storage.
  • Plaid API for bank account linking (token exchange, account fetch).
  • Yodlee API for bank account linking (Fastlink, token management).
  • Intuit/QuickBooks API for reconciliation report data.
  • Solr for client name search (company-search endpoint).

Frontend

  • HTMX for all server-rendered interactions.
  • Alpine.js for signature canvas state, drag-and-drop file upload, modal state, chart initialization.
  • Chart.js for expense breakdown bar chart.
  • SignaturePad library for canvas signature drawing.
  • Plaid Link SDK for Plaid account linking.
  • Yodlee Fastlink SDK for Yodlee account linking.
  • Jdenticon for account identicons in Plaid grid.