import Fastify from 'fastify'; import path from 'path'; import { fileURLToPath } from 'url'; import fastifyStatic from '@fastify/static'; import { AppStatus } from '@ludops/shared'; import { db } from './db/index.js'; import { visits } from './db/schemas.js'; import { sql } from 'drizzle-orm'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const fastify = Fastify({ logger: true }); // API Route fastify.get('/api/status', async (): Promise => { const [result] = await db.select({ count: sql`count(*)` }).from(visits); return { status: 'OK', version: '1.0.0', database: true, totalVisits: Number(result.count) }; }); // Serve Frontend (Vite Dist) const webDistPath = process.env.NODE_ENV === 'production' ? path.join(__dirname, '../web-dist') // Adjusted for the flattened Docker structure : path.join(__dirname, '../../web/dist'); fastify.register(fastifyStatic, { root: webDistPath, prefix: '/', }); // SPA Routing: Redirect everything else to index.html fastify.setNotFoundHandler((req, reply) => { if (req.url.startsWith('/api')) { reply.code(404).send({ error: 'Not Found' }); } else { reply.sendFile('index.html'); } }); fastify.listen({ port: 3000, host: '0.0.0.0' }); fastify.addHook('onRequest', async (request) => { try { if (request.url.startsWith('/api')) { await db.insert(visits).values({ ip: request.ip, userAgent: request.headers['user-agent'] || '', }); } } catch (error) { fastify.log.error(`Failed to log visit: ${error}`); } });