PSA/ee/docs/plans/2025-11-24-tax-system-completion-and-external-passthrough-plan.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

62 KiB
Raw Permalink Blame History

Tax System Completion & External Tax Passthrough Plan

Purpose & Overview

Complete the Alga PSA tax system by exposing existing backend capabilities through UI and implementing an external tax passthrough system that allows accounting packages (Xero, QuickBooks) to handle tax calculations with results imported back into Alga PSA.

Primary outcomes:

  • UI Completion: Expose composite tax components, progressive tax brackets, tax holidays, and client tax exemption features that exist in the backend but lack UI.
  • External Tax Mode: Enable invoices to delegate tax calculation to external accounting systems, import calculated taxes back, and store them as authoritative while preserving internal tax calculation capabilities.
  • Reconciliation Dashboard: Provide visibility into tax source (internal vs external) and any discrepancies between systems.

Discovery Highlights

Current Backend Capabilities (Implemented but Hidden)

Feature Backend Location Status
Composite Tax Components taxSettingsActions.ts:77-95, tax_components table Full CRUD, UI stripped
Progressive Tax Brackets taxSettingsActions.ts:97-115, tax_rate_thresholds table Full CRUD, UI stripped
Tax Holidays taxSettingsActions.ts:117-135, tax_holidays table Full CRUD, UI stripped
Client Tax Exempt Flag clients.is_tax_exempt column Field exists, no UI toggle
Location-Specific Rates client_tax_rates.location_id column Schema ready, not enforced

Code Intentionally Disabled

server/src/components/TaxSettingsForm.tsx:137:

// Removed UI sections for Tax Components, Thresholds, and Holidays (Phase 1.2)

server/src/lib/models/clientTaxSettings.ts:94-129:

// getCompositeTaxComponents() returns [] (commented out)
// getTaxRateThresholds() returns [] (commented out)

Current Accounting Integration Architecture

┌─────────────────┐         ┌──────────────────┐
│   Alga PSA      │ ──────► │  Xero/QuickBooks │
│ (Tax Calculated)│         │ (Receives Tax)   │
└─────────────────┘         └──────────────────┘
       │                            │
       │ Pre-calculated tax         │ Cannot override
       │ amounts sent               │ tax calculations
       └────────────────────────────┘
         ONE-WAY ONLY - NO IMPORT

Key Files Reference

Tax Service & Actions:

  • server/src/lib/services/taxService.ts - Core calculation engine
  • server/src/lib/actions/taxRateActions.ts - Tax rate CRUD
  • server/src/lib/actions/taxSettingsActions.ts - Settings, components, thresholds, holidays
  • server/src/lib/actions/clientTaxRateActions.ts - Client-tax associations
  • server/src/interfaces/tax.interfaces.ts - Type definitions

Tax UI Components:

  • server/src/components/billing-dashboard/TaxRates.tsx - Tax rate management
  • server/src/components/settings/tax/TaxRegionsManager.tsx - Region management
  • server/src/components/TaxSettingsForm.tsx - Client tax settings (stripped)
  • server/src/components/clients/ClientTaxRates.tsx - Client default tax rate

Accounting Integration:

  • server/src/lib/adapters/accounting/accountingExportAdapter.ts - Adapter interface
  • server/src/lib/adapters/accounting/quickBooksOnlineAdapter.ts - QBO implementation
  • server/src/lib/adapters/accounting/xeroAdapter.ts - Xero implementation
  • server/src/lib/services/accountingExportService.ts - Export orchestration

Database Tables:

  • tax_rates - Master tax rate definitions
  • tax_components - Composite tax components
  • tax_rate_thresholds - Progressive tax brackets
  • tax_holidays - Temporary exemption periods
  • client_tax_settings - Per-client tax configuration
  • client_tax_rates - Client-tax rate associations
  • tax_regions - Geographic tax regions

Scope & Deliverables

In Scope

  1. Phase A - UI for Existing Features:

    • Composite tax component editor with sequence and compound controls
    • Progressive tax bracket editor with min/max/rate inputs
    • Tax holiday manager with date-range picker
    • Client tax exempt toggle
    • Tax precedence documentation in UI
  2. Phase B - External Tax Passthrough:

    • Database schema for tax source tracking
    • Export mode that delegates tax to external system
    • Import service to fetch calculated taxes from Xero/QuickBooks
    • Reconciliation UI showing internal vs external tax
  3. Phase C - Integration & Testing:

    • End-to-end tests for all new UI
    • Sandbox tests for external tax import
    • Documentation and admin guides

Out of Scope

  • Automatic tax rate updates from government sources
  • Real-time tax calculation during quote/estimate creation
  • Tax reporting/filing integrations
  • Multi-currency tax handling (deferred)

Phase A UI Implementation for Existing Backend Features

A.1 Re-enable Tax Component Data Fetching

Objective: Restore the data layer that fetches composite tax components from the database.

Files to Modify:

  • server/src/lib/models/clientTaxSettings.ts

Tasks:

  • A.1.1 Uncomment getCompositeTaxComponents() method (lines 94-108)

    • Remove the early return of empty array
    • Ensure query joins tax_components with composite_tax_mappings
    • Return ITaxComponent[] with all fields: tax_component_id, name, rate, sequence, is_compound, start_date, end_date, conditions
  • A.1.2 Uncomment getTaxRateThresholds() method (lines 111-129)

    • Remove the early return of empty array
    • Query tax_rate_thresholds table filtered by tax_rate_id
    • Return ITaxRateThreshold[] with: tax_rate_threshold_id, min_amount, max_amount, rate
  • A.1.3 Verify getTaxHolidays() returns actual data

    • Currently not commented but may not be called
    • Query tax_holidays filtered by tax_component_id
    • Return ITaxHoliday[] with: tax_holiday_id, start_date, end_date, description
  • A.1.4 Add integration test for each data fetching method

    • Create test file: server/src/test/unit/clientTaxSettings.test.ts
    • Seed test data with composite rates, thresholds, and holidays
    • Verify correct data returned

