// server.js — Phusion Passenger / Plesk production entrypoint // // Plesk sets PORT, then runs: node server.js // We register the tsx ESM loader so TypeScript source is imported directly // (no compile step needed), build the Fastify app, then start listening. import { register } from 'tsx/esm/api'; register(); // server.ts exports buildServer(); env.ts exports the validated env object. // Both are loaded through tsx so TypeScript is handled transparently. const { buildServer } = await import('./apps/api/src/server.ts'); const { env } = await import('./apps/api/src/env.ts'); const app = await buildServer(); // ── Graceful shutdown ────────────────────────────────────────────────────── async function shutdown(signal) { app.log.info(`${signal} received — closing server`); try { await app.close(); } catch (err) { app.log.error(err, 'error during shutdown'); } process.exit(0); } process.on('SIGTERM', () => void shutdown('SIGTERM')); process.on('SIGINT', () => void shutdown('SIGINT')); // Surface hard crashes — Sentry is already initialised inside buildServer(). process.on('uncaughtException', (err) => { app.log.error(err, 'uncaughtException'); process.exit(1); }); process.on('unhandledRejection', (reason) => { app.log.error({ reason }, 'unhandledRejection'); process.exit(1); }); // ── Start ────────────────────────────────────────────────────────────────── // Passenger injects PORT; env.ts validates and defaults it to 8080 in dev. await app.listen({ host: '0.0.0.0', port: env.PORT }); app.log.info(`eLegal Software ready · port ${env.PORT}`);