File size: 3,665 Bytes
529090e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * ╔═══════════════════════════════════════════════════════════════════════════╗
 * β•‘                    CORTEX API - VISUAL BRIDGE                             β•‘
 * ║═══════════════════════════════════════════════════════════════════════════║
 * β•‘  Exposes system health and graph status to frontend visualization         β•‘
 * β•‘  Handover #007 - Visual Cortex Activation                                 β•‘
 * β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
 */

import { Router, Request, Response } from 'express';
import { neo4jAdapter } from '../adapters/Neo4jAdapter';
import { selfHealing } from '../services/SelfHealingAdapter';

const router = Router();

/**
 * GET /api/cortex/status
 * Returns unified system health status for frontend visualization
 */
router.get('/status', async (req: Request, res: Response) => {
    try {
        // Get Neo4j health status
        const dbHealth = await neo4jAdapter.healthCheck();
        
        // Get self-healing system status
        const systemStatus = selfHealing.getSystemStatus();
        
        // Determine provider based on URI
        const neo4jUri = process.env.NEO4J_URI || 'bolt://localhost:7687';
        const isCloud = neo4jUri.includes('neo4j.io');
        
        const response = {
            brain: {
                connected: dbHealth.connected,
                nodes: dbHealth.nodeCount || 0,
                relationships: dbHealth.relationshipCount || 0,
                latencyMs: dbHealth.latencyMs || -1,
                provider: isCloud ? 'AuraDB' : 'Local Docker',
                lastCheck: dbHealth.lastCheck
            },
            immune_system: {
                status: systemStatus.overallHealth,
                active_services: systemStatus.services
                    .filter((s: any) => s.status === 'healthy')
                    .map((s: any) => s.name),
                unhealthy_services: systemStatus.services
                    .filter((s: any) => s.status !== 'healthy')
                    .map((s: any) => s.name),
                uptime: process.uptime(),
                lastUpdate: new Date().toISOString()
            },
            timestamp: new Date().toISOString()
        };
        
        res.json(response);
        
    } catch (error: any) {
        console.error('[Cortex API] ❌ Status check failed:', error.message);
        
        res.status(503).json({
            brain: {
                connected: false,
                nodes: 0,
                provider: 'UNKNOWN',
                error: error.message
            },
            immune_system: {
                status: 'CRITICAL',
                active_services: [],
                error: error.message
            },
            timestamp: new Date().toISOString()
        });
    }
});

/**
 * GET /api/cortex/pulse
 * Lightweight heartbeat endpoint for quick connectivity checks
 */
router.get('/pulse', async (req: Request, res: Response) => {
    const isHealthy = neo4jAdapter.isHealthy();
    res.status(isHealthy ? 200 : 503).json({
        alive: true,
        cortex_online: isHealthy,
        timestamp: Date.now()
    });
});

export default router;