import { sdkLogger as logger } from "../services/reporting-service/logger.js"; import { CoreConfiguration } from "../services/data-sync-service/configuration-manager.js"; import { SQLiteCoordinator } from "../services/sqlite-service/index.js"; import { ensureCompanyInfo } from "../services/mm-api-service/company-info.js"; import knex from "knex"; import config from "../knexfile.js"; /** * Utility class to handle application initialization tasks */ export class ApplicationInitializer { /** * Performs all necessary application initialization tasks * This should be called before starting any services or jobs */ public static async initialize(): Promise { try { logger.info( "\n================================INITIALIZING APPLICATION================================\n" ); // Load and validate core configuration const coreConfig = CoreConfiguration.inst(); logger.info("Core Configuration loaded:", coreConfig.toSafeLogObject()); // Migrations first: runtime-state reads (startup lock check) use sdk_runtime_state, // which must exist via migrate.latest before any lazy CREATE TABLE IF NOT EXISTS runs. logger.info("Running database migrations..."); await ApplicationInitializer.runMigrations(); logger.info("Database migrations completed successfully"); logger.info("Performing database startup checks..."); await SQLiteCoordinator.performStartupCheck(); logger.info("Database startup checks completed successfully"); // Loads company info from MM into memory + SQLite runtime state (timezone, locationRef, companyId). // Retries until success; failure aborts init. Confirms the MM API token works for /accounts/current. await ensureCompanyInfo(); logger.info( "\n================================APPLICATION INITIALIZATION COMPLETED================================\n" ); } catch (error) { logger.error("Critical initialization failure. Exiting.", error); process.exitCode = 1; } } /** * Runs database migrations to ensure all required tables exist */ private static async runMigrations(): Promise { const db = knex(config.local); try { await db.migrate.latest(); } catch (error) { logger.error("Error running migrations:", error); throw error; } finally { await db.destroy(); } } }