Files
integreat/docs/testing/behaviors/legacy-spa.md
Bryce d627e3c5d0 refactor(all): rewrite all behavior docs in table format with checkboxes
Rewrite all 11 remaining behavior documents to match the streamlined
invoice.md format:

- dashboard.md: 250 lines, 62 behaviors
- payment.md: 260 lines, behaviors for list, void, check printing, ACH
- transaction.md: 310 lines, list, import, admin insights
- ledger.md: 519 lines, entries, P&L, balance sheet, cash flows
- company.md: 320 lines, profile, 1099s, Plaid/Yodlee, reports
- admin.md: 494 lines, clients, accounts, vendors, rules, jobs, history
- pos.md: 405 lines, sales, deposits, tenders, refunds, shifts
- search-indicators.md: 167 lines, search modal, indicators
- auth.md: 184 lines, login, logout, impersonation, sessions
- outgoing-invoice.md: 192 lines, create, line items, PDF
- legacy-spa.md: 340 lines, all legacy pages (docs only)

All documents now use:
- Testing Patterns section with reusable abstractions
- Numbered tables: # | Behavior | Test Strategy | Status
- It should... behavior descriptions
- Checkboxes [ ]/[x] for tracking implementation
- Cross-Cutting Behaviors for permissions, lock dates, etc.
- Test Data Requirements tables
- Existing Tests to Preserve sections

Total: 3,844 lines of behavior documentation across 12 subsystem docs.
2026-05-04 13:48:51 -07:00

20 KiB

Legacy SPA Behaviors

Overview

These pages are rendered client-side via Reagent/Re-frame and use GraphQL for data fetching. They are being migrated to HTMX SSR. No UI tests should be written for these pages until migrated.

Testing Philosophy

  • Prefer unit tests for pure business logic (calculations, validations, transformations)
  • Use integration tests for GraphQL queries, mutations, and data flows
  • Use UI tests only after migration to SSR; until then, mark as "UI (when migrated)"
  • Every behavior must be user-visible; no tests for implementation details

Testing Patterns

Pattern: GraphQL Data Fetching

All data fetching uses re-frame graphql effect with JWT token from :user in app-db:

  1. Queries use owns-state to track loading status per page
  2. Results flow through ::data-page/received event which stores data and syncs URL query params
  3. Filter changes are debounced (800ms) via dispatch-debounce

Test implications: Integration test the GraphQL query resolution and response shape. Do not test the re-frame effect machinery.

Pattern: Re-frame State Management

  • Data pages: data-page namespace provides reusable pagination/filtering state
    • ::data-page/params — merged filters + table params + query params
    • ::data-page/data — GraphQL response data
    • ::data-page/checked — selected rows for bulk operations
  • Forms: forms namespace manages edit dialogs with start-form, change-handler, save-succeeded
  • Status: status namespace tracks async operation states (:loading, :complete, :error)

Test implications: Test via integration tests that verify the correct data appears after state transitions. Do not test subscription internals.

Pattern: Client-Side Routing

  • Navbar uses Bidi path-for with routes/routes for legacy SPA links
  • Some navbar items (Payments, POS, Invoices) now link to ssr-routes/only-routes instead
  • Page components dispatch ::mounted on mount and ::unmounted on unmount

Test implications: After migration, integration test route redirects from old SPA routes to new SSR routes.


Home

Dashboard Display

# Behavior Test Strategy Status
1.1 It should display a dashboard with three chart sections: top expense categories, upcoming bills, and cash flow projection UI (when migrated) [ ]
1.2 It should load data for the currently selected client on page load Integration [ ]
1.3 It should display a note: "these reports are for [client]. Please choose a specific customer for their report." when the user has access to multiple clients and has not selected a specific one UI (when migrated) [ ]
1.4 It should display an interactive bar chart for cash flow projection UI (when migrated) [ ]
1.5 It should display a table below the cash flow chart showing invoices, upcoming debits, and upcoming credits with days-until due UI (when migrated) [ ]
1.6 It should allow switching the cash flow range between 7, 30, 60, 90, 120, 150, and 180 days UI (when migrated) [ ]
1.7 Given the user switches the cash flow range, then the chart and table should update to reflect the selected range Integration [ ]
1.8 Given the user clicks a cash flow bar, then it should redirect to the unpaid invoices page for that date UI (when migrated) [ ]
1.9 It should show empty charts gracefully when there is no data for the selected client UI (when migrated) [ ]
1.10 It should show a loading state while GraphQL data is being fetched UI (when migrated) [ ]
1.11 It should handle GraphQL errors by showing the loading state appropriately UI (when migrated) [ ]