Acceptance Criteria:

  • All three methods return real data from database
  • Existing tax calculation tests still pass
  • New unit tests cover data fetching

A.2 Create Tax Component Editor UI

Objective: Build a UI component for managing composite tax components within a tax rate.

New File:

  • server/src/components/settings/tax/TaxComponentEditor.tsx

Tasks:

  • A.2.1 Create TaxComponentEditor component structure

    interface TaxComponentEditorProps {
      taxRateId: string;
      components: ITaxComponent[];
      onComponentsChange: (components: ITaxComponent[]) => void;
      isReadOnly?: boolean;
    }
    
  • A.2.2 Implement component list display

    • DataTable showing: Name, Rate (%), Sequence, Compound (Yes/No), Date Range
    • Sort by sequence ascending
    • Visual indicator for compound components (icon or badge)
  • A.2.3 Implement "Add Component" functionality

    • Button opens modal/drawer with form fields:
      • Name (required, text input, max 100 chars)
      • Rate (required, number input, 0-100%, 2 decimal places)
      • Sequence (required, integer, auto-increments)
      • Is Compound (checkbox, default false)
      • Start Date (optional, date picker)
      • End Date (optional, date picker)
    • Form validation:
      • Name uniqueness within the tax rate
      • End date must be after start date if both provided
    • Call createTaxComponent() action on submit
  • A.2.4 Implement "Edit Component" functionality

    • Row action to open edit modal with pre-filled values
    • Call updateTaxComponent() action on submit
    • Prevent editing sequence to value already in use
  • A.2.5 Implement "Delete Component" functionality

    • Row action with confirmation dialog
    • Warning if component has tax holidays
    • Call deleteTaxComponent() action on confirm
  • A.2.6 Implement drag-and-drop sequence reordering

    • Allow reordering components via drag handle
    • Update all affected component sequences on drop
    • Batch update via updateTaxComponent() calls
  • A.2.7 Add compound tax calculation preview

    • Show example calculation below the list:
      Example: $100.00 base amount
      Component 1 (VAT 10%): $10.00
      Component 2 (Local 2%, compound): $2.20
      Total Tax: $12.20 (Effective Rate: 12.2%)
      
    • Update preview when components change

Acceptance Criteria:

  • Full CRUD operations work for tax components
  • Sequence ordering is maintained correctly
  • Compound calculation preview matches TaxService.calculateCompositeTax() logic
  • Form validation prevents invalid data entry

A.3 Create Tax Threshold/Bracket Editor UI

Objective: Build a UI component for managing progressive tax brackets within a tax rate.

New File:

  • server/src/components/settings/tax/TaxThresholdEditor.tsx

Tasks:

  • A.3.1 Create TaxThresholdEditor component structure

    interface TaxThresholdEditorProps {
      taxRateId: string;
      thresholds: ITaxRateThreshold[];
      onThresholdsChange: (thresholds: ITaxRateThreshold[]) => void;
      currency: string; // For formatting
      isReadOnly?: boolean;
    }
    
  • A.3.2 Implement threshold list display

    • DataTable showing: Min Amount, Max Amount, Rate (%)
    • Format amounts with currency symbol
    • Show "No limit" or infinity symbol for null max_amount
    • Sort by min_amount ascending
  • A.3.3 Implement "Add Bracket" functionality

    • Button opens modal with form fields:
      • Min Amount (required, currency input, default to previous max + 0.01)
      • Max Amount (optional, currency input, null = unlimited)
      • Rate (required, number input, 0-100%, 2 decimal places)
    • Form validation:
      • Min must be >= 0
      • Max must be > min if provided
      • No overlapping brackets (check against existing)
      • No gaps between brackets (warn user)
    • Call createTaxRateThreshold() action on submit
  • A.3.4 Implement "Edit Bracket" functionality

    • Row action to open edit modal
    • Validate changes don't create overlaps/gaps
    • Call updateTaxRateThreshold() action on submit
  • A.3.5 Implement "Delete Bracket" functionality

    • Row action with confirmation
    • Warn if deletion creates gap in brackets
    • Call deleteTaxRateThreshold() action on confirm
  • A.3.6 Add progressive tax calculation preview

    • Input field for test amount
    • Show bracket-by-bracket breakdown:
      Amount: $75,000.00
      $0 - $10,000 @ 10%: $1,000.00
      $10,000 - $50,000 @ 15%: $6,000.00
      $50,000+ @ 20%: $5,000.00
      Total Tax: $12,000.00 (Effective Rate: 16.0%)
      
    • Update on amount change
  • A.3.7 Add bracket visualization

    • Optional: Visual bar chart showing brackets
    • Color-coded by rate
    • Tooltip on hover showing details

Acceptance Criteria:

  • Full CRUD operations work for thresholds
  • Validation prevents overlapping brackets
  • Preview calculation matches TaxService.calculateThresholdBasedTax() logic
  • Currency formatting respects tenant settings

A.4 Create Tax Holiday Manager UI

Objective: Build a UI component for managing tax holidays (temporary exemption periods).

New File:

  • server/src/components/settings/tax/TaxHolidayManager.tsx

