106 lines
3.5 KiB
JavaScript
106 lines
3.5 KiB
JavaScript
require('dotenv').config();
|
|
|
|
const http = require('http');
|
|
const express = require('express');
|
|
const cors = require('cors');
|
|
const { port, corsOrigin } = require('./config');
|
|
const { initDatabase } = require('./db/database');
|
|
const errorHandler = require('./middleware/errorHandler');
|
|
const requestLogger = require('./middleware/requestLogger');
|
|
const settingsRoutes = require('./routes/settingsRoutes');
|
|
const pipelineRoutes = require('./routes/pipelineRoutes');
|
|
const historyRoutes = require('./routes/historyRoutes');
|
|
const cronRoutes = require('./routes/cronRoutes');
|
|
const runtimeRoutes = require('./routes/runtimeRoutes');
|
|
const wsService = require('./services/websocketService');
|
|
const pipelineService = require('./services/pipelineService');
|
|
const cronService = require('./services/cronService');
|
|
const diskDetectionService = require('./services/diskDetectionService');
|
|
const hardwareMonitorService = require('./services/hardwareMonitorService');
|
|
const logger = require('./services/logger').child('BOOT');
|
|
const { errorToMeta } = require('./utils/errorMeta');
|
|
|
|
async function start() {
|
|
logger.info('backend:start:init');
|
|
await initDatabase();
|
|
await pipelineService.init();
|
|
await cronService.init();
|
|
|
|
const app = express();
|
|
app.use(cors({ origin: corsOrigin }));
|
|
app.use(express.json({ limit: '2mb' }));
|
|
app.use(requestLogger);
|
|
|
|
app.get('/api/health', (req, res) => {
|
|
res.json({ ok: true, now: new Date().toISOString() });
|
|
});
|
|
|
|
app.use('/api/settings', settingsRoutes);
|
|
app.use('/api/pipeline', pipelineRoutes);
|
|
app.use('/api/history', historyRoutes);
|
|
app.use('/api/crons', cronRoutes);
|
|
app.use('/api/runtime', runtimeRoutes);
|
|
|
|
app.use(errorHandler);
|
|
|
|
const server = http.createServer(app);
|
|
wsService.init(server);
|
|
await hardwareMonitorService.init();
|
|
|
|
diskDetectionService.on('discInserted', (device) => {
|
|
logger.info('disk:inserted:event', { device });
|
|
pipelineService.onDiscInserted(device).catch((error) => {
|
|
logger.error('pipeline:onDiscInserted:failed', { error: errorToMeta(error), device });
|
|
wsService.broadcast('PIPELINE_ERROR', { message: error.message });
|
|
});
|
|
});
|
|
|
|
diskDetectionService.on('discRemoved', (device) => {
|
|
logger.info('disk:removed:event', { device });
|
|
pipelineService.onDiscRemoved(device).catch((error) => {
|
|
logger.error('pipeline:onDiscRemoved:failed', { error: errorToMeta(error), device });
|
|
wsService.broadcast('PIPELINE_ERROR', { message: error.message });
|
|
});
|
|
});
|
|
|
|
diskDetectionService.on('error', (error) => {
|
|
logger.error('diskDetection:error:event', { error: errorToMeta(error) });
|
|
wsService.broadcast('DISK_DETECTION_ERROR', { message: error.message });
|
|
});
|
|
|
|
diskDetectionService.start();
|
|
|
|
server.listen(port, () => {
|
|
logger.info('backend:listening', { port });
|
|
});
|
|
|
|
const shutdown = () => {
|
|
logger.warn('backend:shutdown:received');
|
|
diskDetectionService.stop();
|
|
hardwareMonitorService.stop();
|
|
cronService.stop();
|
|
server.close(() => {
|
|
logger.warn('backend:shutdown:completed');
|
|
process.exit(0);
|
|
});
|
|
};
|
|
|
|
process.on('SIGINT', shutdown);
|
|
process.on('SIGTERM', shutdown);
|
|
|
|
process.on('uncaughtException', (error) => {
|
|
logger.error('process:uncaughtException', { error: errorToMeta(error) });
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason) => {
|
|
logger.error('process:unhandledRejection', {
|
|
reason: reason instanceof Error ? errorToMeta(reason) : String(reason)
|
|
});
|
|
});
|
|
}
|
|
|
|
start().catch((error) => {
|
|
logger.error('backend:start:failed', { error: errorToMeta(error) });
|
|
process.exit(1);
|
|
});
|