# 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) ```bash # 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 ```bash # 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 ```bash 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 ```bash npm install npm run build ``` #### 5. Start the Worker ```bash # Terminal 3: Start the worker npm run start:worker ``` #### 6. Test the Worker ```bash # Terminal 4: Run test client npm run start:client ``` ### Quick Commands Reference ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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**: ```bash docker-compose up -d ``` 2. **View worker logs**: ```bash docker-compose logs -f temporal-worker ``` 3. **Run example client**: ```bash docker-compose run --rm temporal-client-example ``` ## Usage ### Starting a Tenant Creation Workflow ```typescript 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 ```typescript // 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 ```typescript // Verify Temporal connectivity const health = await client.healthCheck(); console.log('System status:', health.status); ``` ## Deployment ### Kubernetes Deployment 1. **Build and deploy**: ```bash ./scripts/deploy.sh deploy -t v1.0.0 -r your-registry.com ``` 2. **Check status**: ```bash ./scripts/deploy.sh status ``` 3. **View logs**: ```bash ./scripts/deploy.sh logs ``` 4. **Rollback if needed**: ```bash ./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 ```bash npm test ``` ### Integration Testing ```bash 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**: ```bash export LOG_LEVEL=debug ``` 2. **Check Temporal Web UI**: https://temporal.nineminds.com 3. **View worker metrics**: ```bash 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.