Tasks:

  • A.4.1 Create TaxHolidayManager component structure

    interface TaxHolidayManagerProps {
      taxComponentId: string;
      componentName: string;
      holidays: ITaxHoliday[];
      onHolidaysChange: (holidays: ITaxHoliday[]) => void;
      isReadOnly?: boolean;
    }
    
  • A.4.2 Implement holiday list display

    • DataTable showing: Start Date, End Date, Description, Status
    • Status column: "Active" (current date in range), "Upcoming", "Expired"
    • Sort by start_date descending (most recent first)
    • Visual indicator for currently active holidays
  • A.4.3 Implement "Add Holiday" functionality

    • Button opens modal with form fields:
      • Start Date (required, date picker)
      • End Date (required, date picker)
      • Description (optional, text input, max 255 chars)
    • Form validation:
      • End date must be after start date
      • Warn if overlaps with existing holiday for same component
    • Call createTaxHoliday() action on submit
  • A.4.4 Implement "Edit Holiday" functionality

    • Row action to open edit modal
    • Call updateTaxHoliday() action on submit
  • A.4.5 Implement "Delete Holiday" functionality

    • Row action with confirmation
    • Call deleteTaxHoliday() action on confirm
  • A.4.6 Add calendar view option

    • Toggle between list and calendar view
    • Calendar shows holidays as date ranges
    • Click on holiday to edit
  • A.4.7 Add bulk import from CSV

    • "Import Holidays" button
    • CSV format: start_date, end_date, description
    • Preview before import
    • Batch create via createTaxHoliday() calls

Acceptance Criteria:

  • Full CRUD operations work for holidays
  • Active/upcoming/expired status displays correctly
  • Date validation prevents invalid ranges
  • Calendar view renders holiday periods

A.5 Integrate Advanced Tax Features into Tax Rate Editor

Objective: Add tabs/sections to the existing tax rate editor to expose components, thresholds, and holidays.

Files to Modify:

  • server/src/components/billing-dashboard/TaxRates.tsx
  • Create: server/src/components/billing-dashboard/TaxRateDetailPanel.tsx

Tasks:

  • A.5.1 Create TaxRateDetailPanel wrapper component

    • Receives taxRateId and isComposite props
    • Shows tabbed interface:
      • "Details" tab: Basic rate info (existing form)
      • "Components" tab: TaxComponentEditor (only if is_composite = true)
      • "Brackets" tab: TaxThresholdEditor (optional progressive taxation)
    • Load data for all tabs on mount
  • A.5.2 Add "Is Composite" toggle to tax rate creation form

    • Checkbox: "This is a composite tax with multiple components"
    • When checked, after creation redirect to Components tab
    • Set is_composite: true on the tax rate
  • A.5.3 Add "Use Progressive Brackets" toggle

    • Checkbox: "Use progressive tax brackets based on amount"
    • Mutually exclusive with flat percentage rate
    • When checked, hide percentage field and show Brackets tab
  • A.5.4 Update TaxRates list to show composite/progressive indicators

    • Icon or badge for composite rates
    • Icon or badge for progressive rates
    • Tooltip showing component count or bracket count
  • A.5.5 Add holiday management access from component editor

    • Each component row has "Manage Holidays" action
    • Opens TaxHolidayManager in drawer/modal
    • Shows holiday count badge on action button
  • A.5.6 Add help text explaining tax calculation precedence

    • Info panel explaining:
      1. Client tax exempt flag checked first
      2. Service-specific tax rate used if assigned
      3. Client default tax rate used as fallback
      4. Tax region lookup determines applicable rate
    • Link to documentation

Acceptance Criteria:

  • Tax rate editor shows all advanced options
  • Composite and progressive modes work correctly
  • Users can access holiday management from component list
  • Help text explains precedence clearly

A.6 Add Client Tax Exempt Toggle

Objective: Expose the is_tax_exempt flag on clients in the UI.

Files to Modify:

  • server/src/components/clients/ClientBillingSettings.tsx (or equivalent)
  • server/src/lib/actions/clientActions.ts

Tasks:

  • A.6.1 Add "Tax Exempt" toggle to client billing settings

    • Checkbox: "This client is tax exempt"
    • Below the checkbox, text field: "Tax Exemption Certificate/Reference" (optional)
    • Save updates clients.is_tax_exempt field
  • A.6.2 Create updateClientTaxExemptStatus action

    async function updateClientTaxExemptStatus(
      clientId: string,
      isTaxExempt: boolean,
      exemptionReference?: string
    ): Promise<void>
    
    • Updates clients table
    • Requires billing.update permission
  • A.6.3 Add tax exempt indicator to client list

    • Badge or icon on client row when is_tax_exempt = true
    • Filter option: "Show only tax exempt clients"
  • A.6.4 Add tax exempt indicator to invoice preview/generation

    • When generating invoice for tax exempt client:
      • Show notice: "Client is tax exempt - no tax applied"
      • Ensure TaxService.calculateTax() respects flag
  • A.6.5 Add audit trail for tax exempt changes

    • Log when is_tax_exempt changes
    • Record who made the change and when

Acceptance Criteria:

  • Toggle saves correctly to database
  • Tax calculation respects exempt flag
  • Audit trail captures changes
  • UI indicators show exempt status

A.7 Documentation and Help Integration

Objective: Update documentation to match implemented features and add in-app help.

Tasks:

  • A.7.1 Update docs/international_tax_support.md

    • Remove references to non-existent UI features
    • Add accurate screenshots of new UI
    • Document all tax calculation modes
  • A.7.2 Create in-app help tooltips

    • "What is a composite tax?" tooltip
    • "What are progressive tax brackets?" tooltip
    • "When should I use tax holidays?" tooltip
  • A.7.3 Add tax setup wizard/guide

    • Step-by-step guide for common scenarios:
      1. Simple flat tax (e.g., 10% VAT)
      2. Composite tax (e.g., GST + PST)
      3. Progressive tax (e.g., income-based brackets)
    • Link from tax settings page
  • A.7.4 Document tax precedence rules

    • Clear documentation of:
      • Client exempt > Service rate > Client default > Region lookup
    • Include flowchart diagram

Acceptance Criteria:

  • Documentation matches actual functionality
  • Help tooltips provide useful context
  • Setup wizard covers common use cases

Phase B External Tax Passthrough System

B.1 Database Schema for External Tax Support

Objective: Add fields to track tax source and store externally-calculated tax amounts.

New Migration File:

  • server/migrations/YYYYMMDDHHMMSS_add_external_tax_support.cjs

