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

12 KiB

Temporal Workflows for Tenant Management

This project implements Temporal workflows for enterprise tenant creation and management in the Alga PSA system.

Overview

The Temporal workflow system provides reliable, scalable, and observable tenant provisioning with the following capabilities:

  • Tenant Creation: Automated tenant database setup and configuration
  • User Management: Admin user creation with proper role assignment
  • Data Setup: Initial configuration of contract lines, statuses, and preferences
  • Error Handling: Comprehensive rollback mechanisms for failed operations
  • Monitoring: Health checks and workflow state tracking

Architecture

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Client API    │    │  Temporal       │    │   Activities    │
│                 │───▶│  Workflows      │───▶│                 │
│ - REST endpoints│    │                 │    │ - Tenant DB ops │
│ - Validation    │    │ - Orchestration │    │ - User creation │
│ - Auth          │    │ - Error handling│    │ - Data setup    │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                                │
                                ▼
                       ┌─────────────────┐
                       │   Database      │
                       │                 │
                       │ - PostgreSQL    │
                       │ - Tenant data   │
                       │ - User accounts │
                       └─────────────────┘

Project Structure

ee/temporal-workflows/
├── src/
│   ├── workflows/              # Temporal workflow definitions
│   │   ├── tenant-creation-workflow.ts
│   │   └── index.ts
│   ├── activities/             # Activity implementations
│   │   ├── tenant-activities.ts
│   │   ├── user-activities.ts
│   │   └── index.ts
│   ├── types/                  # TypeScript type definitions
│   │   └── workflow-types.ts
│   ├── worker.ts              # Temporal worker process
│   └── client.ts              # Temporal client library
├── k8s/                       # Kubernetes deployment manifests
│   └── deployment.yaml
├── scripts/                   # Deployment and utility scripts
│   └── deploy.sh
├── Dockerfile                 # Container image definition
├── docker-compose.yaml        # Local development setup
└── README.md                  # This file

Quick Start - Local Development

Prerequisites

  • Node.js 20+
  • Temporal CLI (brew install temporal or download from https://temporal.io/downloads)
  • Local PostgreSQL database running (or use the project's Docker containers)

Step-by-Step Local Development Setup

1. Start Local Database (if not already running)

# From project root (~/alga-psa)
docker ps | grep postgres  # Check if already running

# If not running, start the database containers:
docker-compose up -d postgres pgbouncer

2. Start Temporal Dev Server

# In a dedicated terminal, keep this running:
temporal server start-dev

# This starts:
# - Temporal server on port 7233
# - Web UI on port 8233 (http://localhost:8233)
# - Uses SQLite (no external dependencies needed!)

3. Configure Environment

cd ee/temporal-workflows

# Create .env file with the following content:
cat > .env << 'EOF'
# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_NAME_SERVER=server
DB_USER_SERVER=postgres
DB_PASSWORD_SERVER=postpass123
DB_USER_ADMIN=postgres
DB_PASSWORD_ADMIN=postpass123

# Temporal Configuration (using local dev server)
TEMPORAL_ADDRESS=localhost:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_TASK_QUEUE=tenant-workflows

# Auth Key (get from secrets/alga_auth_key)
ALGA_AUTH_KEY=your-auth-key-here

# Logging
LOG_LEVEL=info

# Worker Configuration
MAX_CONCURRENT_ACTIVITIES=10
MAX_CONCURRENT_WORKFLOWS=10

# Health Check
ENABLE_HEALTH_CHECK=true
HEALTH_CHECK_PORT=8080

# Environment
NODE_ENV=development
EOF

# Set the actual auth key
echo "ALGA_AUTH_KEY=$(cat ../../secrets/alga_auth_key 2>/dev/null || echo 'set-your-key')" >> .env

4. Install Dependencies and Build

npm install
npm run build

5. Start the Worker

# Terminal 3: Start the worker
npm run start:worker

6. Test the Worker

# Terminal 4: Run test client
npm run start:client

Quick Commands Reference

# All commands from ee/temporal-workflows directory

# Start everything (assuming port-forwarding is active):
npm run build && npm run start:worker

# Run tests:
npm test                    # Unit tests
npm run test:integration    # Integration tests

# Watch mode for development:
npm run dev                 # If available

# Check worker logs:
docker-compose logs -f temporal-worker  # If using Docker

# View Temporal Web UI (after port-forwarding):
open http://localhost:8088

Troubleshooting

Database Connection Issues

# Verify PostgreSQL is running:
docker ps | grep postgres

# Test connection:
PGPASSWORD=postpass123 psql -h localhost -p 5432 -U postgres -d server -c "SELECT 1"

# If connection fails, check Docker containers:
docker-compose ps
docker-compose up -d postgres pgbouncer

Temporal Connection Issues

# Verify port-forwarding is active:
lsof -i :7233

# Check Temporal service in cluster:
kubectl get svc -n temporal | grep frontend

# Restart port-forwarding:
kubectl port-forward -n temporal svc/temporal-frontend 7233:7233

Missing Environment Variables

# Check required variables are set:
grep -E "DB_|TEMPORAL_|ALGA_AUTH_KEY" .env

# Get auth key from secrets:
cat ../../secrets/alga_auth_key

Build Errors

# Clean and rebuild:
rm -rf dist node_modules
npm install
npm run build

Alternative: Docker Compose Development

If you prefer to use Docker Compose for everything:

Docker Development

  1. Start services with Docker Compose:

    docker-compose up -d
    
  2. View worker logs:

    docker-compose logs -f temporal-worker
    
  3. Run example client:

    docker-compose run --rm temporal-client-example
    

Usage

Starting a Tenant Creation Workflow

import { TenantWorkflowClient } from './src/client';

const client = await TenantWorkflowClient.create();

const { workflowId, result } = await client.startTenantCreation({
  tenantName: 'Acme Corporation',
  adminUser: {
    firstName: 'John',
    lastName: 'Admin',
    email: 'admin@acme.com',
    password: 'securePassword123!'
  },
  companyName: 'Acme Corp',
  contractLine: 'Enterprise'
});

console.log('Workflow started:', workflowId);

const finalResult = await result;
console.log('Tenant created:', finalResult);

Monitoring Workflow State

// Get current workflow state
const state = await client.getTenantCreationState(workflowId);
console.log('Workflow progress:', state.progress + '%');
console.log('Current step:', state.step);

// Cancel a workflow if needed
await client.cancelTenantCreation(workflowId, 'User requested cancellation', 'admin@example.com');

Health Checking

// Verify Temporal connectivity
const health = await client.healthCheck();
console.log('System status:', health.status);

Deployment

Kubernetes Deployment

  1. Build and deploy:

    ./scripts/deploy.sh deploy -t v1.0.0 -r your-registry.com
    
  2. Check status:

    ./scripts/deploy.sh status
    
  3. View logs:

    ./scripts/deploy.sh logs
    
  4. Rollback if needed:

    ./scripts/deploy.sh rollback
    

Configuration

The worker uses environment variables for configuration:

Variable Description Default
TEMPORAL_ADDRESS Temporal server address temporal-frontend.temporal.svc.cluster.local:7233
TEMPORAL_NAMESPACE Temporal namespace default
TEMPORAL_TASK_QUEUE Task queue name tenant-workflows
DATABASE_URL PostgreSQL connection string Required
ADMIN_DATABASE_URL Admin database connection Required
STRIPE_SECRET_KEY Stripe API secret key for billing integration Required for Stripe
MASTER_BILLING_TENANT_ID Nine Minds billing tenant UUID Required for Stripe
LOG_LEVEL Logging level info
MAX_CONCURRENT_ACTIVITIES Max concurrent activities 10
MAX_CONCURRENT_WORKFLOWS Max concurrent workflows 10

Workflow Details

Tenant Creation Workflow

The main workflow (tenantCreationWorkflow) performs these steps:

  1. Validate Input: Check tenant name and admin user details
  2. Create Tenant: Insert tenant record and optional default company
  3. Create Admin User: Set up admin user with proper authentication
  4. Setup Initial Data: Configure roles, statuses, billing, and preferences
  5. Complete: Return tenant and user IDs

Error Handling

The workflow includes comprehensive error handling:

  • Validation Errors: Input validation with clear error messages
  • Database Errors: Transaction rollback and data cleanup
  • Timeout Handling: Configurable timeouts for each activity
  • Retry Logic: Automatic retries with exponential backoff
  • Rollback Operations: Clean removal of partially created data

Signals and Queries

  • Cancel Signal: Gracefully cancel workflow execution
  • Update Signal: Modify workflow parameters during execution
  • State Query: Get current workflow progress and status

Integration

Database Integration

The workflows integrate with the existing Alga PSA database schema:

  • Uses @alga-psa/db utilities for database connections
  • Follows CitusDB compatibility requirements
  • Maintains tenant isolation and security policies
  • Leverages existing action patterns from server/src/lib/actions/

Security

  • Passwords are hashed using the same algorithm as the main application
  • All database operations respect tenant boundaries
  • User permissions are properly configured
  • Admin users get full system access within their tenant

Monitoring

  • Structured logging with Winston
  • Health check endpoints for Kubernetes
  • Temporal Web UI integration for workflow visualization
  • Metrics and alerting support

Testing

Unit Testing

npm test

Integration Testing

npm run test:integration

Load Testing

The system supports horizontal scaling through:

  • Multiple worker instances
  • Configurable concurrency limits
  • Kubernetes HPA for automatic scaling

Troubleshooting

Common Issues

  1. Connection Errors:

    • Verify Temporal server address and connectivity
    • Check network policies and service discovery
  2. Database Errors:

    • Ensure database credentials are correct
    • Verify tenant isolation is properly configured
  3. Workflow Failures:

    • Check Temporal Web UI for detailed execution history
    • Review worker logs for activity failures

Debugging

  1. Enable debug logging:

    export LOG_LEVEL=debug
    
  2. Check Temporal Web UI: https://temporal.nineminds.com

  3. View worker metrics:

    kubectl logs -l app=temporal-workflows-worker -n default
    

Development Guidelines

Adding New Workflows

  1. Create workflow definition in src/workflows/
  2. Implement required activities in src/activities/
  3. Add type definitions in src/types/
  4. Update client interface if needed
  5. Add tests and documentation

Database Operations

  • Always use transaction wrappers from @alga-psa/db
  • Include tenant filtering in all queries
  • Follow CitusDB compatibility patterns
  • Implement proper rollback logic

Error Handling

  • Use specific error types for different failure modes
  • Implement idempotent operations where possible
  • Provide detailed error messages and context
  • Log errors with appropriate severity levels

Contributing

  1. Follow existing code patterns and TypeScript conventions
  2. Add tests for new functionality
  3. Update documentation for API changes
  4. Ensure CitusDB compatibility for database operations
  5. Test deployment with the provided scripts

License

This is part of the Alga PSA enterprise edition. See the main project license for details.