eletrotupi / tcc/ api/src/createApp.tsa2ea1352da034bd3377e2a3cbfa4c53a75eba523
2.7 KB | 92 lines Raw
1
import express from "express";
2
import cors from "cors";
3
import bodyParser from "body-parser";
4
import mainRouter from "@app/routes/main";
5
import userRouter from "@app/routes/users";
6
import authRouter from "@app/routes/auth";
7
import moodRouter from "@app/routes/moods";
8
import triggerRouter from "@app/routes/triggers";
9
import sleepRecordRouter from "@app/routes/sleepRecords";
10
import insightRouter from "@app/routes/insights";
11
import careActionsRouter from "@app/routes/careActions";
12
import medicineRegimensRouter from "@app/routes/medicineRegimens";
13
import exportsRouter from "@app/routes/exports";
14
import notificationRouter from "@app/routes/notifications";
15
import reportRouter from "@app/reports/report.router";
16
import { errorHandler } from "@app/middleware/errorHandler";
17
import { logger } from "@app/lib/logger";
18
import { PrismaClient } from "@prisma/client";
19
import {
20
  bootWorkers,
21
  closeAllWorkers,
22
  closeAllQueues,
23
  scheduleInsights,
24
} from "@app/lib/queue";
25

26
import pinoHttp from "pino-http";
27
import { randomUUID } from "crypto";
28
import path from "path";
29

30
export function createApp() {
31
  const app = express();
32
  bootWorkers();
33
  scheduleInsights();
34

35
  // Use pino-http for HTTP logging (better than Morgan for structured logs)
36
  // Registered before the rest so every request has a logger attached,
37
  // including errors raised by the CORS and body-parsing middleware below
38
  app.use(
39
    pinoHttp({
40
      logger,
41
      genReqId: (req, res) => {
42
        const header = req.headers["x-request-id"];
43
        const requestId =
44
          (Array.isArray(header) ? header[0] : header) || randomUUID();
45

46
        res.setHeader("X-Request-Id", requestId);
47

48
        return requestId;
49
      },
50
    }),
51
  );
52

53
  // Configure CORS
54
  app.use(
55
    cors({
56
      origin: process.env.FRONTEND_URL || "*",
57
      credentials: true,
58
    }),
59
  );
60

61
  app.use(bodyParser.json());
62

63
  app.use("/users", userRouter);
64
  app.use("/auth", authRouter);
65
  app.use("/moods", moodRouter);
66
  app.use("/sleep_records", sleepRecordRouter);
67
  app.use("/triggers", triggerRouter);
68
  app.use("/insights", insightRouter);
69
  app.use("/care-actions", careActionsRouter);
70
  app.use("/medicine-regimens", medicineRegimensRouter);
71
  app.use("/exports", exportsRouter);
72
  app.use("/notifications", notificationRouter);
73
  app.use("/reports", reportRouter);
74

75
  app.use(errorHandler); // always last
76

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

83
  process.on("SIGTERM", shutdown);
84
  process.on("SIGINT", shutdown);
85

86
  return app;
87
}
88

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