Tasks:

  • B.1.1 Add tax_source column to invoices table

    ALTER TABLE invoices
    ADD COLUMN tax_source VARCHAR(20) DEFAULT 'internal'
    CHECK (tax_source IN ('internal', 'external', 'pending_external'));
    
    COMMENT ON COLUMN invoices.tax_source IS
      'Source of tax calculation: internal (Alga), external (accounting package), pending_external (awaiting import)';
    
  • B.1.2 Add external tax fields to invoice_charges table

    ALTER TABLE invoice_charges
    ADD COLUMN external_tax_amount INTEGER,
    ADD COLUMN external_tax_code VARCHAR(50),
    ADD COLUMN external_tax_rate DECIMAL(5,2);
    
    COMMENT ON COLUMN invoice_charges.external_tax_amount IS
      'Tax amount calculated by external accounting system (in cents)';
    
  • B.1.3 Add tax delegation settings to tenant_settings table

    ALTER TABLE tenant_settings
    ADD COLUMN default_tax_source VARCHAR(20) DEFAULT 'internal',
    ADD COLUMN allow_external_tax_override BOOLEAN DEFAULT false,
    ADD COLUMN external_tax_adapter VARCHAR(50);
    
    COMMENT ON COLUMN tenant_settings.default_tax_source IS
      'Default tax calculation source for new invoices';
    
  • B.1.4 Add client-level tax source override

    ALTER TABLE client_tax_settings
    ADD COLUMN tax_source_override VARCHAR(20),
    ADD COLUMN external_tax_adapter_override VARCHAR(50);
    
    COMMENT ON COLUMN client_tax_settings.tax_source_override IS
      'Per-client override of tenant tax source setting';
    
  • B.1.5 Create external_tax_imports tracking table

    CREATE TABLE external_tax_imports (
      import_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
      tenant UUID NOT NULL REFERENCES tenants(tenant),
      invoice_id UUID NOT NULL REFERENCES invoices(invoice_id),
      adapter_type VARCHAR(50) NOT NULL,
      external_invoice_ref VARCHAR(255),
      imported_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      imported_by UUID REFERENCES users(user_id),
      import_status VARCHAR(20) DEFAULT 'success',
      original_internal_tax INTEGER,
      imported_external_tax INTEGER,
      tax_difference INTEGER,
      metadata JSONB,
      created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );
    
    CREATE INDEX idx_external_tax_imports_invoice
      ON external_tax_imports(invoice_id);
    CREATE INDEX idx_external_tax_imports_tenant
      ON external_tax_imports(tenant);
    
  • B.1.6 Create rollback migration

    • Remove all added columns and tables
    • Ensure clean rollback path
  • B.1.7 Update TypeScript interfaces

    • Add new fields to IInvoice, IInvoiceCharge, ITenantSettings, IClientTaxSettings
    • Create IExternalTaxImport interface

Acceptance Criteria:

  • Migration runs successfully on fresh and existing databases
  • Rollback works cleanly
  • TypeScript interfaces match schema
  • Default values preserve existing behavior

B.2 Tax Source Selection UI

Objective: Allow users to configure tax delegation at tenant, client, and invoice levels.

New Files:

  • server/src/components/settings/tax/TaxSourceSettings.tsx
  • server/src/components/invoices/InvoiceTaxSourceBadge.tsx

Tasks:

  • B.2.1 Create tenant-level tax source settings UI

    • Radio buttons: "Internal (Alga PSA)", "External (Accounting Package)"
    • When External selected:
      • Dropdown: "Select Accounting System" (QuickBooks Online, Xero, etc.)
      • Warning: "Tax will be calculated by {system} and imported back"
    • Save to tenant_settings
  • B.2.2 Create client-level tax source override UI

    • Add to client billing settings
    • Options: "Use Tenant Default", "Internal", "External"
    • When External selected, show adapter dropdown
    • Save to client_tax_settings
  • B.2.3 Create invoice-level tax source indicator

    • Badge component showing: "Tax: Internal", "Tax: External", "Tax: Pending Import"
    • Tooltip explaining the source
    • Color-coded: Green (internal), Blue (external), Orange (pending)
  • B.2.4 Add tax source selection to manual invoice creation

    • When creating manual invoice:
      • Show tax source dropdown (inherits from client default)
      • Allow override per invoice
    • Set invoices.tax_source on creation
  • B.2.5 Update invoice detail view to show tax source

    • Add tax source badge to invoice header
    • If external, show "Imported from {system} on {date}"
    • Link to import history

Acceptance Criteria:

  • Settings save correctly at each level
  • Inheritance chain works: Invoice -> Client -> Tenant
  • Visual indicators clearly show tax source
  • Users understand implications of each setting

B.3 Export Adapter Modifications for Tax Delegation

Objective: Modify accounting export adapters to support exporting invoices without tax (pending external calculation).

Files to Modify:

  • server/src/lib/adapters/accounting/accountingExportAdapter.ts
  • server/src/lib/adapters/accounting/quickBooksOnlineAdapter.ts
  • server/src/lib/adapters/accounting/xeroAdapter.ts

