Files

52 lines
1.9 KiB
TypeScript

import Fastify from "fastify";
import cors from "@fastify/cors";
import fastifyStatic from "@fastify/static";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { systemsRoutes } from "./routes/systems.js";
import { structuresRoutes } from "./routes/structures.js";
import { quizRoutes } from "./routes/quiz.js";
import { analyticsRoutes } from "./routes/analytics.js";
import { adminRoutes } from "./routes/admin.js";
import { feedbackRoutes } from "./routes/feedback.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const MODELS_DIR = process.env.MODELS_DIR ?? path.resolve(__dirname, "../models");
// trustProxy: essencial pra "req.ip" refletir o visitante real (via
// X-Forwarded-For) em vez do IP do nginx interno — ver nginx/nginx.conf,
// que já repassa X-Forwarded-For a partir do reverse proxy externo.
const app = Fastify({ logger: true, trustProxy: true });
await app.register(cors, { origin: true });
// Cache-Control é decidido no nginx interno (ver nginx/nginx.conf,
// location /models/), não aqui — "immutable"/maxAge nesse nível conflitava
// com o "no-cache" que o nginx adiciona por cima (dois headers
// Cache-Control na mesma resposta, comportamento indefinido entre
// navegadores), e ia contra o motivo do "no-cache": os .glb têm nome fixo
// mas o CONTEÚDO muda toda vez que o pipeline roda de novo.
await app.register(fastifyStatic, {
root: MODELS_DIR,
prefix: "/models/",
decorateReply: false,
etag: true,
});
app.get("/api/health", async () => ({ status: "ok" }));
await app.register(systemsRoutes);
await app.register(structuresRoutes);
await app.register(quizRoutes);
await app.register(analyticsRoutes);
await app.register(adminRoutes);
await app.register(feedbackRoutes);
const port = Number(process.env.PORT ?? 3333);
app
.listen({ port, host: "0.0.0.0" })
.catch((err) => {
app.log.error(err);
process.exit(1);
});