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.
This commit is contained in:
547
docs/testing/behaviors/legacy-spa.md
Normal file
547
docs/testing/behaviors/legacy-spa.md
Normal file
@@ -0,0 +1,547 @@
|
||||
# Legacy SPA Behaviors
|
||||
|
||||
## Overview
|
||||
|
||||
These pages are rendered client-side via Reagent/Re-frame. They use GraphQL for data fetching. They are being migrated to HTMX SSR. Behavior docs exist for reference but **NO UI tests should be written for these pages until migrated**.
|
||||
|
||||
### Architecture
|
||||
- **Routing**: Bidi client-side routes (`src/cljc/auto_ap/client_routes.cljc`)
|
||||
- **State**: Re-frame subscriptions and events
|
||||
- **Data**: GraphQL via custom `graphql` effect (`auto-ap.effects`)
|
||||
- **Permissions**: `auto-ap.permissions/can?` with role-based checks
|
||||
|
||||
### Role Permissions Summary
|
||||
| Role | Transaction Page | Ledger Page | Vendor Create/Edit |
|
||||
|------|-----------------|-------------|-------------------|
|
||||
| admin | full | full | full |
|
||||
| power-user | full | full | full |
|
||||
| manager | full | blocked | full |
|
||||
| user | full | full | full |
|
||||
| read-only | blocked | full | blocked |
|
||||
|
||||
---
|
||||
|
||||
## Pages
|
||||
|
||||
### Home (`/`)
|
||||
|
||||
#### Purpose
|
||||
Dashboard showing financial overview for the selected client: top expense categories (pie chart), upcoming bills (bar chart), and cash flow projection (interactive bar chart with table).
|
||||
|
||||
#### User Flows
|
||||
1. User lands on `/`
|
||||
2. Page loads data for currently selected client
|
||||
3. If user has access to multiple clients, shows note: "these reports are for [client]. Please choose a specific customer for their report."
|
||||
4. User can switch cash flow range: 7/30/60/90/120/150/180 days
|
||||
5. Cash flow bars are clickable and redirect to unpaid invoices for that date
|
||||
|
||||
#### GraphQL Queries Used
|
||||
```graphql
|
||||
query HomeDashboard($clientId: id) {
|
||||
expense_account_stats(client_id: $clientId) {
|
||||
account { id name }
|
||||
total
|
||||
}
|
||||
invoice_stats(client_id: $clientId) {
|
||||
name
|
||||
paid
|
||||
unpaid
|
||||
}
|
||||
cash_flow(client_id: $clientId) {
|
||||
beginning_balance
|
||||
outstanding_payments
|
||||
invoices_due_soon { due outstanding_balance invoice_number vendor { id name } }
|
||||
upcoming_credits { date amount identifier }
|
||||
upcoming_debits { date amount identifier }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Dashboard loads with all three chart sections
|
||||
- **Multi-client note**: Displays when user hasn't selected a specific client
|
||||
- **Cash flow ranges**: Switching between 7-180 day views updates chart and table
|
||||
- **Cash flow table**: Shows invoices, upcoming debits/credits with days-until
|
||||
- **Edge case**: No data for client shows empty charts gracefully
|
||||
- **Error states**: GraphQL errors show loading state appropriately
|
||||
|
||||
---
|
||||
|
||||
### Login (`/login`)
|
||||
|
||||
#### Purpose
|
||||
Authentication page with Google OAuth login.
|
||||
|
||||
#### User Flows
|
||||
1. User visits `/login`
|
||||
2. Shows "Login with Google" button
|
||||
3. Button links to Google OAuth with optional `redirect-to` query param
|
||||
4. After auth failure/logout, may show logout reason notification
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
None.
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Shows login button linking to Google OAuth
|
||||
- **Redirect**: Preserves `redirect-to` query parameter in OAuth URL
|
||||
- **Logout reason**: Displays warning notification when `logout-reason` is set
|
||||
- **Edge case**: Already authenticated user visiting login page
|
||||
|
||||
---
|
||||
|
||||
### Needs Activation (`/needs-activation`)
|
||||
|
||||
#### Purpose
|
||||
Shown when authenticated user's account is not yet activated.
|
||||
|
||||
#### User Flows
|
||||
1. User logs in but account is inactive
|
||||
2. Shows message: "Sorry, your user is not activated yet. Please have Ben Skinner enable your account."
|
||||
3. "here" link clears user state and redirects to login
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
None.
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Shows activation required message
|
||||
- **Relogin link**: Clears user state and redirects to login
|
||||
|
||||
---
|
||||
|
||||
### Transactions (`/transactions/`, `/transactions/unapproved`, `/transactions/approved`, `/transactions/requires-feedback`, `/transactions/excluded`)
|
||||
|
||||
#### Purpose
|
||||
Transaction list with filtering, editing, and bulk admin operations. Different routes show different approval statuses.
|
||||
|
||||
#### User Flows
|
||||
1. User navigates to transactions page
|
||||
2. Default date filter: last 1 month
|
||||
3. Side bar allows filtering by: vendor, account, bank account, date range, amount range, location, import batch, description, linked status
|
||||
4. Table shows transactions with checkbox selection (admin only)
|
||||
5. Clicking row opens edit side bar
|
||||
6. Admin can: bulk code, bulk delete, suppress, or manual Yodlee import
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query TransactionPage($filters: transaction_filters) {
|
||||
transaction_page(filters: $filters) {
|
||||
data {
|
||||
id amount memo location approval_status check_number is_locked
|
||||
matched_rule { note id }
|
||||
vendor { name id }
|
||||
accounts { id amount location account { name id location numeric_code } }
|
||||
date yodlee_merchant { name yodlee_id id } plaid_merchant { name id }
|
||||
post_date expected_deposit { id date } forecast_match { id identifier }
|
||||
status description_original
|
||||
payment { check_number s3_url id date }
|
||||
client { name id }
|
||||
bank_account { name yodlee_account_id current_balance }
|
||||
}
|
||||
total start end count
|
||||
}
|
||||
}
|
||||
|
||||
mutation EditTransaction($transaction: edit_transaction) {
|
||||
edit_transaction(transaction: $transaction) { ... }
|
||||
}
|
||||
|
||||
mutation DeleteTransactions($filters: transaction_filters, $ids: [id], $suppress: Boolean) {
|
||||
delete_transactions(filters: $filters, ids: $ids, suppress: $suppress) { message }
|
||||
}
|
||||
|
||||
mutation BulkCodeTransactions($filters: transaction_filters, $ids: [id], $vendor: id, $approval_status: transaction_approval_status, $accounts: [edit_percentage_account]) {
|
||||
bulk_code_transactions(filters: $filters, ids: $ids, vendor: $vendor, approval_status: $approval_status, accounts: $accounts) { message }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Loads transaction list with default 1-month filter
|
||||
- **Route variants**: Each approval-status route applies correct default filter
|
||||
- **Filtering**: Side bar filters trigger debounced data refresh (800ms)
|
||||
- **Pagination**: Start/per-page params work correctly
|
||||
- **Edit transaction**: Update vendor, approval status, memo, expense accounts
|
||||
- **Edit validation**: Account total must equal transaction amount; locations must be valid
|
||||
- **Bulk delete (admin)**: Delete selected transactions or all visible transactions
|
||||
- **Bulk suppress (admin)**: Mark transactions as suppressed instead of deleting
|
||||
- **Bulk code (admin)**: Apply vendor/account rules to multiple transactions
|
||||
- **Manual import (admin)**: Import transactions via manual Yodlee import dialog
|
||||
- **Error states**: Locked transactions cannot be edited/deleted; validation errors display inline
|
||||
- **Permissions**: Non-admin users don't see checkboxes or action buttons
|
||||
|
||||
---
|
||||
|
||||
### Ledger (`/ledger/`)
|
||||
|
||||
#### Purpose
|
||||
General ledger showing journal entries with line items. Supports filtering and CSV export.
|
||||
|
||||
#### User Flows
|
||||
1. User navigates to `/ledger/`
|
||||
2. Default date filter: last 1 month
|
||||
3. Side bar filters: vendor, account, bank account, date range, amount range, location
|
||||
4. Table shows journal entries with expandable line items
|
||||
5. Admin can export to CSV
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query LedgerPage($filters: ledger_filters) {
|
||||
ledger_page(filters: $filters) {
|
||||
journal_entries {
|
||||
id source original_entity amount note cleared_against alternate_description
|
||||
vendor { name id } client { name id }
|
||||
line_items { id debit credit location running_balance account { id name } }
|
||||
date
|
||||
}
|
||||
total start end
|
||||
}
|
||||
}
|
||||
|
||||
query LedgerCsv($filters: ledger_filters) {
|
||||
ledger_csv(filters: $filters) { csv_content_b64 }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Loads ledger with default 1-month filter
|
||||
- **Filtering**: Date range, vendor, account, location filters work
|
||||
- **CSV export**: Admin can export filtered results as base64 CSV download
|
||||
- **Pagination**: Virtual pagination controls
|
||||
- **Permissions**: Manager role sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### Profit and Loss (`/ledger/profit-and-loss`)
|
||||
|
||||
#### Purpose
|
||||
Financial report showing revenue and expenses over configurable periods. Supports multi-company and PDF export.
|
||||
|
||||
#### User Flows
|
||||
1. User selects companies (multi-select typeahead)
|
||||
2. User selects period preset (13 periods, 12 months, last week, week-to-date, last month, month-to-date, year-to-date, last calendar year, full year)
|
||||
3. Optional: Include deltas, Column per location
|
||||
4. Click "Run" to generate report
|
||||
5. Admin can "Export" to PDF
|
||||
6. Clicking report cells opens ledger detail side bar
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query ProfitAndLoss($clientIds: [id], $periods: [date_range], $includeDeltas: Boolean, $columnPerLocation: Boolean) {
|
||||
profit_and_loss(client_ids: $clientIds, periods: $periods, include_deltas: $includeDeltas, column_per_location: $columnPerLocation) {
|
||||
periods { accounts { name amount client_id account_type id count numeric_code location } }
|
||||
}
|
||||
}
|
||||
|
||||
query ProfitAndLossPdf($clientIds: [id], $periods: [date_range], $includeDeltas: Boolean, $columnPerLocation: Boolean) {
|
||||
profit_and_loss_pdf(...) { url name }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Generate P&L for single client with default period
|
||||
- **Multi-company**: Select multiple clients and generate combined report
|
||||
- **Period presets**: All preset buttons populate correct date ranges
|
||||
- **Advanced mode**: Custom period date pickers
|
||||
- **Include deltas**: Shows period-over-period changes
|
||||
- **Column per location**: Breaks out by location (mutually exclusive with deltas)
|
||||
- **PDF export**: Admin can generate and download PDF; single-client shows email link
|
||||
- **Ledger drill-down**: Clicking cells opens ledger entries side bar for that account/period
|
||||
- **Permissions**: Manager role sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### Cash Flows (`/ledger/cash-flows`)
|
||||
|
||||
#### Purpose
|
||||
Statement of cash flows report. Same control structure as P&L but different report format.
|
||||
|
||||
#### User Flows
|
||||
Same as Profit and Loss but generates cash flow statement.
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query CashFlows($clientIds: [id], $periods: [date_range], $includeDeltas: Boolean, $columnPerLocation: Boolean) {
|
||||
profit_and_loss(client_ids: $clientIds, periods: $periods, include_deltas: $includeDeltas, column_per_location: $columnPerLocation) {
|
||||
periods { accounts { name amount debits credits client_id account_type id count numeric_code location } }
|
||||
}
|
||||
}
|
||||
|
||||
query CashFlowsPdf($clientIds: [id], $periods: [date_range], $includeDeltas: Boolean, $columnPerLocation: Boolean) {
|
||||
cash_flows_pdf(...) { url name }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Generate cash flows report
|
||||
- **Same controls as P&L**: Companies, periods, deltas, location columns
|
||||
- **PDF export**: Admin-only export button
|
||||
- **Ledger drill-down**: Clicking cells opens ledger detail
|
||||
- **Permissions**: Manager role sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### Profit and Loss Detail (`/ledger/profit-and-loss-detail`)
|
||||
|
||||
#### Purpose
|
||||
Detailed journal entry report broken down by category (sales, COGS, payroll, controllable, fixed overhead, ownership controllable).
|
||||
|
||||
#### User Flows
|
||||
1. Select companies
|
||||
2. Select date range (start/end date pickers)
|
||||
3. Click "Run" to generate detail report
|
||||
4. Shows journal entries grouped by category and account with running balances
|
||||
5. Admin can export to PDF
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query JournalDetailReport($clientIds: [id], $dateRange: date_range, $categories: [category]) {
|
||||
journal_detail_report(client_ids: $clientIds, date_range: $dateRange, categories: $categories) {
|
||||
categories {
|
||||
category client_id location
|
||||
account { numeric_code name }
|
||||
journal_entries { description date debit credit location running_balance account { id name } }
|
||||
total
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query JournalDetailReportPdf($clientIds: [id], $dateRange: date_range, $categories: [category]) {
|
||||
journal_detail_report_pdf(...) { url name }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Generate detail report with default 2-week range
|
||||
- **Category breakdown**: Report includes all 6 category sections plus Gross Profit, Overhead, Net Profit summaries
|
||||
- **Date range filtering**: Start/end dates filter journal entries
|
||||
- **PDF export**: Admin can export to PDF with email link for single client
|
||||
- **Permissions**: Manager role sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### Balance Sheet (`/ledger/balance-sheet`)
|
||||
|
||||
#### Purpose
|
||||
Balance sheet report as of a specific date, with optional prior-year comparison.
|
||||
|
||||
#### User Flows
|
||||
1. Select companies
|
||||
2. Select report date
|
||||
3. Optionally enable "Include comparison" and select comparison date
|
||||
4. Click "Run" to generate balance sheet
|
||||
5. Admin can export to PDF
|
||||
6. Clicking cells opens ledger detail side bar
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query BalanceSheet($clientIds: [id], $date: iso_date, $comparisonDate: iso_date, $includeComparison: Boolean) {
|
||||
balance_sheet(client_ids: $clientIds, date: $date, comparison_date: $comparisonDate, include_comparison: $includeComparison) {
|
||||
balance_sheet_accounts { name amount account_type id numeric_code client_id }
|
||||
comparable_balance_sheet_accounts { name amount account_type id client_id numeric_code }
|
||||
}
|
||||
}
|
||||
|
||||
query BalanceSheetPdf($clientIds: [id], $date: iso_date, $comparisonDate: iso_date, $includeComparison: Boolean) {
|
||||
balance_sheet_pdf(...) { url name }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Generate balance sheet for current date
|
||||
- **Comparison mode**: Shows prior period side-by-side
|
||||
- **Multi-company**: Combines multiple clients
|
||||
- **PDF export**: Admin-only with email composition link for single client
|
||||
- **Ledger drill-down**: Clicking cells opens ledger entries filtered by account and date range
|
||||
- **Permissions**: Manager role sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### External Ledger (`/ledger/external`)
|
||||
|
||||
#### Purpose
|
||||
Shows only externally-imported journal entries. Admin can delete entries.
|
||||
|
||||
#### User Flows
|
||||
1. Admin navigates to `/ledger/external`
|
||||
2. Shows external journal entries with external_id
|
||||
3. Can select entries and delete them
|
||||
4. Admin can export to CSV
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
query ExternalLedger($filters: ledger_filters) {
|
||||
ledger_page(filters: $filters) {
|
||||
journal_entries { id external_id source ... }
|
||||
total start end
|
||||
}
|
||||
}
|
||||
|
||||
mutation DeleteExternalLedger($filters: ledger_filters, $ids: [id]) {
|
||||
delete_external_ledger(filters: $filters, ids: $ids) { message }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Loads external-only ledger entries
|
||||
- **Delete**: Admin can delete selected entries (max 1000 at once)
|
||||
- **CSV export**: Same as main ledger
|
||||
- **Permissions**: Admin-only; non-admin sees "Not authorized"
|
||||
|
||||
---
|
||||
|
||||
### External Import (`/ledger/external-import`)
|
||||
|
||||
#### Purpose
|
||||
Manual import of ledger entries via tab-separated text paste.
|
||||
|
||||
#### User Flows
|
||||
1. Admin pastes tab-separated data into textarea
|
||||
2. Optional: indicates whether first row is header
|
||||
3. Click "Parse" to convert to table
|
||||
4. Table shows parsed rows: Id, Client, Source, Vendor, Date, Account, Location, Debit, Credit, Note, Cleared against
|
||||
5. Click "Import" to submit
|
||||
6. Results show: success count, ignored count, error count
|
||||
7. Errors show inline with dropdown explanations
|
||||
8. "Only show errors" filter available
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
mutation ImportLedger($entries: [ledger_entry_input]) {
|
||||
import_ledger(entries: $entries) {
|
||||
successful { external_id }
|
||||
existing { external_id }
|
||||
ignored { external_id }
|
||||
errors { external_id error }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Paste TSV data, parse, import successfully
|
||||
- **Header row**: Checkbox to skip first row
|
||||
- **Validation**: Client code must exist, vendor must exist, date must be MM/dd/yyyy, debits=credits, amounts > 0
|
||||
- **Lock check**: Entries must be after client's locked-until date
|
||||
- **Location validation**: Location must belong to client or be "A"
|
||||
- **Account validation**: Account must exist and location must match account's required location
|
||||
- **Error display**: Errors show per-row with dropdown explanation
|
||||
- **Success/ignored/existing**: Status icons show import result per row
|
||||
- **Permissions**: Admin-only
|
||||
|
||||
---
|
||||
|
||||
### Payments (`/payments/`)
|
||||
|
||||
#### Purpose
|
||||
**Already migrated to SSR.** Legacy client route exists for navbar highlighting only. Actual payments page is served by `payment` SSR routes at `/payment/`.
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
N/A (SSR page)
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
Already migrated. Test via SSR routes.
|
||||
|
||||
---
|
||||
|
||||
### Reports (`/reports/`)
|
||||
|
||||
#### Purpose
|
||||
**Already migrated to SSR.** Legacy client route exists for navbar highlighting only. Actual reports page is served by `company/reports` SSR routes.
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
N/A (SSR page)
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
Already migrated. Test via SSR routes.
|
||||
|
||||
---
|
||||
|
||||
### Admin Vendors (`/admin/vendors`)
|
||||
|
||||
#### Purpose
|
||||
**Already migrated to SSR.** Legacy client route exists for navbar highlighting only. Actual vendor management is served by `admin/vendor` SSR routes.
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
N/A (SSR page)
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
Already migrated. Test via SSR routes.
|
||||
|
||||
---
|
||||
|
||||
### New Vendor (`/vendor/new`)
|
||||
|
||||
#### Purpose
|
||||
Opens the home dashboard with the vendor creation dialog pre-opened.
|
||||
|
||||
#### User Flows
|
||||
1. User navigates to `/vendor/new`
|
||||
2. Loads home dashboard
|
||||
3. Opens vendor dialog if user has `:vendor :create` permission
|
||||
4. Dialog allows creating new vendor with name, terms, address, contacts, default account, etc.
|
||||
|
||||
#### GraphQL Queries/Mutations Used
|
||||
```graphql
|
||||
mutation UpsertVendor($vendor: add_vendor) {
|
||||
upsert_vendor(vendor: $vendor) { id name ... }
|
||||
}
|
||||
```
|
||||
|
||||
#### Behaviors to Test (when migrated)
|
||||
- **Happy path**: Home loads with vendor dialog open
|
||||
- **Permission check**: Dialog only opens if user can `:vendor :create`
|
||||
- **Vendor creation**: Form submission creates vendor via GraphQL mutation
|
||||
- **Validation**: Only one terms override, schedule payment DOM override, and account override per client
|
||||
|
||||
---
|
||||
|
||||
## Cross-Cutting Behaviors
|
||||
|
||||
### GraphQL Query Patterns
|
||||
- All data fetching uses re-frame `graphql` effect with JWT token from `:user` in app-db
|
||||
- Queries use `owns-state` to track loading status per page
|
||||
- Results flow through `::data-page/received` event which stores data and syncs URL query params
|
||||
- Filter changes are debounced (800ms) via `dispatch-debounce`
|
||||
|
||||
### Client-Side State Management (Re-frame)
|
||||
- **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`)
|
||||
|
||||
### Navigation Between Legacy Pages
|
||||
- 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 to set up/tear down:
|
||||
- Data subscriptions
|
||||
- Forward event listeners
|
||||
- Track subscriptions (parameter change watchers)
|
||||
|
||||
---
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### Actively Migrated / Already 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.
|
||||
Reference in New Issue
Block a user