Tasks:

  • B.3.1 Extend adapter capabilities interface

    export interface AccountingExportAdapterCapabilities {
      deliveryMode: 'api' | 'file';
      supportsPartialRetry: boolean;
      supportsInvoiceUpdates: boolean;
      supportsTaxDelegation: boolean;        // NEW
      supportsInvoiceFetch: boolean;         // NEW
      supportsTaxComponentImport: boolean;   // NEW
    }
    
  • B.3.2 Add tax delegation mode to transform context

    export interface AccountingExportAdapterContext {
      batch: AccountingExportBatch;
      lines: AccountingExportLine[];
      taxDelegationMode: 'include_tax' | 'exclude_tax' | 'zero_tax';  // NEW
    }
    
  • B.3.3 Modify QBO adapter transform for tax delegation

    • When taxDelegationMode === 'exclude_tax':
      • Set TaxCodeRef to the mapped code (for compliance)
      • Set line amounts WITHOUT tax
      • Add metadata flag: taxDelegated: true
    • When taxDelegationMode === 'zero_tax':
      • Use "Tax Exempt" or equivalent tax code
      • External system will apply its own tax
  • B.3.4 Modify Xero adapter transform for tax delegation

    • When taxDelegationMode === 'exclude_tax':
      • Set LineAmountType: 'Exclusive'
      • Map to appropriate Xero tax code
      • Let Xero calculate tax
    • Store Xero invoice ID for later fetch
  • B.3.5 Add post-export callback for pending imports

    • After successful export with tax delegation:
      • Update invoice: tax_source = 'pending_external'
      • Store external document reference
      • Queue import job (or manual trigger)
  • B.3.6 Add adapter method for invoice fetch

    interface AccountingExportAdapter {
      // ... existing methods
      fetchInvoice?(externalRef: string): Promise<ExternalInvoiceData | null>;
    }
    

Acceptance Criteria:

  • Adapters correctly handle tax delegation mode
  • Invoices export without tax when configured
  • External references stored for import
  • Invoice status updated to pending_external

B.4 External Tax Import Service

Objective: Create service to fetch invoices from external systems and import calculated tax amounts.

New Files:

  • server/src/lib/services/externalTaxImportService.ts
  • server/src/lib/adapters/accounting/taxImportAdapter.ts

Tasks:

  • B.4.1 Create ExternalTaxImportService class

    export class ExternalTaxImportService {
      async importTaxForInvoice(invoiceId: string): Promise<ExternalTaxImportResult>;
      async batchImportPendingTaxes(): Promise<BatchImportResult>;
      async getImportHistory(invoiceId: string): Promise<IExternalTaxImport[]>;
      async reconcileTaxDifferences(invoiceId: string): Promise<ReconciliationResult>;
    }
    
  • B.4.2 Implement QBO invoice fetch

    • Use QboClientService to fetch invoice by external ref
    • Extract per-line tax amounts from response:
      interface QboInvoiceTaxData {
        invoiceId: string;
        totalTax: number;
        lines: Array<{
          lineId: string;
          description: string;
          amount: number;
          taxAmount: number;
          taxCode: string;
          taxRate: number;
        }>;
      }
      
    • Match QBO lines to Alga invoice charges
  • B.4.3 Implement Xero invoice fetch

    • Use XeroClientService to fetch invoice
    • Extract tax data from Xero response format
    • Handle multi-component taxes (GST + PST etc.)
  • B.4.4 Implement tax amount import logic

    async importTaxForInvoice(invoiceId: string): Promise<ExternalTaxImportResult> {
      // 1. Get invoice and verify tax_source = 'pending_external'
      // 2. Get adapter based on invoice's export batch
      // 3. Fetch invoice from external system
      // 4. Match external lines to invoice_charges
      // 5. Update invoice_charges.external_tax_amount
      // 6. Update invoice.tax_source = 'external'
      // 7. Recalculate invoice.tax total
      // 8. Record import in external_tax_imports table
      // 9. Return result with any discrepancies
    }
    
  • B.4.5 Implement line matching algorithm

    • Primary match: Use stored external line reference
    • Fallback match: Match by description + amount
    • Handle partial matches with warning
    • Report unmatched lines as errors
  • B.4.6 Implement batch import for pending invoices

    async batchImportPendingTaxes(): Promise<BatchImportResult> {
      // 1. Query invoices with tax_source = 'pending_external'
      // 2. Group by adapter type
      // 3. Import each group (with rate limiting)
      // 4. Return summary: success count, failure count, errors
    }
    
  • B.4.7 Create reconciliation logic

    • Compare internal tax calculation with imported external tax
    • Flag invoices with >1% difference
    • Store both values for audit
  • B.4.8 Add API endpoints

    POST /api/invoices/{id}/import-external-tax
    POST /api/invoices/batch-import-external-tax
    GET /api/invoices/{id}/external-tax-history
    

Acceptance Criteria:

  • Tax import works for QBO and Xero
  • Line matching handles edge cases
  • Discrepancies are tracked and flagged
  • Batch import handles large volumes

B.5 External Tax Import UI

Objective: Build UI for managing external tax imports and viewing import history.

New Files:

  • server/src/components/invoices/ExternalTaxImportPanel.tsx
  • server/src/components/invoices/TaxReconciliationView.tsx

Tasks:

  • B.5.1 Create "Import External Tax" button on invoice detail

    • Only visible when tax_source = 'pending_external'
    • Button: "Import Tax from {System}"
    • Shows loading state during import
    • Displays success/error toast on completion
  • B.5.2 Create import history panel

    • Shows list of imports for invoice
    • Columns: Date, System, Status, Internal Tax, External Tax, Difference
    • Click to expand shows line-by-line comparison
  • B.5.3 Create batch import dashboard

    • Card showing: "X invoices pending external tax import"
    • "Import All" button triggers batch import
    • Progress indicator during batch import
    • Results summary when complete
  • B.5.4 Create tax reconciliation view

    • Side-by-side comparison:
      • Left: Alga internal calculation
      • Right: External system calculation
    • Per-line breakdown
    • Highlight differences
    • Action: "Accept External Tax" or "Keep Internal Tax"
  • B.5.5 Add reconciliation alerts

    • Dashboard widget: "X invoices have tax discrepancies"
    • Link to reconciliation queue
    • Filter by discrepancy amount
  • B.5.6 Create tax source history timeline

    • Visual timeline showing:
      • Invoice created (internal tax)
      • Exported to {system}
      • Tax imported from {system}
      • Any reconciliation actions

Acceptance Criteria:

  • Users can import external tax with one click
  • Import history provides full audit trail
  • Reconciliation view clearly shows differences
  • Batch operations handle large volumes

