111 lines
3.1 KiB
JavaScript
111 lines
3.1 KiB
JavaScript
import express from 'express';
|
|
import { pgPool } from '../db.js';
|
|
import { supabase } from '../db.js';
|
|
import { getPythonServiceHealth, checkPythonServiceHealth } from '../middleware/pythonServiceHealth.js';
|
|
import { getCheddarFlowStatus } from '../services/cheddarflowWebSocketService.js';
|
|
|
|
const router = express.Router();
|
|
|
|
router.get('/', async (req, res) => {
|
|
const health = {
|
|
status: 'ok',
|
|
timestamp: new Date().toISOString(),
|
|
uptime: process.uptime(),
|
|
environment: process.env.NODE_ENV,
|
|
};
|
|
|
|
try {
|
|
// Check database connectivity
|
|
const dbStart = Date.now();
|
|
if (pgPool) {
|
|
// Test direct PostgreSQL connection
|
|
await pgPool.query('SELECT 1');
|
|
health.database = {
|
|
status: 'connected',
|
|
type: 'postgresql',
|
|
latency: Date.now() - dbStart,
|
|
};
|
|
} else {
|
|
// Test Supabase connection
|
|
const { error } = await supabase.from('options_flow').select('count').limit(1);
|
|
if (error && error.code !== 'PGRST116') {
|
|
throw error;
|
|
}
|
|
health.database = {
|
|
status: 'connected',
|
|
type: 'supabase',
|
|
latency: Date.now() - dbStart,
|
|
};
|
|
}
|
|
} catch (error) {
|
|
health.database = {
|
|
status: 'error',
|
|
error: error.message,
|
|
};
|
|
health.status = 'degraded';
|
|
}
|
|
|
|
// Check Python service health
|
|
if (process.env.USE_PYTHON_SERVICE !== 'false') {
|
|
try {
|
|
const isHealthy = await checkPythonServiceHealth();
|
|
const lastCheck = getPythonServiceHealth();
|
|
health.pythonService = {
|
|
available: isHealthy,
|
|
lastCheck: lastCheck?.timestamp || null,
|
|
status: lastCheck?.healthy ? 'healthy' : 'unhealthy',
|
|
url: process.env.PYTHON_SERVICE_URL || 'http://localhost:8010'
|
|
};
|
|
|
|
if (!isHealthy) {
|
|
health.status = 'degraded';
|
|
}
|
|
} catch (error) {
|
|
health.pythonService = {
|
|
available: false,
|
|
error: error.message,
|
|
status: 'error'
|
|
};
|
|
health.status = 'degraded';
|
|
}
|
|
} else {
|
|
health.pythonService = {
|
|
status: 'disabled'
|
|
};
|
|
}
|
|
|
|
// Check CheddarFlow WebSocket service
|
|
if (process.env.ENABLE_CHEDDARFLOW !== 'false') {
|
|
try {
|
|
const cheddarFlowStatus = getCheddarFlowStatus();
|
|
health.cheddarFlow = {
|
|
running: cheddarFlowStatus.running,
|
|
connected: cheddarFlowStatus.connected,
|
|
subscriptionId: cheddarFlowStatus.subscriptionId || null,
|
|
reconnectAttempts: cheddarFlowStatus.reconnectAttempts || 0,
|
|
status: cheddarFlowStatus.connected ? 'connected' : cheddarFlowStatus.running ? 'connecting' : 'disconnected'
|
|
};
|
|
|
|
if (!cheddarFlowStatus.connected && cheddarFlowStatus.running) {
|
|
health.status = 'degraded';
|
|
}
|
|
} catch (error) {
|
|
health.cheddarFlow = {
|
|
status: 'error',
|
|
error: error.message
|
|
};
|
|
health.status = 'degraded';
|
|
}
|
|
} else {
|
|
health.cheddarFlow = {
|
|
status: 'disabled'
|
|
};
|
|
}
|
|
|
|
// Only return 503 if the server itself is broken — degraded means optional services are down
|
|
const statusCode = health.status === 'error' ? 503 : 200;
|
|
res.status(statusCode).json(health);
|
|
});
|
|
|
|
export default router;
|