huge refactor to remove depenencie hell and add typesafe container
This commit is contained in:
parent
28b9822d55
commit
843a7b9b9b
148 changed files with 3603 additions and 2378 deletions
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
import { Hono } from 'hono';
|
||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
||||
import { createHealthRoutes } from './health.routes';
|
||||
import { createExchangeRoutes } from './exchange.routes';
|
||||
import { createHealthRoutes } from './health.routes';
|
||||
import { createMonitoringRoutes } from './monitoring.routes';
|
||||
import { createPipelineRoutes } from './pipeline.routes';
|
||||
|
||||
|
|
@ -26,4 +26,4 @@ export function createRoutes(container: IServiceContainer): Hono {
|
|||
app.route('/api/pipeline', pipelineRoutes);
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
* Exchange management routes - Refactored
|
||||
*/
|
||||
import { Hono } from 'hono';
|
||||
import type { IServiceContainer } from '@stock-bot/types';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
||||
import { createExchangeService } from '../services/exchange.service';
|
||||
import { createSuccessResponse, handleError } from '../utils/error-handler';
|
||||
import {
|
||||
|
|
@ -259,4 +259,4 @@ export function createExchangeRoutes(container: IServiceContainer) {
|
|||
});
|
||||
|
||||
return exchangeRoutes;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
* Health check routes factory
|
||||
*/
|
||||
import { Hono } from 'hono';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
|
||||
const logger = getLogger('health-routes');
|
||||
|
||||
|
|
@ -70,7 +70,10 @@ export function createHealthRoutes(container: IServiceContainer) {
|
|||
health.checks.postgresql = { status: 'healthy', message: 'Connected and responsive' };
|
||||
logger.debug('PostgreSQL health check passed');
|
||||
} else {
|
||||
health.checks.postgresql = { status: 'unhealthy', message: 'PostgreSQL client not available' };
|
||||
health.checks.postgresql = {
|
||||
status: 'unhealthy',
|
||||
message: 'PostgreSQL client not available',
|
||||
};
|
||||
logger.warn('PostgreSQL health check failed - client not available');
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -108,4 +111,4 @@ export function createHealthRoutes(container: IServiceContainer) {
|
|||
}
|
||||
|
||||
// Export legacy routes for backward compatibility during migration
|
||||
export const healthRoutes = createHealthRoutes({} as IServiceContainer);
|
||||
export const healthRoutes = createHealthRoutes({} as IServiceContainer);
|
||||
|
|
|
|||
|
|
@ -13,167 +13,200 @@ export function createMonitoringRoutes(container: IServiceContainer) {
|
|||
/**
|
||||
* Get overall system health
|
||||
*/
|
||||
monitoring.get('/', async (c) => {
|
||||
monitoring.get('/', async c => {
|
||||
try {
|
||||
const health = await monitoringService.getSystemHealth();
|
||||
|
||||
|
||||
// Set appropriate status code based on health
|
||||
const statusCode = health.status === 'healthy' ? 200 :
|
||||
health.status === 'degraded' ? 503 : 500;
|
||||
|
||||
const statusCode =
|
||||
health.status === 'healthy' ? 200 : health.status === 'degraded' ? 503 : 500;
|
||||
|
||||
return c.json(health, statusCode);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
status: 'error',
|
||||
message: 'Failed to retrieve system health',
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
status: 'error',
|
||||
message: 'Failed to retrieve system health',
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get cache/Dragonfly statistics
|
||||
*/
|
||||
monitoring.get('/cache', async (c) => {
|
||||
monitoring.get('/cache', async c => {
|
||||
try {
|
||||
const stats = await monitoringService.getCacheStats();
|
||||
return c.json(stats);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve cache statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve cache statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get queue statistics
|
||||
*/
|
||||
monitoring.get('/queues', async (c) => {
|
||||
monitoring.get('/queues', async c => {
|
||||
try {
|
||||
const stats = await monitoringService.getQueueStats();
|
||||
return c.json({ queues: stats });
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve queue statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve queue statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get specific queue statistics
|
||||
*/
|
||||
monitoring.get('/queues/:name', async (c) => {
|
||||
monitoring.get('/queues/:name', async c => {
|
||||
try {
|
||||
const queueName = c.req.param('name');
|
||||
const stats = await monitoringService.getQueueStats();
|
||||
const queueStats = stats.find(q => q.name === queueName);
|
||||
|
||||
|
||||
if (!queueStats) {
|
||||
return c.json({
|
||||
error: 'Queue not found',
|
||||
message: `Queue '${queueName}' does not exist`,
|
||||
}, 404);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Queue not found',
|
||||
message: `Queue '${queueName}' does not exist`,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return c.json(queueStats);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve queue statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve queue statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get database statistics
|
||||
*/
|
||||
monitoring.get('/databases', async (c) => {
|
||||
monitoring.get('/databases', async c => {
|
||||
try {
|
||||
const stats = await monitoringService.getDatabaseStats();
|
||||
return c.json({ databases: stats });
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve database statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve database statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get specific database statistics
|
||||
*/
|
||||
monitoring.get('/databases/:type', async (c) => {
|
||||
monitoring.get('/databases/:type', async c => {
|
||||
try {
|
||||
const dbType = c.req.param('type') as 'postgres' | 'mongodb' | 'questdb';
|
||||
const stats = await monitoringService.getDatabaseStats();
|
||||
const dbStats = stats.find(db => db.type === dbType);
|
||||
|
||||
|
||||
if (!dbStats) {
|
||||
return c.json({
|
||||
error: 'Database not found',
|
||||
message: `Database type '${dbType}' not found or not enabled`,
|
||||
}, 404);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Database not found',
|
||||
message: `Database type '${dbType}' not found or not enabled`,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return c.json(dbStats);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve database statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve database statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get service metrics
|
||||
*/
|
||||
monitoring.get('/metrics', async (c) => {
|
||||
monitoring.get('/metrics', async c => {
|
||||
try {
|
||||
const metrics = await monitoringService.getServiceMetrics();
|
||||
return c.json(metrics);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve service metrics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve service metrics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get detailed cache info (Redis INFO command output)
|
||||
*/
|
||||
monitoring.get('/cache/info', async (c) => {
|
||||
monitoring.get('/cache/info', async c => {
|
||||
try {
|
||||
if (!container.cache) {
|
||||
return c.json({
|
||||
error: 'Cache not available',
|
||||
message: 'Cache service is not enabled',
|
||||
}, 503);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Cache not available',
|
||||
message: 'Cache service is not enabled',
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const info = await container.cache.info();
|
||||
const stats = await monitoringService.getCacheStats();
|
||||
|
||||
|
||||
return c.json({
|
||||
parsed: stats,
|
||||
raw: info,
|
||||
});
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve cache info',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve cache info',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Health check endpoint for monitoring
|
||||
*/
|
||||
monitoring.get('/ping', (c) => {
|
||||
return c.json({
|
||||
status: 'ok',
|
||||
monitoring.get('/ping', c => {
|
||||
return c.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
service: 'monitoring',
|
||||
});
|
||||
|
|
@ -182,78 +215,90 @@ export function createMonitoringRoutes(container: IServiceContainer) {
|
|||
/**
|
||||
* Get service status for all microservices
|
||||
*/
|
||||
monitoring.get('/services', async (c) => {
|
||||
monitoring.get('/services', async c => {
|
||||
try {
|
||||
const services = await monitoringService.getServiceStatus();
|
||||
return c.json({ services });
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve service status',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve service status',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get proxy statistics
|
||||
*/
|
||||
monitoring.get('/proxies', async (c) => {
|
||||
monitoring.get('/proxies', async c => {
|
||||
try {
|
||||
const stats = await monitoringService.getProxyStats();
|
||||
return c.json(stats || { enabled: false });
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve proxy statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve proxy statistics',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get comprehensive system overview
|
||||
*/
|
||||
monitoring.get('/overview', async (c) => {
|
||||
monitoring.get('/overview', async c => {
|
||||
try {
|
||||
const overview = await monitoringService.getSystemOverview();
|
||||
return c.json(overview);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
error: 'Failed to retrieve system overview',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
error: 'Failed to retrieve system overview',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test direct BullMQ queue access
|
||||
*/
|
||||
monitoring.get('/test/queue/:name', async (c) => {
|
||||
monitoring.get('/test/queue/:name', async c => {
|
||||
const queueName = c.req.param('name');
|
||||
const { Queue } = await import('bullmq');
|
||||
|
||||
|
||||
const connection = {
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
db: 0, // All queues in DB 0
|
||||
db: 0, // All queues in DB 0
|
||||
};
|
||||
|
||||
|
||||
const queue = new Queue(queueName, { connection });
|
||||
|
||||
|
||||
try {
|
||||
const counts = await queue.getJobCounts();
|
||||
await queue.close();
|
||||
return c.json({
|
||||
return c.json({
|
||||
queueName,
|
||||
counts
|
||||
counts,
|
||||
});
|
||||
} catch (error: any) {
|
||||
await queue.close();
|
||||
return c.json({
|
||||
queueName,
|
||||
error: error.message
|
||||
}, 500);
|
||||
return c.json(
|
||||
{
|
||||
queueName,
|
||||
error: error.message,
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return monitoring;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,4 +132,4 @@ export function createPipelineRoutes(container: IServiceContainer) {
|
|||
});
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue