import { createServer } from "node:http"; import os from "node:os"; import createApp from "./app.js"; import { db } from "./db/db.controller.js"; import { dbCleanup } from "./db/dbCleanup.controller.js"; import { type Setting, settings } from "./db/schema/settings.schema.js"; import { connectGPSql } from "./gpSql/gpSqlConnection.controller.js"; import { createLogger } from "./logger/logger.controller.js"; import { startNotifications } from "./notification/notification.controller.js"; import { createNotifications } from "./notification/notifications.master.js"; import { printerSync } from "./ocp/ocp.printer.manage.js"; import { monitorReleaseChanges } from "./opendock/openDockRreleaseMonitor.utils.js"; import { opendockSocketMonitor } from "./opendock/opendockSocketMonitor.utils.js"; import { connectProdSql } from "./prodSql/prodSqlConnection.controller.js"; import { monitorAlplaPurchase } from "./purchase/purchase.controller.js"; import { setupSocketIORoutes } from "./socket.io/serverSetup.js"; import { baseSettingValidationCheck } from "./system/settingsBase.controller.js"; import { startTCPServer } from "./tcpServer/tcp.server.js"; import { createCronJob } from "./utils/croner.utils.js"; import { sendEmail } from "./utils/sendEmail.utils.js"; const port = Number(process.env.PORT) || 3000; export let systemSettings: Setting[] = []; const start = async () => { const { app, baseUrl } = await createApp(); const server = createServer(app); setupSocketIORoutes(baseUrl, server); const log = createLogger({ module: "system", subModule: "main start" }); // triggering long lived processes startTCPServer(); connectProdSql(); connectGPSql(); // trigger startup processes these must run before anything else can run await baseSettingValidationCheck(); systemSettings = await db.select().from(settings); //when starting up long lived features the name must match the setting name. // also we always want to have long lived processes inside a setting check. setTimeout(() => { if (systemSettings.filter((n) => n.name === "opendock_sync")[0]?.active) { log.info({}, "Opendock is active"); monitorReleaseChanges(); // this is od monitoring the db for all new releases opendockSocketMonitor(); createCronJob("opendockAptCleanup", "0 30 5 * * *", () => dbCleanup("opendockApt", 90), ); } if (systemSettings.filter((n) => n.name === "purchaseMonitor")[0]?.active) { monitorAlplaPurchase(); } if (systemSettings.filter((n) => n.name === "ocp")[0]?.active) { printerSync(); } // these jobs below are system jobs and should run no matter what. createCronJob("JobAuditLogCleanUp", "0 0 5 * * *", () => dbCleanup("jobs", 30), ); createCronJob("logsCleanup", "0 15 5 * * *", () => dbCleanup("logs", 120)); // one shots only needed to run on server startups createNotifications(); startNotifications(); }, 5 * 1000); process.on("uncaughtException", async (err) => { console.error("Uncaught Exception:", err); //await closePool(); const emailData = { email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused. subject: `${os.hostname()} has just encountered a crash.`, template: "serverCrash", context: { error: err, plant: `${os.hostname()}`, }, }; await sendEmail(emailData); //process.exit(1); }); server.listen(port, async () => { log.info( `Listening on http://${os.hostname()}:${port}${baseUrl}, logging in ${process.env.LOG_LEVEL}, current ENV ${process.env.NODE_ENV ? process.env.NODE_ENV : "development"}`, ); }); }; start();