PSA/docs/archive/INVOICE_CONTROLLER_MIGRATION.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

5.5 KiB

Invoice Controller Migration to V2

Summary

Successfully converted the legacy InvoiceController to ApiInvoiceControllerV2 following the established V2 controller pattern used throughout the application.

Changes Made

1. Created ApiInvoiceControllerV2

  • File: /src/lib/api/controllers/ApiInvoiceControllerV2.ts
  • Pattern: Extends ApiBaseControllerV2 for consistent API key authentication
  • Features:
    • Proper tenant isolation with runWithTenant
    • Simplified error handling (no manual try/catch blocks)
    • Built-in authentication and permission checking
    • Support for all invoice operations

2. Converted Controller Methods

All methods from the original InvoiceController were converted to the V2 pattern:

Core CRUD Operations

  • list() - List invoices with advanced filtering
  • getById() - Get invoice details with includes
  • create() - Create new invoice
  • update() - Update existing invoice
  • delete() - Delete invoice

Invoice Generation

  • generateFromBillingCycle() - Generate from billing cycle
  • createManualInvoice() - Create manual invoice
  • previewInvoice() - Preview invoice before generation

Status Transitions

  • finalize() - Finalize invoice (draft → pending)
  • send() - Send invoice to customer
  • approve() - Approve invoice
  • reject() - Reject invoice

Payment Processing

  • recordPayment() - Record payment against invoice
  • applyCredit() - Apply credit to invoice

Document Management

  • generatePDF() - Generate PDF for invoice
  • downloadPDF() - Download invoice PDF

Tax Operations

  • calculateTax() - Calculate tax for invoice items

Bulk Operations

  • bulkUpdateStatus() - Bulk update invoice status
  • bulkSend() - Bulk send invoices
  • bulkDelete() - Bulk delete invoices
  • bulkApplyCredit() - Bulk apply credit

Search and Analytics

  • search() - Advanced invoice search
  • getAnalytics() - Get invoice analytics
  • export() - Export invoices

Recurring Invoices

  • listRecurringTemplates() - List recurring templates
  • createRecurringTemplate() - Create recurring template
  • updateRecurringTemplate() - Update recurring template
  • deleteRecurringTemplate() - Delete recurring template

Invoice Items & Transactions

  • listItems() - List invoice items
  • listTransactions() - List invoice transactions
  • duplicate() - Duplicate invoice

3. Updated All Invoice Routes

Updated 24 invoice route files to use the new V2 controller:

Main Routes

  • /src/app/api/v1/invoices/route.ts
  • /src/app/api/v1/invoices/[id]/route.ts

Specialized Routes

  • /src/app/api/v1/invoices/generate/route.ts
  • /src/app/api/v1/invoices/manual/route.ts
  • /src/app/api/v1/invoices/preview/route.ts
  • /src/app/api/v1/invoices/search/route.ts
  • /src/app/api/v1/invoices/analytics/route.ts
  • /src/app/api/v1/invoices/export/route.ts

Invoice-Specific Operations

  • /src/app/api/v1/invoices/[id]/finalize/route.ts
  • /src/app/api/v1/invoices/[id]/send/route.ts
  • /src/app/api/v1/invoices/[id]/approve/route.ts
  • /src/app/api/v1/invoices/[id]/reject/route.ts
  • /src/app/api/v1/invoices/[id]/payment/route.ts
  • /src/app/api/v1/invoices/[id]/credit/route.ts
  • /src/app/api/v1/invoices/[id]/pdf/route.ts
  • /src/app/api/v1/invoices/[id]/tax/route.ts
  • /src/app/api/v1/invoices/[id]/items/route.ts
  • /src/app/api/v1/invoices/[id]/transactions/route.ts
  • /src/app/api/v1/invoices/[id]/duplicate/route.ts

Bulk Operations

  • /src/app/api/v1/invoices/bulk/route.ts
  • /src/app/api/v1/invoices/bulk/send/route.ts
  • /src/app/api/v1/invoices/bulk/delete/route.ts
  • /src/app/api/v1/invoices/bulk/credit/route.ts

Recurring Invoices

  • /src/app/api/v1/invoices/recurring/route.ts
  • /src/app/api/v1/invoices/recurring/[id]/route.ts

4. Route Pattern Changes

Before (V1 Pattern):

import { InvoiceController } from 'server/src/lib/api/controllers/InvoiceController';
import { handleApiError } from 'server/src/lib/api/middleware/apiMiddleware';

const controller = new InvoiceController();

export async function GET(request: Request) {
  try {
    return await controller.list()(request as any);
  } catch (error) {
    return handleApiError(error);
  }
}

After (V2 Pattern):

import { ApiInvoiceControllerV2 } from 'server/src/lib/api/controllers/ApiInvoiceControllerV2';

const controller = new ApiInvoiceControllerV2();

export async function GET(request: Request) {
  return controller.list()(request as any);
}

5. Removed Legacy Files

  • Deleted /src/lib/api/controllers/InvoiceController.ts
  • Cleaned up temporary migration scripts

Benefits of V2 Migration

  1. Consistent Authentication: All routes now use the same API key authentication pattern
  2. Better Error Handling: Centralized error handling in the base controller
  3. Tenant Isolation: Proper tenant context management with runWithTenant
  4. Cleaner Code: Reduced boilerplate in route handlers
  5. Type Safety: Better TypeScript integration with Zod schemas
  6. Permission Management: Unified permission checking across all endpoints

Verification

  • All 24 invoice route files updated
  • No remaining references to old InvoiceController
  • All invoice schemas properly imported and used
  • Controller follows established V2 pattern
  • TypeScript compilation successful (no invoice-related errors)

Next Steps

The invoice API is now fully migrated to the V2 pattern and ready for use with proper API key authentication and tenant isolation.