PSA/ee/docs/plans/2025-08-05-email-system-refactor.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

13 KiB

/# Email System Refactoring Plan

Intro / Rationale

Executive Summary

The current email system has duplicate implementations and lacks clear separation between system-level emails and tenant-specific business emails. This refactoring will establish a clear architectural pattern that distinguishes between:

  • System Emails: Platform-level emails (user registration, password reset, system notifications) using environment variables
  • Tenant Emails: Business-specific emails (portal invitations, invoices, project notifications) using database-configured settings

Business and Technical Drivers

  • Code Duplication: Two separate EmailService implementations exist with overlapping functionality
  • Architectural Confusion: Email verification incorrectly uses TenantEmailService when it should use system settings
  • Maintenance Overhead: Scattered email logic makes updates and bug fixes difficult
  • Scalability Issues: No clear pattern for adding new email types

Success Criteria

  • Single, clear EmailService implementation for system emails using environment variables
  • Properly separated TenantEmailService for business emails using database settings
  • Email verification and password reset using SystemEmailService
  • Portal invitations and business emails continue using TenantEmailService
  • Clear documentation and examples for future development

Key Stakeholders

  • Development team implementing new email features
  • Operations team managing email configuration
  • End users receiving system and business emails

Phased Implementation Checklist

Phase 1: System Email Service Consolidation

Goal: Create unified SystemEmailService for all platform-level emails

  • Task 1.1: Create new directory structure
    • Create /src/lib/email/system/ directory
    • Create /src/lib/email/tenant/ directory
  • Task 1.2: Consolidate duplicate EmailService implementations
    • Analyze differences between /src/services/emailService.ts and /src/lib/notifications/emailService.ts
    • Create unified SystemEmailService.ts in /src/lib/email/system/
    • Implement environment variable configuration exclusively
    • Add comprehensive logging and error handling
  • Task 1.3: Create system email templates
    • Move system templates to /src/lib/email/system/templates/
    • Create emailVerification.ts template
    • Create passwordReset.ts template
    • Create systemNotification.ts template
  • Task 1.4: Create system email types
    • Create /src/lib/email/system/types.ts with SystemEmailOptions interface
    • Define SystemEmailConfig interface
    • Export template interfaces

Dependencies: None
Completion Criteria: SystemEmailService can send emails using environment variables, all system templates are available

Phase 2: Tenant Email Service Migration

Goal: Move and enhance existing TenantEmailService to new structure

  • Task 2.1: Move TenantEmailService to new location
    • Move TenantEmailService.ts to /src/lib/email/tenant/
    • Move templateProcessors.ts to /src/lib/email/tenant/
    • Update all import paths referencing moved files
  • Task 2.2: Enhance TenantEmailService documentation
    • Add comprehensive JSDoc comments explaining tenant email purpose
    • Document when to use TenantEmailService vs SystemEmailService
    • Add usage examples in code comments
  • Task 2.3: Create tenant email types
    • Create /src/lib/email/tenant/types.ts
    • Move tenant-specific interfaces from existing files
    • Ensure clear separation from system email types

Dependencies: Phase 1 completion
Completion Criteria: TenantEmailService is in new location with enhanced documentation, all imports updated

Phase 3: Email Function Updates

Goal: Update specific email functions to use correct service

  • Task 3.1: Update email verification to use SystemEmailService
    • Modify /src/lib/email/sendVerificationEmail.ts to import SystemEmailService
    • Replace TenantEmailService.sendEmail() call with SystemEmailService
    • Update template processor to use system templates
    • Test email verification flow works with environment variables
  • Task 3.2: Ensure password reset uses SystemEmailService
    • Locate password reset email functions
    • Update to use SystemEmailService instead of any tenant service calls
    • Verify password reset templates are in system templates directory
  • Task 3.3: Verify portal invitations continue using TenantEmailService
    • Confirm /src/lib/email/sendPortalInvitationEmail.ts uses TenantEmailService
    • Update import paths to new tenant service location
    • Test portal invitation flow still works correctly

Dependencies: Phase 2 completion
Completion Criteria: Email verification and password reset use SystemEmailService, portal invitations use TenantEmailService

Phase 4: Email Service Factory and Integration

Goal: Create centralized factory and update integration points

  • Task 4.1: Create email service factory
    • Create /src/lib/email/index.ts as main entry point
    • Export getSystemEmailService() function
    • Export getTenantEmailService() function
    • Re-export key types and interfaces
  • Task 4.2: Update application integration points
    • Update all files importing old EmailService locations
    • Replace direct service instantiation with factory functions
    • Update API routes and actions to use correct email service
  • Task 4.3: Clean up old implementations
    • Remove /src/services/emailService.ts after confirming no references
    • Remove /src/lib/notifications/emailService.ts after confirming no references
    • Remove /src/utils/email/emailService.tsx if unused

Dependencies: Phase 3 completion
Completion Criteria: Single entry point for email services, old implementations removed, all imports updated

Phase 5: Documentation and Guidelines

Goal: Create comprehensive documentation for email system usage

  • Task 5.1: Create main email documentation
    • Create /src/lib/email/README.md with comprehensive guidelines
    • Document when to use SystemEmailService vs TenantEmailService
    • Provide code examples for common email scenarios

Dependencies: Phase 4 completion
Completion Criteria: Complete documentation available, clear guidelines for future development

Background Details / Investigation / Implementation Advice

Current System Analysis

Duplicate EmailService Implementations