Login

Authentication

# Behavior Test Strategy Status
2.1 It should display a "Login with Google" button on the login page UI (when migrated) [ ]
2.2 It should link the login button to Google OAuth UI (when migrated) [ ]
2.3 It should preserve the redirect-to query parameter in the Google OAuth URL Integration [ ]
2.4 It should display a warning notification with the logout reason when the logout-reason query parameter is set UI (when migrated) [ ]
2.5 It should redirect an already authenticated user away from the login page Integration [ ]

Needs Activation

# Behavior Test Strategy Status
2.6 It should display the message: "Sorry, your user is not activated yet. Please have Ben Skinner enable your account." when the user's account is inactive UI (when migrated) [ ]
2.7 It should provide a "here" link that clears user state and redirects to the login page Integration [ ]

Transactions

List Display

# Behavior Test Strategy Status
3.1 It should display a table of transactions with columns for amount, memo, location, approval status, vendor, accounts, date, and description UI (when migrated) [ ]
3.2 It should load the transaction list with a default date filter of the last 1 month Integration [ ]
3.3 It should allow filtering by vendor, account, bank account, date range, amount range, location, import batch, description, and linked status via a sidebar UI (when migrated) [ ]
3.4 It should debounce sidebar filter changes by 800ms before refreshing data Integration [ ]
3.5 It should support pagination with start and per-page parameters Integration [ ]
3.6 It should display checkboxes for row selection when the user is an admin UI (when migrated) [ ]
3.7 It should not display checkboxes or bulk action buttons for non-admin users UI (when migrated) [ ]

Transaction Edit

# Behavior Test Strategy Status
3.8 It should open an edit sidebar when the user clicks a transaction row UI (when migrated) [ ]
3.9 It should allow updating the vendor, approval status, memo, and expense accounts UI (when migrated) [ ]
3.10 It should validate that the sum of expense account amounts equals the transaction amount Unit + Integration [ ]
3.11 It should validate that locations are valid for the selected accounts Unit + Integration [ ]
3.12 It should block editing locked transactions Integration [ ]
3.13 It should display validation errors inline in the edit form UI (when migrated) [ ]

Bulk Operations (Admin)

# Behavior Test Strategy Status
3.14 It should allow deleting selected transactions or all visible transactions Integration [ ]
3.15 It should allow suppressing selected transactions instead of deleting them Integration [ ]
3.16 It should allow bulk coding by applying vendor, account, approval status, and account rules to multiple transactions Integration [ ]
3.17 It should allow importing transactions via a manual Yodlee import dialog Integration [ ]

Route Variants

# Behavior Test Strategy Status
3.18 It should apply the correct default approval status filter for each route variant: all, unapproved, approved, requires-feedback, excluded Integration [ ]

Ledger

General Ledger

# Behavior Test Strategy Status
4.1 It should display a table of journal entries with expandable line items UI (when migrated) [ ]
4.2 It should load the ledger with a default date filter of the last 1 month Integration [ ]
4.3 It should allow filtering by vendor, account, bank account, date range, amount range, and location via a sidebar UI (when migrated) [ ]
4.4 It should support virtual pagination controls Integration [ ]
4.5 It should allow admin users to export filtered results as a CSV download Integration [ ]
4.6 It should display "Not authorized" for users with the manager role UI (when migrated) [ ]

Profit and Loss

# Behavior Test Strategy Status
4.7 It should generate a profit and loss report for a single client with a default period Integration [ ]
4.8 It should allow selecting multiple companies via a multi-select typeahead and generating a combined report UI (when migrated) [ ]
4.9 It should provide period preset buttons: 13 periods, 12 months, last week, week-to-date, last month, month-to-date, year-to-date, last calendar year, and full year UI (when migrated) [ ]
4.10 It should populate the correct date ranges when a period preset is selected Unit [ ]
4.11 It should allow custom period selection via start and end date pickers in advanced mode UI (when migrated) [ ]
4.12 It should optionally include period-over-period deltas UI (when migrated) [ ]
4.13 It should optionally break out the report by location, which is mutually exclusive with including deltas Integration [ ]
4.14 It should allow admin users to generate and download a PDF export Integration [ ]
4.15 It should provide an email composition link for single-client PDF exports UI (when migrated) [ ]
4.16 It should open a ledger detail sidebar when the user clicks a report cell UI (when migrated) [ ]
4.17 It should display "Not authorized" for users with the manager role UI (when migrated) [ ]

