cargo / src /server.js
vish85521's picture
Upload 53 files
964569f verified
Raw
History Blame Contribute Delete
5.34 kB
const path = require("path");
const { config } = require("./config/env");
const { createLogger } = require("./config/logger");
const { createApp } = require("./app");
const { createRuntimeState } = require("./services/runtimeState");
const { createDbPool, verifyDbConnection } = require("./db/pool");
const { runMigrations, runSeeds } = require("./db/migrator");
const { createMqttConsumer } = require("./mqtt/client");
const { createTelemetryIngestService } = require("./services/telemetryIngestService");
const { createAlertEngineService } = require("./services/alertEngineService");
const { createFleetService } = require("./services/fleetService");
const { createAlertsService } = require("./services/alertsService");
const { createReportsService } = require("./services/reportsService");
const { createAdminService } = require("./services/adminService");
const { createAuthService } = require("./services/authService");
const { createTripsService } = require("./services/tripsService");
const { createTripSummaryAiService } = require("./services/tripSummaryAiService");
const { startOfflineScannerJob } = require("./jobs/offlineScannerJob");
const telemetryRepository = require("./repositories/telemetryRepository");
const assetRepository = require("./repositories/assetRepository");
const alertRulesRepository = require("./repositories/alertRulesRepository");
const alertsRepository = require("./repositories/alertsRepository");
const reportsRepository = require("./repositories/reportsRepository");
const adminRepository = require("./repositories/adminRepository");
const authRepository = require("./repositories/authRepository");
const auditRepository = require("./repositories/auditRepository");
const tripsRepository = require("./repositories/tripsRepository");
const telemetryValidator = require("./validators/telemetryValidator");
async function main() {
const logger = createLogger(config.logLevel);
const runtimeState = createRuntimeState();
const pool = createDbPool(config, logger);
let mqttConsumer = null;
let offlineScannerJob = null;
let server = null;
let shuttingDown = false;
async function shutdown(signal) {
if (shuttingDown) {
return;
}
shuttingDown = true;
logger.info("Shutdown started", { signal });
try {
if (offlineScannerJob) {
offlineScannerJob.stop();
}
if (mqttConsumer) {
mqttConsumer.stop();
}
if (server) {
await new Promise((resolve) => server.close(resolve));
}
await pool.end();
logger.info("Shutdown complete");
process.exit(0);
} catch (error) {
logger.error("Shutdown failed", { error: error.message });
process.exit(1);
}
}
process.on("SIGINT", () => shutdown("SIGINT"));
process.on("SIGTERM", () => shutdown("SIGTERM"));
try {
await verifyDbConnection(pool);
runtimeState.markDbHealthy();
logger.info("PostgreSQL connection established");
if (config.db.runMigrationsOnBoot) {
const migrationsDir = path.resolve(__dirname, "../migrations");
await runMigrations(pool, migrationsDir, logger);
}
if (config.db.runSeedsOnBoot) {
const seedsDir = path.resolve(__dirname, "../seeds");
await runSeeds(pool, seedsDir, logger);
}
const alertEngineService = createAlertEngineService({
config,
alertsRepository,
alertRulesRepository,
});
const telemetryIngestService = createTelemetryIngestService({
pool,
logger,
runtimeState,
telemetryRepository,
assetRepository,
alertEngineService,
telemetryValidator,
});
const tripSummaryAiService = createTripSummaryAiService({
config,
logger,
});
const services = {
authService: createAuthService({
config,
pool,
authRepository,
}),
fleetService: createFleetService({
pool,
config,
telemetryRepository,
}),
alertsService: createAlertsService({
pool,
config,
alertsRepository,
}),
reportsService: createReportsService({
pool,
config,
reportsRepository,
}),
tripsService: createTripsService({
pool,
tripsRepository,
assetRepository,
auditRepository,
alertsRepository,
tripSummaryAiService,
}),
adminService: createAdminService({
pool,
adminRepository,
auditRepository,
}),
};
mqttConsumer = createMqttConsumer({
config,
logger,
runtimeState,
onTelemetryMessage: telemetryIngestService.handleIncomingTelemetry,
});
offlineScannerJob = startOfflineScannerJob({
pool,
config,
logger,
runtimeState,
telemetryRepository,
alertEngineService,
});
const app = createApp(config, logger, services, runtimeState);
server = app.listen(config.server.port, () => {
logger.info("Backend started", {
port: config.server.port,
apiPrefix: config.server.apiPrefix,
mqttTopicFilter: config.mqtt.topicFilter,
});
});
} catch (error) {
runtimeState.markDbError(error);
logger.error("Backend startup failed", { error: error.message });
await pool.end();
process.exit(1);
}
}
main();