PSA/docs/archive/contact-api-e2e-test-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

9.9 KiB

Contact REST API E2E Testing Plan

Introduction

This document outlines the plan for implementing end-to-end (e2e) tests for the Contact REST API endpoints in the Alga PSA application. The tests will use Vitest as the testing framework and establish patterns for API testing that can be extended to other endpoints.

Table of Contents

  1. Introduction
  2. Table of Contents
  3. Phased Implementation Plan
  4. Discovered Details

Phased Implementation Plan

Phase 1: Create Test Utilities for API Testing

  • Create /server/src/test/e2e/utils/apiTestHelpers.ts
    • Implement API client wrapper for making authenticated requests
    • Create test data factories for contacts
    • Add database setup/cleanup utilities
  • Run initial test to verify utilities work correctly

Phase 2: Create Contact API E2E Test Suite

  • Create /server/src/test/e2e/api/contacts.e2e.test.ts
    • Add authentication tests (missing/invalid API key)
    • Implement CRUD operation tests (create, read, update, delete)
    • Add list contacts with pagination tests
    • Create search functionality tests
    • Add export functionality tests
    • Implement statistics endpoint tests
    • Add error handling tests (404s, validation errors)
    • Create permission check tests (placeholders)

Phase 3: Test Infrastructure Setup

  • Configure setup/teardown for database state
  • Implement test user and API key creation
  • Add response validation against schemas
  • Ensure edge cases and error scenarios are covered

Phase 4: Dependencies and Configuration

  • Evaluate need for additional testing libraries (e.g., supertest)
  • Enhance database test utilities if needed
  • Update test scripts if necessary
  • Run final test suite to ensure everything works with any new dependencies
  • Run tests in CI environment (if applicable) to verify they work in automated pipelines

Phase 5: Test Execution and API Implementation COMPLETED

  • Verify Contact API routes are implemented
  • Run Contact API e2e tests against actual endpoints
  • Fix any failing tests by:
    • Implementing missing API endpoints if needed
    • Adjusting test expectations to match actual API behavior
    • Fixing API authentication middleware issues
      • Created new ApiKeyServiceForApi to avoid circular dependencies
      • Created ApiBaseControllerV2 with simplified authentication flow
      • Updated all contact routes to use new controller
    • Fixing permission issues in test setup
      • Created proper permission records for test users
      • Fixed tenant context in permission checks
      • Corrected method names in service calls
  • Run full test suite multiple times to ensure stability
  • Document any API changes or discoveries
  • Final test run - 25 out of 30 tests passing

Final Status:

  • All contact API routes are implemented and functional
  • API key authentication is working correctly
  • Permission system is properly integrated
  • 25 out of 30 tests passing (83% success rate)
  • ⚠️ 5 tests still failing (edge cases in validation and error handling)

Discovered Details

Contact API Endpoints

The Contact API is located at /api/v1/contacts/ with the following endpoints:

  1. GET /api/v1/contacts - List contacts with pagination
  2. POST /api/v1/contacts - Create new contact
  3. GET /api/v1/contacts/:id - Get contact by ID
  4. PUT /api/v1/contacts/:id - Update contact
  5. DELETE /api/v1/contacts/:id - Delete contact
  6. GET /api/v1/contacts/search - Advanced search functionality
  7. GET /api/v1/contacts/export - Export contacts (supports CSV/JSON formats)
  8. GET /api/v1/contacts/stats - Get contact statistics

Current Test Setup

  • Test Framework: Vitest is configured in /server/vitest.config.ts
  • Test Script: Available via npm run test:local
  • Test Utilities: Exist in /server/test-utils/ directory
  • Current State: No existing E2E tests found - this will be the first API e2e test suite

Authentication

  • API uses authentication via x-api-key header
  • Test suite will need to handle API key generation and validation

Key Findings

  1. This will establish the first E2E API test pattern for the project
  2. The implementation will serve as a template for testing other API endpoints
  3. All contact endpoints are RESTful and follow standard patterns
  4. The test suite will need to handle multi-tenant scenarios based on the database structure
  5. Tests should follow the coding standards outlined in /home/coder/alga-psa/docs/AI_coding_standards.md

Controller Migration Guide: BaseController to ApiBaseControllerV2

Overview