Cash Flows

# Behavior Test Strategy Status
4.18 It should generate a cash flows statement report Integration [ ]
4.19 It should use the same company, period, delta, and location column controls as the profit and loss report Integration [ ]
4.20 It should allow admin users to export the report to PDF Integration [ ]
4.21 It should open a ledger detail sidebar when the user clicks a report cell UI (when migrated) [ ]
4.22 It should display "Not authorized" for users with the manager role UI (when migrated) [ ]

Profit and Loss Detail

# Behavior Test Strategy Status
4.23 It should generate a detailed journal entry report with a default 2-week date range Integration [ ]
4.24 It should group journal entries by category: sales, COGS, payroll, controllable, fixed overhead, and ownership controllable Integration [ ]
4.25 It should display Gross Profit, Overhead, and Net Profit summaries UI (when migrated) [ ]
4.26 It should filter journal entries by the selected start and end dates Integration [ ]
4.27 It should allow admin users to export the report to PDF with an email link for single client Integration [ ]
4.28 It should display "Not authorized" for users with the manager role UI (when migrated) [ ]

Balance Sheet

# Behavior Test Strategy Status
4.29 It should generate a balance sheet report as of a specific date Integration [ ]
4.30 It should allow selecting multiple companies and combining them into a single report Integration [ ]
4.31 It should optionally include a prior-year comparison with a side-by-side view UI (when migrated) [ ]
4.32 It should allow admin users to export the report to PDF with an email composition link for single client Integration [ ]
4.33 It should open ledger entries filtered by account and date range when the user clicks a cell UI (when migrated) [ ]
4.34 It should display "Not authorized" for users with the manager role UI (when migrated) [ ]

External Ledger

# Behavior Test Strategy Status
4.35 It should display only externally-imported journal entries with an external_id Integration [ ]
4.36 It should allow admin users to delete selected entries, with a maximum of 1000 at once Integration [ ]
4.37 It should allow admin users to export to CSV Integration [ ]
4.38 It should display "Not authorized" for non-admin users UI (when migrated) [ ]

External Import

# Behavior Test Strategy Status
4.39 It should allow admin users to paste tab-separated data into a textarea UI (when migrated) [ ]
4.40 It should provide a checkbox to indicate whether the first row is a header UI (when migrated) [ ]
4.41 It should parse the pasted data into a table with columns: Id, Client, Source, Vendor, Date, Account, Location, Debit, Credit, Note, and Cleared against Integration [ ]
4.42 It should validate that the client code exists Unit + Integration [ ]
4.43 It should validate that the vendor exists Unit + Integration [ ]
4.44 It should validate that the date is in MM/dd/yyyy format Unit + Integration [ ]
4.45 It should validate that total debits equal total credits Unit + Integration [ ]
4.46 It should validate that all amounts are greater than 0 Unit + Integration [ ]
4.47 It should validate that entries are dated after the client's locked-until date Integration [ ]
4.48 It should validate that the location belongs to the client or is "A" Unit + Integration [ ]
4.49 It should validate that the account exists and the location matches the account's required location Unit + Integration [ ]
4.50 It should display errors per row with a dropdown explanation UI (when migrated) [ ]
4.51 It should show status icons indicating success, ignored, or existing per row after import UI (when migrated) [ ]
4.52 It should display the total success count, ignored count, and error count after import UI (when migrated) [ ]
4.53 It should provide an "Only show errors" filter UI (when migrated) [ ]
4.54 It should display "Not authorized" for non-admin users UI (when migrated) [ ]

Payments

# Behavior Test Strategy Status
5.1 It should be fully migrated to SSR at /payment/; the legacy client route exists only for navbar highlighting N/A [x]

Reports

# Behavior Test Strategy Status
6.1 It should be fully migrated to SSR at /company/reports; the legacy client route exists only for navbar highlighting N/A [x]

Vendors

Admin Vendor Management

# Behavior Test Strategy Status
7.1 It should be fully migrated to SSR at /admin/vendor; the legacy client route exists only for navbar highlighting N/A [x]

New Vendor Dialog