Two separate EmailService classes exist:

  1. /src/services/emailService.ts:

    • Uses both environment variables and database templates
    • Includes invoice email functionality
    • Has comprehensive logging and error handling
    • Contains template fallback logic
  2. /src/lib/notifications/emailService.ts:

    • Uses environment variables exclusively
    • Includes Handlebars template compilation
    • Simpler implementation focused on notifications

Key Issues Identified

  • Email verification uses TenantEmailService but should use system settings
  • Template storage is inconsistent (hardcoded vs database)
  • No clear naming convention to distinguish email types
  • Import paths are scattered across different directories

Technical Implementation Guidelines

SystemEmailService Requirements

  • Configuration: Environment variables only (EMAIL_HOST, EMAIL_PORT, EMAIL_USERNAME, EMAIL_PASSWORD, EMAIL_FROM)
  • Templates: Static templates in code or system template table
  • Use Cases: User registration, password reset, system alerts, platform notifications
  • Initialization: Singleton pattern with lazy initialization
  • Error Handling: Comprehensive logging with diagnostic information

TenantEmailService Requirements

  • Configuration: Database-stored tenant email settings
  • Templates: Database templates with tenant-specific customization
  • Use Cases: Portal invitations, invoices, project notifications, business communications
  • Provider Support: Multiple email provider configurations per tenant
  • Template Processing: Support for complex template data and variables

Directory Structure Implementation

/src/lib/email/
├── index.ts                    # Main factory and exports
├── README.md                   # Comprehensive documentation
├── system/
│   ├── SystemEmailService.ts  # Environment-based email service
│   ├── templates/
│   │   ├── emailVerification.ts
│   │   ├── passwordReset.ts
│   │   └── systemNotification.ts
│   └── types.ts               # System email interfaces
└── tenant/
    ├── TenantEmailService.ts  # Database-based email service
    ├── templateProcessors.ts  # Template processing logic
    └── types.ts               # Tenant email interfaces

Migration Strategy

  1. Preserve Functionality: Ensure zero downtime during migration
  2. Gradual Transition: Update services one at a time with testing
  3. Import Path Updates: Use find-replace to update import statements systematically
  4. Template Migration: Move templates without changing their content initially

Testing Approach

  • Test system emails with environment variable configuration
  • Test tenant emails with database configuration
  • Verify email verification flow uses system service
  • Verify portal invitations use tenant service
  • Test error handling for missing configuration

Potential Pitfalls and Solutions

Pitfall: Breaking existing email functionality during migration
Solution: Update one service at a time, maintain parallel implementations during transition

Pitfall: Template references breaking after file moves
Solution: Update all import paths in single atomic operation, use IDE refactoring tools

Pitfall: Configuration conflicts between system and tenant emails
Solution: Clearly separate configuration sources, add validation for each service type

Pitfall: Missing error handling in new implementations
Solution: Copy comprehensive error handling from existing services, add diagnostic logging

Code Examples

SystemEmailService Usage

import { getSystemEmailService } from '@/lib/email';

const emailService = await getSystemEmailService();
await emailService.sendVerificationEmail({
  to: 'user@example.com',
  templateData: { verificationUrl: 'https://...' }
});

TenantEmailService Usage

import { getTenantEmailService } from '@/lib/email';

const result = await TenantEmailService.sendEmail({
  tenantId: 'tenant-123',
  to: 'client@company.com',
  templateProcessor: new DatabaseTemplateProcessor(knex, 'portal-invitation'),
  templateData: { portalLink: 'https://...' }
});

Resources and References

  • Current TenantEmailService implementation: /src/lib/services/TenantEmailService.ts
  • Email provider management: /src/services/email/EmailProviderManager.ts
  • Template processing: /src/lib/services/email/templateProcessors.ts
  • Email types: /src/types/email.types.ts

Implementer's Scratch Pad

Progress Tracking

  • Phase 1 started: ___________
  • Phase 1 completed: ___________
  • Phase 2 started: ___________
  • Phase 2 completed: ___________
  • Phase 3 started: ___________
  • Phase 3 completed: ___________
  • Phase 4 started: ___________
  • Phase 4 completed: ___________
  • Phase 5 started: ___________
  • Phase 5 completed: ___________

Implementation Notes

Phase 1 Notes:
- SystemEmailService consolidation status: 
- Template migration status:
- Environment variable testing:

Phase 2 Notes:
- TenantEmailService move status:
- Import path updates:
- Documentation additions:

Phase 3 Notes:
- Email verification update status:
- Password reset verification:
- Portal invitation testing:

Phase 4 Notes:
- Factory implementation:
- Integration point updates:
- Cleanup completion:

Phase 5 Notes:
- Documentation completeness:
- Example code validation:
- Final review status:

Issues Encountered and Resolutions

Issue 1: [Description]
Resolution: [How resolved]
Impact: [Impact on timeline/scope]

Issue 2: [Description]  
Resolution: [How resolved]
Impact: [Impact on timeline/scope]

Deviations From Original Plan

Deviation 1: [What changed]
Reason: [Why it changed]
Approval: [Who approved change]

Deviation 2: [What changed]
Reason: [Why it changed]  
Approval: [Who approved change]

Performance Metrics and Test Results

Email Verification Tests:
- System service configuration: [PASS/FAIL]
- Template rendering: [PASS/FAIL]
- Email delivery: [PASS/FAIL]

Portal Invitation Tests:
- Tenant service configuration: [PASS/FAIL]
- Database template retrieval: [PASS/FAIL]
- Email delivery: [PASS/FAIL]

Integration Tests:
- Import path updates: [PASS/FAIL]
- Service factory: [PASS/FAIL]
- Error handling: [PASS/FAIL]

Questions for Review

1. [Question about implementation approach]
2. [Question about configuration]
3. [Question about testing strategy]