B.6 Invoice Flow Updates

Objective: Update invoice generation and finalization flows to support external tax mode.

Files to Modify:

  • server/src/lib/services/invoiceService.ts
  • server/src/lib/billing/billingEngine.ts

Tasks:

  • B.6.1 Update invoice generation to check tax source setting

    // In invoice generation:
    const taxSource = await getTaxSourceForClient(clientId);
    if (taxSource === 'external') {
      // Generate invoice with tax_source = 'pending_external'
      // Set tax amounts to 0 (or skip calculation)
      // Flag for export
    } else {
      // Existing internal tax calculation
    }
    
  • B.6.2 Add validation for invoice finalization with pending tax

    • Block finalization if tax_source = 'pending_external'
    • Show error: "Import external tax before finalizing"
    • Allow override with confirmation
  • B.6.3 Update invoice total calculation

    // When tax_source = 'external':
    invoice.tax = sumOfExternalTaxAmounts();
    // When tax_source = 'internal':
    invoice.tax = sumOfInternalTaxAmounts();
    
  • B.6.4 Add tax source to invoice preview

    • Show which tax calculation mode will be used
    • If external, show: "Tax will be calculated by {system}"
  • B.6.5 Handle tax source changes after creation

    • Allow changing tax source on draft invoices
    • Recalculate tax based on new source
    • Warn if changing from external (loses imported data)
  • B.6.6 Update invoice PDF/email to show tax source

    • Add note on invoice: "Tax calculated by {system}" when external
    • Include in audit section

Acceptance Criteria:

  • Invoice generation respects tax source settings
  • Finalization blocks on pending external tax
  • Totals calculate correctly for both modes
  • Preview clearly shows tax calculation mode

B.7 Accounting Export Service Updates

Objective: Integrate external tax mode into the existing accounting export workflow.

Files to Modify:

  • server/src/lib/services/accountingExportService.ts
  • server/src/lib/validation/accountingExportValidation.ts

Tasks:

  • B.7.1 Add tax delegation mode to batch creation

    interface CreateExportBatchOptions {
      // ... existing fields
      taxDelegationMode?: 'include_tax' | 'delegate_tax';
    }
    
  • B.7.2 Update validation for tax delegation exports

    • When delegate_tax:
      • Validate adapter supports tax delegation
      • Validate all lines have valid tax code mappings
      • Skip internal tax amount validation
  • B.7.3 Add post-delivery tax import scheduling

    • After successful delivery with tax delegation:
      • Option 1: Queue automatic import after delay (configurable)
      • Option 2: Send notification to import manually
    • Record scheduled import in batch metadata
  • B.7.4 Add export status for tax-delegated batches

    • New status: awaiting_tax_import
    • Transitions: delivered -> awaiting_tax_import -> tax_imported -> posted
  • B.7.5 Create export batch tax import action

    • "Import Taxes for Batch" action on export batch
    • Triggers ExternalTaxImportService.batchImportPendingTaxes() for batch invoices
  • B.7.6 Update batch summary to show tax import status

    • Column: "Tax Status" (N/A, Pending Import, Imported, Discrepancy)
    • Count of invoices in each status

Acceptance Criteria:

  • Tax delegation integrates with existing export flow
  • Post-delivery import can be automatic or manual
  • Batch status reflects tax import state
  • Summary provides clear visibility

Phase C Testing and Documentation

C.1 Unit Tests for Tax UI Components

New Test Files:

  • server/src/test/components/TaxComponentEditor.test.tsx
  • server/src/test/components/TaxThresholdEditor.test.tsx
  • server/src/test/components/TaxHolidayManager.test.tsx

Tasks:

  • C.1.1 Test TaxComponentEditor

    • Renders component list correctly
    • Add component form validation
    • Edit component updates list
    • Delete component with confirmation
    • Sequence reordering works
    • Compound calculation preview accurate
  • C.1.2 Test TaxThresholdEditor

    • Renders threshold list correctly
    • Add bracket validation (no overlaps)
    • Edit bracket updates list
    • Delete bracket with confirmation
    • Progressive calculation preview accurate
  • C.1.3 Test TaxHolidayManager

    • Renders holiday list correctly
    • Add holiday date validation
    • Status calculation (active/upcoming/expired)
    • Calendar view renders
  • C.1.4 Test TaxSourceSettings

    • Tenant setting saves correctly
    • Client override saves correctly
    • Inheritance chain works

Acceptance Criteria:

  • All UI components have >80% coverage
  • Validation edge cases covered
  • Accessibility tests pass

C.2 Integration Tests for External Tax Import

New Test Files:

  • server/src/test/integration/externalTaxImport.test.ts
  • server/src/test/integration/taxDelegationExport.test.ts

Tasks:

  • C.2.1 Test tax delegation export flow

    • Create invoice with external tax source
    • Export with tax delegation mode
    • Verify external system receives correct data
    • Verify invoice status updated to pending_external
  • C.2.2 Test external tax import flow

    • Mock external system invoice response
    • Import tax for invoice
    • Verify invoice_charges updated
    • Verify invoice.tax recalculated
    • Verify import history recorded
  • C.2.3 Test line matching scenarios

    • Exact match by reference
    • Fallback match by description
    • Partial match handling
    • Unmatched line handling
  • C.2.4 Test reconciliation scenarios

    • Matching tax amounts
    • Small discrepancy (<1%)
    • Large discrepancy (>1%)
    • Accept/reject actions
  • C.2.5 Test batch import

    • Multiple invoices pending
    • Mixed success/failure
    • Rate limiting
    • Error recovery

Acceptance Criteria:

  • All integration paths tested
  • Edge cases covered
  • Error scenarios handled

C.3 Sandbox Testing with External Systems

