eletrotupi / tcc / api/src/createApp.ts master
2.1 KB Raw
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
import morgan from "morgan";
import mainRouter from "@app/routes/main";
import userRouter from "@app/routes/users";
import authRouter from "@app/routes/auth";
import moodRouter from "@app/routes/moods";
import triggerRouter from "@app/routes/triggers";
import sleepRecordRouter from "@app/routes/sleepRecords";
import insightRouter from "@app/routes/insights";
import { errorHandler } from "@app/middleware/errorHandler";
import { PrismaClient } from "@prisma/client";
import {
  bootWorkers,
  closeAllWorkers,
  closeAllQueues,
  scheduleInsights,
} from "@app/lib/queue";

import pino from "pino";
import pinoHttp from "pino-http";
import path from "path";

export function createApp() {
  const app = express();
  bootWorkers();
  scheduleInsights();

  // Configure CORS
  app.use(
    cors({
      origin: process.env.FRONTEND_URL || "*",
      credentials: true,
    }),
  );

  app.use(bodyParser.json());

  const isDev = process.env.NODE_ENV !== "production";

  const logger = pino({
    level: process.env.LOG_LEVEL || "info",
    ...(isDev && {
      transport: {
        target: "pino-pretty",
        options: {
          colorize: true,
          singleLine: false,
          messageFormat: "{if levelLabel}{levelLabel} - {end}{msg}",
        },
      },
    }),
  });

  // Use pino-http for HTTP logging (better than Morgan for structured logs)
  app.use(pinoHttp({ logger }));

  app.use("/users", userRouter);
  app.use("/auth", authRouter);
  app.use("/moods", moodRouter);
  app.use("/sleep_records", sleepRecordRouter);
  app.use("/triggers", triggerRouter);
  app.use("/insights", insightRouter);

  app.use(errorHandler); // always last

  // TODO: flesh the actual page here
  app.use(express.static(path.join(__dirname, "./static")));
  app.get(/.*/, (req, res) => {
    res.sendFile(path.join(__dirname, "./static/index.html"));
  });

  process.on("SIGTERM", shutdown);
  process.on("SIGINT", shutdown);

  return app;
}

const shutdown = async () => {
  await Promise.all([closeAllWorkers(), closeAllQueues()]);
  process.exit(0);
};