import { serve } from "@hono/node-server"; import { loadConfig } from "./lib/config.js"; import { createAppContext, destroyAppContext } from "./lib/app-context.js"; import { createApp } from "./lib/create-app.js"; import { seedDefaultRoles } from "./lib/seed-roles.js"; async function main() { // Load configuration const config = loadConfig(); // Create application context with all dependencies const ctx = await createAppContext(config); const { logger } = ctx; // Wire BackfillManager ↔ FirehoseService (two-phase init: both exist now) if (ctx.backfillManager) { ctx.firehose.setBackfillManager(ctx.backfillManager); ctx.backfillManager.setIndexer(ctx.firehose.getIndexer()); } // Seed default roles if enabled if (process.env.SEED_DEFAULT_ROLES !== "false") { logger.info("Seeding default roles"); const result = await seedDefaultRoles(ctx); logger.info("Default roles seeded", { created: result.created, skipped: result.skipped, }); } else { logger.info("Role seeding disabled via SEED_DEFAULT_ROLES=false"); } // Create Hono app const app = createApp(ctx); // Start HTTP server const server = serve( { fetch: app.fetch, port: config.port, }, (info) => { logger.info("Server started", { url: `http://localhost:${info.port}`, port: info.port, }); } ); // Start firehose subscription ctx.firehose.start().catch((error) => { logger.fatal("Failed to start firehose", { error: error instanceof Error ? error.message : String(error), }); process.exit(1); }); // Graceful shutdown handler const shutdown = async (signal: string) => { logger.info("Shutdown initiated", { signal }); try { await destroyAppContext(ctx); server.close(() => { logger.info("Server closed"); process.exit(0); }); setTimeout(() => { logger.error("Forced shutdown after timeout"); process.exit(1); }, 10000); } catch (error) { logger.error("Error during shutdown", { error: error instanceof Error ? error.message : String(error), }); process.exit(1); } }; process.on("SIGTERM", () => shutdown("SIGTERM")); process.on("SIGINT", () => shutdown("SIGINT")); } main().catch((error) => { // Logger may not be initialized yet — fall back to structured stderr process.stderr.write( JSON.stringify({ timestamp: new Date().toISOString(), level: "fatal", message: "Fatal error during startup", service: "atbb-appview", error: error?.message || String(error), stack: error?.stack, }) + "\n" ); process.exit(1); });