Tasks:

  • C.3.1 QBO Sandbox testing

    • Set up QBO sandbox company
    • Test tax delegation export
    • Test invoice fetch
    • Test tax import
    • Document sandbox credentials handling
  • C.3.2 Xero Demo Company testing

    • Set up Xero demo company
    • Test tax delegation export
    • Test invoice fetch
    • Test multi-component tax import
    • Document sandbox credentials handling
  • C.3.3 Create test fixtures

    • Sample invoices for export
    • Mock external system responses
    • Expected import results
  • C.3.4 Performance testing

    • Batch import with 100+ invoices
    • Concurrent import handling
    • Memory usage monitoring

Acceptance Criteria:

  • Both QBO and Xero sandbox tests pass
  • Test fixtures created for CI
  • Performance acceptable for large batches

C.4 Documentation

Tasks:

  • C.4.1 Update docs/international_tax_support.md

    • Add sections for:
      • Composite tax components
      • Progressive tax brackets
      • Tax holidays
      • External tax passthrough
    • Remove references to non-existent features
    • Add accurate screenshots
  • C.4.2 Create docs/external_tax_integration.md

    • Overview of external tax mode
    • Setup guide for each accounting system
    • Tax delegation export process
    • Tax import process
    • Reconciliation workflow
    • Troubleshooting guide
  • C.4.3 Create admin guide

    • How to configure tax source settings
    • How to manage composite taxes
    • How to set up progressive brackets
    • How to handle tax discrepancies
    • Best practices
  • C.4.4 Update API documentation

    • New endpoints for external tax
    • Request/response examples
    • Error codes
  • C.4.5 Create release notes template

    • Summary of new features
    • Migration steps for existing tenants
    • Breaking changes (if any)
    • Known limitations

Acceptance Criteria:

  • Documentation complete and accurate
  • Screenshots match current UI
  • API docs include all new endpoints
  • Release notes ready for publication

Appendix A: Database Schema Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                           TAX SYSTEM SCHEMA                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────┐         ┌─────────────────────┐                    │
│  │   tax_regions   │         │     tax_rates       │                    │
│  │─────────────────│         │─────────────────────│                    │
│  │ region_code (PK)│◄────────│ region_code (FK)    │                    │
│  │ region_name     │         │ tax_rate_id (PK)    │                    │
│  │ is_active       │         │ tax_type            │                    │
│  │ tenant          │         │ tax_percentage      │                    │
│  └─────────────────┘         │ is_composite        │                    │
│                              │ start_date          │                    │
│                              │ end_date            │                    │
│                              │ tenant              │                    │
│                              └──────────┬──────────┘                    │
│                                         │                                │
│                    ┌────────────────────┼────────────────────┐          │
│                    │                    │                    │          │
│                    ▼                    ▼                    ▼          │
│  ┌─────────────────────┐  ┌─────────────────────┐  ┌─────────────────┐ │
│  │   tax_components    │  │tax_rate_thresholds  │  │client_tax_rates │ │
│  │─────────────────────│  │─────────────────────│  │─────────────────│ │
│  │ tax_component_id(PK)│  │ threshold_id (PK)   │  │ client_id (FK)  │ │
│  │ tax_rate_id (FK)    │  │ tax_rate_id (FK)    │  │ tax_rate_id(FK) │ │
│  │ name                │  │ min_amount          │  │ is_default      │ │
│  │ rate                │  │ max_amount          │  │ location_id     │ │
│  │ sequence            │  │ rate                │  │ tenant          │ │
│  │ is_compound         │  │ tenant              │  └─────────────────┘ │
│  │ start_date          │  └─────────────────────┘                      │
│  │ end_date            │                                                │
│  │ tenant              │                                                │
│  └──────────┬──────────┘                                                │
│             │                                                            │
│             ▼                                                            │
│  ┌─────────────────────┐                                                │
│  │    tax_holidays     │                                                │
│  │─────────────────────│                                                │
│  │ tax_holiday_id (PK) │                                                │
│  │ tax_component_id(FK)│                                                │
│  │ start_date          │                                                │
│  │ end_date            │                                                │
│  │ description         │                                                │
│  └─────────────────────┘                                                │
│                                                                          │
│  ┌─────────────────────┐         ┌─────────────────────────────────┐   │
│  │client_tax_settings  │         │    external_tax_imports         │   │
│  │─────────────────────│         │─────────────────────────────────│   │
│  │ client_id (FK)      │         │ import_id (PK)                  │   │
│  │ is_reverse_charge   │         │ invoice_id (FK)                 │   │
│  │ tax_source_override │ [NEW]   │ adapter_type                    │   │
│  │ external_adapter    │ [NEW]   │ external_invoice_ref            │   │
│  │ tenant              │         │ imported_at                     │   │
│  └─────────────────────┘         │ original_internal_tax           │   │
│                                  │ imported_external_tax           │   │
│  ┌─────────────────────┐         │ tax_difference                  │   │
│  │      invoices       │         │ tenant                          │   │
│  │─────────────────────│         └─────────────────────────────────┘   │
│  │ invoice_id (PK)     │                                                │
│  │ tax_source          │ [NEW: internal/external/pending_external]     │
│  │ tax                 │                                                │
│  │ ...                 │                                                │
│  └─────────────────────┘                                                │
│                                                                          │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                      invoice_charges                             │   │
│  │─────────────────────────────────────────────────────────────────│   │
│  │ item_id (PK)                                                     │   │
│  │ invoice_id (FK)                                                  │   │
│  │ tax_amount              (internal calculation)                   │   │
│  │ tax_region                                                       │   │
│  │ tax_rate                                                         │   │
│  │ external_tax_amount     [NEW] (external calculation)             │   │
│  │ external_tax_code       [NEW]                                    │   │
│  │ external_tax_rate       [NEW]                                    │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Appendix B: External Tax Flow Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                     EXTERNAL TAX PASSTHROUGH FLOW                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. INVOICE CREATION                                                     │
│  ┌──────────────────┐                                                   │
│  │ Check tax_source │                                                   │
│  │ setting          │                                                   │
│  └────────┬─────────┘                                                   │
│           │                                                              │
│     ┌─────┴─────┐                                                       │
│     │           │                                                       │
│     ▼           ▼                                                       │
│  ┌──────┐   ┌──────────┐                                               │
│  │INTERNAL│  │ EXTERNAL │                                               │
│  └───┬───┘   └────┬─────┘                                               │
│      │            │                                                      │
│      ▼            ▼                                                      │
│  ┌─────────┐  ┌─────────────────┐                                       │
│  │Calculate │  │Set tax_source = │                                       │
│  │tax via   │  │pending_external │                                       │
│  │TaxService│  │tax_amount = 0   │                                       │
│  └─────────┘  └────────┬────────┘                                       │
│                        │                                                 │
│  2. EXPORT TO ACCOUNTING SYSTEM                                         │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ Export with taxDelegationMode =     │                                │
│  │ 'delegate_tax'                      │                                │
│  │                                      │                                │
│  │ Adapter sends invoice WITHOUT tax    │                                │
│  │ External system calculates tax       │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│  3. TAX IMPORT                                                          │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ ExternalTaxImportService            │                                │
│  │                                      │                                │
│  │ 1. Fetch invoice from ext system    │                                │
│  │ 2. Extract tax amounts per line     │                                │
│  │ 3. Match to invoice_charges         │                                │
│  │ 4. Update external_tax_amount       │                                │
│  │ 5. Set tax_source = 'external'      │                                │
│  │ 6. Recalculate invoice total        │                                │
│  │ 7. Record in external_tax_imports   │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│  4. RECONCILIATION (if needed)                                          │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ Compare internal vs external tax    │                                │
│  │                                      │                                │
│  │ If difference > threshold:          │                                │
│  │   - Flag for review                 │                                │
│  │   - Show reconciliation UI          │                                │
│  │   - Allow accept/reject             │                                │
│  └─────────────────────────────────────┘                                │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Appendix C: Tax Calculation Precedence

┌─────────────────────────────────────────────────────────────────────────┐
│                     TAX CALCULATION PRECEDENCE                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  START: Calculate tax for invoice line                                   │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 1. Check invoice.tax_source         │                                │
│  │    If 'external' -> use external_tax│                                │
│  │    If 'pending' -> tax = 0          │                                │
│  │    If 'internal' -> continue        │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 2. Check client.is_tax_exempt       │                                │
│  │    If TRUE -> tax = 0               │                                │
│  │    If FALSE -> continue             │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 3. Check invoice_charge.is_taxable  │                                │
│  │    If FALSE -> tax = 0              │                                │
│  │    If TRUE -> continue              │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 4. Check service.tax_rate_id        │                                │
│  │    If SET -> use service tax rate   │                                │
│  │    If NULL -> continue              │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 5. Check client default tax rate    │                                │
│  │    (from client_tax_rates)          │                                │
│  │    If SET -> use client tax rate    │                                │
│  │    If NULL -> continue              │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 6. Look up by tax_region            │                                │
│  │    (from invoice_charge.tax_region) │                                │
│  │    Query tax_rates for region       │                                │
│  │    Apply date-based filtering       │                                │
│  └─────────────────────┬───────────────┘                                │
│                        │                                                 │
│                        ▼                                                 │
│  ┌─────────────────────────────────────┐                                │
│  │ 7. Calculate tax                    │                                │
│  │    - Simple: amount * rate          │                                │
│  │    - Composite: sum components      │                                │
│  │    - Progressive: bracket calc      │                                │
│  │    - Check tax holidays             │                                │
│  └─────────────────────────────────────┘                                │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Appendix D: File Reference Index

Tax Backend Files

File Purpose
server/src/lib/services/taxService.ts Core tax calculation engine
server/src/lib/actions/taxRateActions.ts Tax rate CRUD operations
server/src/lib/actions/taxSettingsActions.ts Settings, components, thresholds, holidays CRUD
server/src/lib/actions/clientTaxRateActions.ts Client-tax rate associations
server/src/lib/models/clientTaxSettings.ts Data fetching (needs uncommenting)
server/src/interfaces/tax.interfaces.ts Type definitions

Tax UI Files

File Purpose
server/src/components/billing-dashboard/TaxRates.tsx Tax rate list/editor
server/src/components/settings/tax/TaxRegionsManager.tsx Region management
server/src/components/TaxSettingsForm.tsx Client tax settings (stripped)
server/src/components/clients/ClientTaxRates.tsx Client default tax rate
server/src/components/clients/TaxRateCreateForm.tsx Inline tax rate creation

Accounting Integration Files

File Purpose
server/src/lib/adapters/accounting/accountingExportAdapter.ts Adapter interface
server/src/lib/adapters/accounting/quickBooksOnlineAdapter.ts QBO implementation
server/src/lib/adapters/accounting/xeroAdapter.ts Xero implementation
server/src/lib/services/accountingExportService.ts Export orchestration
server/src/lib/services/accountingMappingResolver.ts Entity mapping resolution

New Files to Create

File Purpose
server/src/components/settings/tax/TaxComponentEditor.tsx Composite tax component editor
server/src/components/settings/tax/TaxThresholdEditor.tsx Progressive bracket editor
server/src/components/settings/tax/TaxHolidayManager.tsx Tax holiday manager
server/src/components/settings/tax/TaxSourceSettings.tsx Tax source configuration
server/src/components/invoices/ExternalTaxImportPanel.tsx External tax import UI
server/src/components/invoices/TaxReconciliationView.tsx Reconciliation comparison
server/src/lib/services/externalTaxImportService.ts External tax import service
server/migrations/XXXXXX_add_external_tax_support.cjs Schema migration

Revision History

Date Version Author Changes
2025-11-24 1.0 Claude Initial plan creation