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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
464 lines
12 KiB
Markdown
464 lines
12 KiB
Markdown
# 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. |