Hypertext Rails
Documentation
System Documentation
- Heartbeat System
- Performance Metrics System
- Project Auto-Provisioning System
-
Communication Center
- Communication Center ERD
- Automation Workflow Complete Flow - Complete guide covering both scheduled and trigger-based workflows
Quick Links
Project Auto-Provisioning System
Overview
This system automatically provisions Integration Hub tokens and Analytics DB credentials for all projects in the system. Projects are stored in an external read-only pepcore database, so when new projects are created there, they need to be provisioned in this application.
Problem Solved
Before: Projects created in the pepcore database would exist without: - API tokens (Integration Hub tokens) - Analytics DB credentials
This caused errors when accessing integrations pages and prevented analytics data from being collected.
After: Every project is automatically provisioned within 5 minutes of creation, with daily reconciliation to catch any gaps.
Architecture
External Pepcore DB (read-only)
↓
Polling Job (every 5 min) ← Optimized to skip if no changes
↓
Provisioning Service
├─→ Generate API Token
├─→ Create Analytics DB
└─→ Initialize Tables
↓
Fully provisioned ✓
Components
1. ProjectProvisioningService (app/services/project_provisioning_service.rb)
Core service that handles all provisioning logic.
Key Methods:
- provision_project(project) - Provisions a single project
- provision_all_missing - Finds and provisions all incomplete projects
- check_project_status(project) - Returns what's missing
- audit_all_projects - Generates comprehensive status report
Features: - Idempotent (safe to run multiple times) - Individual project failures don't stop others - Comprehensive error handling and logging - Sentry integration for failures
2. ProjectProvisioningJob (app/jobs/project_provisioning_job.rb)
Background job that runs every 5 minutes to check for new projects.
Optimization:
- Caches project count between runs
- Skips provisioning if count unchanged
- Runs safety check every 30 minutes even if count unchanged
- Uses dedicated project_provisioning queue
Failsafes: - 5-minute timeout - Cleans up database connections - Continues on individual failures - Always schedules next run
3. ProjectReconciliationJob (app/jobs/project_reconciliation_job.rb)
Daily job (1 AM UTC) that performs deep scan of all projects.
Purpose: - Safety net to catch any gaps - Generates comprehensive daily report - Auto-fixes missing credentials - Alerts via Sentry if persistent issues
4. Rake Tasks (lib/tasks/project_provisioning.rake)
Command-line tools for management and monitoring.
Available Commands:
# Schedule the 5-minute polling job
rake projects:schedule_provisioning
# Schedule the daily reconciliation job
rake projects:schedule_reconciliation
# Manually provision all missing credentials
rake projects:provision_missing
# Audit status without making changes
rake projects:audit_status
# Provision a specific project
rake projects:provision_project[PROJECT_ID]
# Check job status
rake projects:job_status
# Clear scheduled jobs (use with caution)
rake projects:clear_scheduled_jobs
5. ActiveAdmin Interface
Batch Actions (select multiple projects): - "Provision Integration Hub + Analytics" - Manually trigger provisioning - "Check Provisioning Status" - See what's missing
Project Index Page: - "Provisioning Status" column with visual indicators - ✅/❌ indicators for API Token and Analytics DB
Project Show Page: - Provisioning status panel at top - "Re-provision Now" button if missing credentials
Setup Instructions
🚀 Cloud66 Job Scheduling (Recommended Approach)
Approach: Cloud66 Jobs (Instead of Self-Scheduling Rails Jobs)
We use Cloud66 Jobs to directly schedule the provisioning tasks instead of Rails job self-scheduling. This provides better visibility, control, and reliability.
Why Cloud66 Jobs Instead of Self-Scheduling: - ✅ Centralized Control - All scheduling visible in Cloud66 dashboard - ✅ Easy Management - Enable/disable via Cloud66 without code changes - ✅ Better Reliability - Cloud66 is more reliable than Rails job scheduling - ✅ Simpler Code - No complex self-scheduling logic needed - ✅ Better Monitoring - Execution history and success/failure tracking
Cloud66 Jobs Configuration Required:
Create two recurring jobs in Cloud66:
Job 1: Project Provisioning
- Name: Project Provisioning
- Type: Rake Task
- Task: projects:provision_missing
- Schedule: Every 5 minutes UTC
- Server: Your main application server
Job 2: Project Reconciliation
- Name: Project Reconciliation
- Type: Rake Task
- Task: projects:reconcile_daily
- Schedule: Daily at 1:00 AM UTC
- Server: Your main application server
How It Works: 1. Cloud66 runs rake tasks on schedule → Direct provisioning work 2. Rails jobs do the actual work → No self-scheduling complexity 3. Cloud66 handles all scheduling → Reliable and visible 4. Easy pause/resume → Control via Cloud66 dashboard
Benefits: - ✅ Simpler architecture - Cloud66 handles scheduling, Rails handles work - ✅ Better monitoring - All job status in Cloud66 dashboard - ✅ Easier debugging - Clear separation of concerns - ✅ No job queue dependency - Works even if delayed_job has issues
Initial Backfill (One-time)
After deploying, provision any existing projects with missing credentials:
bundle exec rake projects:provision_missing
Delayed Job Scheduling (No Cron Needed!)
The system uses self-scheduling Delayed Jobs (like the heartbeat system):
- Each job automatically schedules the next one
- No external cron required
- Managed by your existing Delayed Job workers
- Self-sustaining system
Monitoring
Logs
All provisioning activity is logged with clear prefixes:
🔍 [ProjectProvisioning] Starting provisioning poll...
✅ [ProjectProvisioning] Poll complete in 2.3s: Scanned=42, Missing=3, Provisioned=3, Failed=0
📊 [ProjectReconciliation] Starting daily reconciliation...
Sentry Integration
Failures are automatically reported to Sentry with full context: - Project ID and name - Error type and message - Operation that failed (provisionapitoken or provisionanalyticsdb)
Check Job Status
rake projects:job_status
Shows: - Polling job status and next run time - Daily job status and next run time - Any failed jobs
Audit Projects
rake projects:audit_status
Shows: - Total projects - Fully provisioned count and percentage - Projects missing API tokens - Projects missing DB credentials - Projects missing both - Detailed list of projects with issues
Usage Examples
Check if a specific project is provisioned
rake projects:provision_project[87]
Output:
```
🔧 PROVISIONING PROJECT 87
Name: Team ML09x Project Key: ML09X
Current Status: API Token: ❌ Missing Analytics DB: ❌ Missing
🔧 Provisioning...
✅ SUCCESS API Token: created
Analytics DB: created
### Audit all projects
```bash
rake projects:audit_status
Manually provision missing projects
rake projects:provision_missing
Via ActiveAdmin
- Go to Projects page
- Select projects needing provisioning
- Choose "Provision Integration Hub + Analytics" from batch actions
- Click "Submit"
Error Handling
Level 1: Individual Project Failures
- Each project provision is wrapped in rescue block
- One failure doesn't stop others
- Error logged with project ID
- Reported to Sentry
Level 2: Service Failures
- Service returns success/failure status
- Job logs failure but continues
- Job always schedules next run
Level 3: Job Failures
- Delayed Job allows 1 retry
- 20-minute timeout prevents hanging
- Failed jobs kept in DB for inspection
- Can retry via ActiveAdmin
Critical Failsafes
- Never runs in main request cycle
- Always in background jobs
- Database connection pool management
PepcoreBase.clear_active_connections!cleanup
Troubleshooting
Jobs not running
# Check job status
rake projects:job_status
# If not scheduled, schedule them
rake projects:schedule_provisioning
rake projects:schedule_reconciliation
Projects still missing credentials
# Run audit to see what's missing
rake projects:audit_status
# Manually provision missing
rake projects:provision_missing
# Check logs for errors
tail -f log/production.log | grep ProjectProvisioning
Database connection issues
The jobs automatically clean up connections, but if you see connection pool exhaustion:
# In Rails console
PepcoreBase.clear_active_connections!
Provision a specific project manually
# Via rake task
rake projects:provision_project[PROJECT_ID]
# Or via Rails console
service = ProjectProvisioningService.new
result = service.provision_project(Project.find(PROJECT_ID))
puts result.inspect
Performance
Optimization Results: - Polling job runs in < 1 second when no changes detected - Full provisioning of 100 projects: ~15-30 seconds - Single project provision: ~2-3 seconds - Daily reconciliation: ~30-60 seconds (depends on project count)
Resource Usage: - Minimal DB load (cached count check) - Dedicated queue prevents blocking other jobs - Connection cleanup prevents pool exhaustion
Testing
Run the audit first to see current state:
bash
rake projects:audit_status
Then test provisioning a single project:
bash
rake projects:provision_project[PROJECT_ID]
Finally, test the full system:
bash
rake projects:provision_missing
Success Metrics
✅ 100% of projects have API tokens within 5 minutes of creation
✅ 100% of projects have Analytics DB within 5 minutes
✅ Zero provision failures (or < 0.1% failure rate)
✅ Job execution time < 30 seconds
✅ Zero impact on main application performance
✅ Full visibility via ActiveAdmin
Support
For issues or questions:
1. Check logs: tail -f log/production.log | grep ProjectProvisioning
2. Run audit: rake projects:audit_status
3. Check Sentry for errors
4. Review job status: rake projects:job_status