The codebase is migrating from the older BaseController pattern (with middleware composition) to the newer ApiBaseControllerV2 pattern (with inline authentication). Here's a comprehensive guide for migration.

Key Differences

1. Middleware vs Inline Authentication

  • Old (BaseController): Uses compose() with middleware functions (withAuth, withPermission, etc.)
  • New (ApiBaseControllerV2): All authentication/validation logic is inline within each method

2. Route Export Pattern

  • Old: export async function GET(request: Request) { try { ... } catch { ... } }
  • New: export const GET = controller.method();

3. Error Handling

  • Old: Manual try-catch in route files with handleApiError
  • New: Error handling built into controller methods

Migration Checklist

When migrating a controller from BaseController to ApiBaseControllerV2:

1. Create New V2 Controller

// Old: extends BaseController
export class TagController extends BaseController { ... }

// New: extends ApiBaseControllerV2
export class ApiTagControllerV2 extends ApiBaseControllerV2 { ... }

2. Convert Methods

  • Remove middleware composition (compose())
  • Add authentication at start: const apiRequest = await this.authenticate(req);
  • Wrap logic in runWithTenant()
  • Add permission check: await this.checkPermission(apiRequest, 'action');
  • Handle validation inline
  • Keep the same return format (createSuccessResponse, createPaginatedResponse)

3. Handle Async ID Extraction

CRITICAL: The extractIdFromPath() method is now async in V2!

// Old (sync)
const id = this.extractIdFromPath(req);

// New (async) - MUST await!
const id = await this.extractIdFromPath(apiRequest);

4. Update Route Files

For each route file:

// Old pattern
import { TagController } from '.../TagController';
import { handleApiError } from '.../apiMiddleware';

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

// New pattern
import { ApiTagControllerV2 } from '@/lib/api/controllers/ApiTagControllerV2';

const controller = new ApiTagControllerV2();

export const GET = controller.list();
export const POST = controller.create();

5. Common Method Name Mappings

When migrating custom methods, consider shorter names for V2:

  • searchTags()search()
  • getTagAnalytics()analytics()
  • getTagCloud()cloud()
  • updateTagColors()updateColors()

6. Delete Status Codes

V2 controllers should return 204 (No Content) for DELETE operations:

// Override delete in V2 controller
delete() {
  return async (req: NextRequest): Promise<NextResponse> => {
    // ... authentication and checks ...
    await this.service.delete(id, context);
    return new NextResponse(null, { status: 204 });
  };
}

7. Complex Path Parameters

For routes with multiple path parameters (e.g., /entity/[entityType]/[entityId]):

const url = new URL(req.url);
const pathParts = url.pathname.split('/');
const entityIndex = pathParts.indexOf('entity');
const entityType = pathParts[entityIndex + 1];
const entityId = pathParts[entityIndex + 2];

Common Pitfalls to Avoid

  1. Forgetting to await extractIdFromPath() - This causes UUID parsing errors
  2. Not updating all route files - Check all routes under /api/v1/{resource}/
  3. Missing method overrides - Some methods like delete() need custom implementations
  4. Incorrect route syntax - Use export const not export async function
  5. Not removing the old controller - Delete after migration is complete

Testing Migration Success

  1. Run the e2e tests for the resource (if they exist)
  2. Check for TypeScript errors: npm run typecheck
  3. Test each endpoint manually or with the test suite
  4. Verify error responses return proper status codes
  5. Ensure authentication and permissions work correctly

Migration Status Tracking

Controllers successfully migrated to V2:

  • ContactController → ApiContactControllerV2
  • CompanyController → ApiCompanyControllerV2
  • UserController → ApiUserControllerV2
  • TeamController → ApiTeamControllerV2
  • ProjectController → ApiProjectControllerV2
  • TicketController → ApiTicketControllerV2
  • RoleController → ApiRoleControllerV2
  • PermissionController → ApiPermissionControllerV2
  • TimeEntryController → ApiTimeEntryControllerV2
  • TagController → ApiTagControllerV2

Controllers still using BaseController pattern:

  • AssetController
  • AutomationController
  • ContractLineController
  • CategoryController
  • FinancialController
  • InvoiceController
  • MetadataController
  • PermissionRoleController
  • QuickBooksController
  • TimeSheetController
  • WebhookController
  • WorkflowController