import { PrismaClient } from '@prisma/client'; import { WorkflowExecutor } from './workflows/workflow-executor'; import { DecisionEngine } from './decision-engine/rules'; import { AlertSystem } from './monitoring/alerts'; import { MetricsCollector } from './monitoring/metrics'; import { log } from './monitoring/logger'; import { config } from './utils/config'; import { businessInputSchema, validateBusinessIdea } from './utils/validators'; export class MetaOrchestrator { private db: PrismaClient; private workflowExecutor: WorkflowExecutor; private decisionEngine: DecisionEngine; private alerts: AlertSystem; private metrics: MetricsCollector; private isRunning: boolean = false; constructor() { this.db = new PrismaClient(); this.alerts = new AlertSystem(this.db); this.metrics = new MetricsCollector(this.db); this.workflowExecutor = new WorkflowExecutor(this.db, this.alerts); this.decisionEngine = new DecisionEngine(this.db, this.alerts, this.metrics); } /** * Initialize the orchestrator */ async initialize(): Promise { try { log.info('Initializing MetaOrchestrator...'); // Test database connection await this.db.$connect(); log.info('Database connected'); // Start background processes this.startBackgroundProcesses(); this.isRunning = true; log.info('MetaOrchestrator initialized successfully'); } catch (error) { log.error('Failed to initialize MetaOrchestrator', error); throw error; } } /** * Create a new business and start its lifecycle */ async createBusiness(input: { name: string; idea: string; targetAudience?: string; budget?: number; }): Promise<{ id: string; name: string }> { try { // Validate input const validated = businessInputSchema.parse(input); // Validate business idea quality const ideaValidation = validateBusinessIdea(validated.idea); if (!ideaValidation.valid) { throw new Error(`Invalid business idea: ${ideaValidation.issues.join(', ')}`); } // Create business record const business = await this.db.business.create({ data: { name: validated.name, idea: validated.idea, targetAudience: validated.targetAudience, budget: validated.budget, status: 'VALIDATING', }, }); log.business.created(business.id, business.name, business.idea); // Start lifecycle in background (non-blocking) this.executeBusinessLifecycle(business.id).catch((error) => { log.error('Business lifecycle execution failed', error, { businessId: business.id }); }); return { id: business.id, name: business.name, }; } catch (error) { log.error('Failed to create business', error); throw error; } } /** * Execute the complete business lifecycle */ async executeBusinessLifecycle(businessId: string): Promise { try { log.info('Starting business lifecycle', { businessId }); // PHASE 1: Market Validation (Sequential) log.info('Phase 1: Market Validation', { businessId }); const validationResult = await this.workflowExecutor.run(businessId, 'MARKET_VALIDATION'); if (!validationResult.success || !validationResult.data?.viable) { log.info('Business validation failed - shutting down', { businessId }); await this.shutdown(businessId, 'Market validation failed: not viable'); return; } // PHASE 2: MVP Development (Sequential) log.info('Phase 2: MVP Development', { businessId }); const mvpResult = await this.workflowExecutor.run(businessId, 'MVP_DEVELOPMENT'); if (!mvpResult.success) { log.error('MVP development failed', undefined, { businessId }); await this.shutdown(businessId, 'MVP development failed'); return; } // PHASE 3: Marketing Setup (Parallel) log.info('Phase 3: Marketing Setup (parallel workflows)', { businessId }); const marketingResults = await this.workflowExecutor.runParallel(businessId, [ 'LANDING_PAGE_SEO', 'PAID_ADS', 'CONTENT_MARKETING', 'EMAIL_AUTOMATION', 'ANALYTICS_SETUP', ]); // Check if any critical marketing workflows failed const failures = marketingResults.filter((r) => !r.success); if (failures.length > 0) { log.warn('Some marketing workflows failed', { businessId, failureCount: failures.length, }); // Continue anyway - marketing workflows are not critical } // Update business status await this.db.business.update({ where: { id: businessId }, data: { status: 'OPTIMIZING' }, }); // PHASE 4: Continuous Optimization Loop (Forever) log.info('Phase 4: Starting continuous optimization', { businessId }); // This runs forever until business is shutdown/paused await this.workflowExecutor.runForever( businessId, 'OPTIMIZATION_LOOP', config.app.optimizationIntervalMinutes ); log.info('Business lifecycle completed', { businessId }); } catch (error) { log.error('Business lifecycle error', error, { businessId }); await this.alerts.systemError( `Business lifecycle failed for ${businessId}`, error instanceof Error ? error.stack : undefined ); } } /** * Shutdown a business */ async shutdown(businessId: string, reason: string): Promise { log.info('Shutting down business', { businessId, reason }); // Pause all campaigns await this.db.campaign.updateMany({ where: { businessId }, data: { active: false }, }); // Update business status await this.db.business.update({ where: { id: businessId }, data: { status: 'SHUTDOWN' }, }); // Send alert const business = await this.db.business.findUnique({ where: { id: businessId }, }); if (business) { await this.alerts.sendAlert({ type: 'DECISION_EXECUTED', severity: 'WARNING', title: 'Business Shutdown', message: `Business "${business.name}" has been shut down.\n\nReason: ${reason}`, businessId, metadata: { reason }, }); } log.info('Business shutdown complete', { businessId }); } /** * Start background processes (decision evaluation) */ private startBackgroundProcesses(): void { // Run decision evaluation periodically setInterval(async () => { try { await this.evaluateAllBusinessDecisions(); } catch (error) { log.error('Decision evaluation error', error); } }, config.app.decisionEvaluationIntervalMinutes * 60 * 1000); log.info('Background processes started', { decisionEvaluationInterval: config.app.decisionEvaluationIntervalMinutes, }); } /** * Evaluate decisions for all active businesses */ private async evaluateAllBusinessDecisions(): Promise { const activeBusinesses = await this.db.business.findMany({ where: { status: { in: ['RUNNING_ADS', 'OPTIMIZING', 'SCALING'], }, }, }); log.info(`Evaluating decisions for ${activeBusinesses.length} businesses`); for (const business of activeBusinesses) { try { await this.decisionEngine.evaluateBusinessDaily(business.id); } catch (error) { log.error('Failed to evaluate business decisions', error, { businessId: business.id, }); } } } /** * Get business status */ async getBusinessStatus(businessId: string) { const business = await this.db.business.findUnique({ where: { id: businessId }, include: { workflows: { orderBy: { createdAt: 'desc' }, take: 10, }, campaigns: true, decisions: { orderBy: { createdAt: 'desc' }, take: 5, }, }, }); if (!business) { throw new Error('Business not found'); } const metrics = await this.metrics.getBusinessMetrics(businessId); const healthScore = await this.metrics.getHealthScore(businessId); return { ...business, metrics, healthScore, }; } /** * List all businesses */ async listBusinesses() { return await this.db.business.findMany({ orderBy: { createdAt: 'desc' }, include: { _count: { select: { workflows: true, campaigns: true, decisions: true, }, }, }, }); } /** * Graceful shutdown */ async close(): Promise { log.info('Shutting down MetaOrchestrator...'); this.isRunning = false; await this.db.$disconnect(); log.info('MetaOrchestrator shutdown complete'); } }