PSA/ee/docs/tenant-onboarding.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

389 lines
9.9 KiB
Markdown

# Tenant Onboarding Process
## Overview
The tenant onboarding process is a fully automated workflow that provisions new tenants in the Alga PSA system. This process uses Temporal workflows to ensure reliability, consistency, and proper error handling throughout the tenant creation process.
## Architecture
### Components
- **Temporal Workflows**: Orchestrate the multi-step tenant creation process
- **Database Operations**: Handle tenant, user, and company creation in PostgreSQL
- **Email Service**: Send welcome emails to new admin users
- **Rollback System**: Automatic cleanup in case of failures
### Key Files
- `ee/temporal-workflows/src/workflows/tenant-creation-workflow.ts` - Main workflow orchestration
- `ee/temporal-workflows/src/db/tenant-operations.ts` - Database operations for tenant setup
- `ee/temporal-workflows/src/db/user-operations.ts` - User creation and management
- `ee/temporal-workflows/src/services/email-service.ts` - Email notification service
## Workflow Steps
### 1. Tenant Creation (`creating_tenant`)
- Creates tenant record in `tenants` table
- Optionally creates company record in `companies` table
- Establishes tenant-company relationship
- **Progress**: 10% → 40%
### 2. Admin User Creation (`creating_admin_user`)
- Creates admin user in `users` table
- Assigns admin role via `user_roles` table
- Generates temporary password
- **Progress**: 40% → 60%
### 3. Tenant Data Setup (`setting_up_data`)
- Configures tenant email settings in `tenant_email_settings`
- Sets up tenant-company associations in `tenant_companies`
- Initializes default configurations
- **Progress**: 60% → 85%
### 4. Welcome Email (`sending_welcome_email`)
- Sends welcome email to admin user
- Includes login credentials and setup instructions
- **Progress**: 85% → 100%
## Database Schema
### Core Tables
```sql
-- Tenant record
tenants (
tenant VARCHAR PRIMARY KEY,
company_name VARCHAR,
email VARCHAR,
created_at TIMESTAMP,
updated_at TIMESTAMP
)
-- Company record
companies (
company_id VARCHAR PRIMARY KEY,
company_name VARCHAR,
tenant VARCHAR REFERENCES tenants(tenant),
created_at TIMESTAMP,
updated_at TIMESTAMP
)
-- Admin user
users (
user_id VARCHAR PRIMARY KEY,
tenant VARCHAR REFERENCES tenants(tenant),
first_name VARCHAR,
last_name VARCHAR,
email VARCHAR,
password_hash VARCHAR,
created_at TIMESTAMP,
updated_at TIMESTAMP
)
-- User roles
user_roles (
user_id VARCHAR REFERENCES users(user_id),
role_id VARCHAR,
tenant VARCHAR REFERENCES tenants(tenant),
created_at TIMESTAMP,
updated_at TIMESTAMP
)
-- Email settings
tenant_email_settings (
tenant_id VARCHAR,
email_provider VARCHAR DEFAULT 'resend',
fallback_enabled BOOLEAN DEFAULT true,
tracking_enabled BOOLEAN DEFAULT false,
created_at TIMESTAMP,
updated_at TIMESTAMP
)
-- Tenant-company associations
tenant_companies (
tenant VARCHAR REFERENCES tenants(tenant),
company_id VARCHAR REFERENCES companies(company_id),
is_default BOOLEAN DEFAULT false,
created_at TIMESTAMP,
updated_at TIMESTAMP
)
```
## API Usage
### Starting a Tenant Creation Workflow
```typescript
import { Client } from '@temporalio/client';
const client = new Client({ address: 'localhost:7233' });
const result = await client.workflow.start('tenantCreationWorkflow', {
workflowId: `tenant-creation-${Date.now()}`,
taskQueue: 'tenant-creation',
args: [{
tenantName: 'Acme Corp',
adminUser: {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@acme.com'
},
companyName: 'Acme Corporation',
contractLine: 'professional'
}]
});
// Monitor progress
const handle = client.workflow.getHandle(result.workflowId);
const state = await handle.query('getState');
console.log('Current step:', state.step, 'Progress:', state.progress + '%');
```
### Input Parameters
```typescript
interface TenantCreationInput {
tenantName: string; // Display name for the tenant
adminUser: {
firstName: string;
lastName: string;
email: string; // Admin user email (also used for tenant)
};
companyName?: string; // Optional company name
contractLine?: string; // Optional contract line (default: 'basic')
}
```
### Output Results
```typescript
interface TenantCreationResult {
tenantId: string; // Generated tenant ID
adminUserId: string; // Generated admin user ID
companyId?: string; // Generated company ID (if applicable)
temporaryPassword: string; // Temporary password for admin user
emailSent: boolean; // Whether welcome email was sent
success: boolean; // Overall success status
createdAt: string; // ISO timestamp of completion
}
```
## Error Handling & Rollback
### Automatic Rollback
The workflow includes comprehensive rollback mechanisms:
1. **User Rollback**: Removes user records and role assignments
2. **Tenant Rollback**: Removes tenant, company, and associated data
3. **Cascade Cleanup**: Handles foreign key relationships properly
### Error Types
- **ValidationError**: Invalid input data (non-retryable)
- **DuplicateError**: Tenant/user already exists (non-retryable)
- **DatabaseError**: Connection or query issues (retryable)
- **EmailError**: Email service failures (retryable)
### Retry Policy
```typescript
retry: {
maximumAttempts: 3,
backoffCoefficient: 2.0,
initialInterval: '1s',
maximumInterval: '30s',
nonRetryableErrorTypes: ['ValidationError', 'DuplicateError']
}
```
## Monitoring & Observability
### Workflow State Queries
```typescript
// Get current workflow state
const state = await handle.query('getState');
// State includes:
// - step: Current workflow step
// - progress: Completion percentage (0-100)
// - tenantId: Created tenant ID
// - adminUserId: Created admin user ID
// - companyId: Created company ID
// - emailSent: Email delivery status
// - error: Error message (if failed)
```
### Workflow Signals
```typescript
// Cancel workflow
await handle.signal('cancel', {
reason: 'User requested cancellation',
cancelledBy: 'admin@example.com'
});
// Update workflow parameters
await handle.signal('update', {
field: 'contractLine',
value: 'enterprise'
});
```
## Testing
### E2E Tests
The system includes comprehensive end-to-end tests:
```bash
# Run all E2E tests
cd ee/temporal-workflows
npm run test:e2e
# Run specific tenant creation test
npm run test:e2e -- tenant-creation-workflow.e2e.test.ts
```
### Test Coverage
- ✅ Complete tenant creation workflow
- ✅ Database rollback on failures
- ✅ Email service integration
- ✅ Workflow state management
- ✅ Error handling and retries
- ✅ Signal and query operations
## Production Deployment
### Prerequisites
1. **Temporal Server**: Running and accessible
2. **PostgreSQL**: Alga database with proper schema
3. **Email Service**: Configured email provider (Resend, AWS SES, etc.)
4. **Worker Process**: Temporal worker running with proper activities
### Configuration
```typescript
// Worker configuration
const worker = new Worker({
taskQueue: 'tenant-creation',
workflowsPath: require.resolve('./workflows'),
activitiesPath: require.resolve('./activities'),
// Database connection
connection: {
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT || '5432'),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD
},
// Email service
email: {
provider: process.env.EMAIL_PROVIDER || 'resend',
apiKey: process.env.EMAIL_API_KEY
}
});
```
### Health Checks
```typescript
// Basic health check workflow
const health = await client.workflow.execute('healthCheckWorkflow', {
workflowId: 'health-check',
taskQueue: 'tenant-creation'
});
console.log('System status:', health.status); // 'healthy'
```
## Security Considerations
### Data Protection
- All passwords are hashed using bcrypt
- Temporary passwords are cryptographically secure
- Database connections use SSL/TLS
- Email content is sanitized
### Access Control
- Workflow execution requires proper Temporal permissions
- Database operations use principle of least privilege
- Email service API keys are encrypted at rest
### Audit Trail
- All workflow executions are logged
- Database operations include audit timestamps
- Email delivery is tracked and logged
## Performance Metrics
### Typical Execution Times
- **Total Workflow**: 2-5 seconds
- **Database Operations**: 1-2 seconds
- **Email Delivery**: 1-3 seconds
- **Rollback Operations**: 0.5-1 second
### Resource Usage
- **Memory**: ~50MB per workflow execution
- **CPU**: Minimal (I/O bound operations)
- **Database**: 5-10 queries per tenant creation
## Troubleshooting
### Common Issues
1. **Database Connection Failures**
- Check connection string and credentials
- Verify network connectivity
- Ensure database schema is up to date
2. **Email Delivery Failures**
- Verify email service API key
- Check rate limiting and quotas
- Validate email addresses
3. **Workflow Timeouts**
- Increase timeout values if needed
- Check for deadlocks or slow queries
- Monitor system resources
### Debugging
```typescript
// Enable debug logging
const client = new Client({
address: 'localhost:7233',
logger: new DefaultLogger('DEBUG')
});
// Query workflow history
const history = await handle.fetchHistory();
console.log('Workflow events:', history.events);
```
## Future Enhancements
### Planned Features
- **Bulk Tenant Creation**: Support for creating multiple tenants
- **Custom Email Templates**: Configurable welcome email content
- **Integration Webhooks**: Notify external systems of tenant creation
- **Advanced Analytics**: Tenant creation metrics and reporting
- **Self-Service Portal**: Allow customers to create their own tenants
### Scaling Considerations
- **Database Sharding**: For high-volume tenant creation
- **Workflow Batching**: Group operations for efficiency
- **Async Email**: Decouple email sending from workflow
- **Caching**: Cache frequently accessed data