# Behavior Test Strategy Status
7.2 It should load the home dashboard with the vendor creation dialog pre-opened when navigating to /vendor/new UI (when migrated) [ ]
7.3 It should only open the vendor dialog if the user has :vendor :create permission Integration [ ]
7.4 It should allow creating a new vendor with name, terms, address, contacts, and default account UI (when migrated) [ ]
7.5 It should validate that only one terms override exists per client Unit + Integration [ ]
7.6 It should validate that only one schedule payment DOM override exists per client Unit + Integration [ ]
7.7 It should validate that only one account override exists per client Unit + Integration [ ]

Cross-Cutting Behaviors

GraphQL Query Patterns

# Behavior Test Strategy Status
8.1 It should include the JWT token from the :user app-db state in all GraphQL requests Integration [ ]
8.2 It should track loading status per page using owns-state Integration [ ]
8.3 It should store GraphQL response data and sync URL query params via the ::data-page/received event Integration [ ]
8.4 It should debounce filter changes by 800ms before dispatching GraphQL requests Integration [ ]

Re-frame State Management

# Behavior Test Strategy Status
8.5 It should merge filters, table params, and query params into ::data-page/params Integration [ ]
8.6 It should store GraphQL response data in ::data-page/data Integration [ ]
8.7 It should track selected rows for bulk operations in ::data-page/checked Integration [ ]
8.8 It should manage edit dialog state with start-form, change-handler, and save-succeeded events Integration [ ]
8.9 It should track async operation states as :loading, :complete, or :error Integration [ ]

Navigation

# Behavior Test Strategy Status
8.10 It should redirect old SPA routes to new SSR routes after migration Integration [ ]
8.11 It should set up data subscriptions, forward event listeners, and parameter change watchers on page mount Integration [ ]
8.12 It should tear down data subscriptions, forward event listeners, and parameter change watchers on page unmount Integration [ ]

Test Data Requirements

Entity Requirements
Users Admin, power-user, manager, user, and read-only roles
Clients Multiple clients with different locations; some with locked-until dates
Vendors With/without default accounts, terms, and autopay settings
Accounts Expense accounts with/without invoice allowance; different locations
Bank Accounts Check, cash, and credit types
Transactions Various approval statuses, dates, amounts, locked/unlocked states
Journal Entries With/without external_id; various categories and accounts
Invoices Various statuses and due dates for cash flow projections

Existing Tests to Preserve

  • Test GraphQL query resolution for HomeDashboard, TransactionPage, LedgerPage, ProfitAndLoss, CashFlows, JournalDetailReport, BalanceSheet, and ExternalLedger
  • Test re-frame event handlers for data page state transitions
  • Test form validation logic for transaction editing and external ledger import

Dependencies

  • GraphQL API (data fetching)
  • Re-frame/Reagent (client-side state and rendering)
  • Bidi (client-side routing)
  • Recharts (chart rendering on Home page)
  • Server-side PDF generation (P&L, Cash Flows, Balance Sheet, P&L Detail)

Migration Notes

Already Migrated to SSR

  • Payments (/payments/) - Fully migrated to /payment/ SSR routes
  • Reports (/reports/) - Fully migrated to /company/reports SSR routes
  • Admin Vendors (/admin/vendors) - Fully migrated to /admin/vendor SSR routes

Still Legacy SPA (prioritized by complexity)

  1. Transactions - High complexity (filters, edit form, bulk operations, manual import)
  2. Home/Dashboard - Medium complexity (charts, cash flow calculations)
  3. Ledger - Medium complexity (filters, CSV export)
  4. External Ledger - Low-medium complexity (subset of ledger + delete)
  5. External Import - Medium complexity (TSV parsing, validation, batch import)
  6. Profit and Loss - High complexity (multi-company, periods, PDF export)
  7. Cash Flows - High complexity (shares P&L infrastructure)
  8. Profit and Loss Detail - Medium complexity (category filtering, running balances)
  9. Balance Sheet - Medium complexity (comparison mode, drill-down)
  10. Login - Low complexity (static page)
  11. Needs Activation - Low complexity (static page)
  12. New Vendor - Low complexity (dialog on home page)

Migration Risks

  • Chart libraries: Home page uses Recharts (React). Replacement needed for SSR.
  • PDF generation: P&L, Cash Flows, Balance Sheet, P&L Detail all support PDF export via server-side generation.
  • Bulk operations: Transactions page has complex bulk coding/deletion with validation.
  • External import: TSV parsing and validation logic lives entirely in SPA; server-side equivalent needed.