Build Phase 1 application foundation

This commit is contained in:
Media
2026-08-16 19:16:45 -05:00
parent 9aab48643b
commit eb19675a5c
30 changed files with 3375 additions and 2207 deletions
+81
View File
@@ -0,0 +1,81 @@
const express = require("express");
const {
createDetailedHealthRouter,
createHealthRouter,
} = require("./health/routes");
const { createSettingsRouter } = require("./settings/routes");
const { createSettingsService } = require("./settings/service");
function createApp({ config, database, lifecycle, migrations }) {
const app = express();
const settingsService = createSettingsService(database);
app.disable("x-powered-by");
app.set("trust proxy", config.trustProxy);
app.use(express.json({ limit: "1mb" }));
app.get("/api", (request, response) => {
response.json({ name: "Announcements API", version: 2 });
});
app.use(
"/health",
createHealthRouter({ database, lifecycle, migrations }),
);
const detailedHealthRouterOptions = {
config,
database,
lifecycle,
migrations,
};
app.use(
"/api/health",
createDetailedHealthRouter(detailedHealthRouterOptions),
);
app.use(
"/api/status",
createDetailedHealthRouter(detailedHealthRouterOptions),
);
app.use("/api/settings", createSettingsRouter(settingsService));
app.use((request, response) => {
response.status(404).json({
error: {
code: "NOT_FOUND",
message: "Route not found",
},
});
});
app.use((error, request, response, next) => {
if (response.headersSent) {
next(error);
return;
}
if (error instanceof SyntaxError && error.status === 400 && "body" in error) {
response.status(400).json({
error: {
code: "INVALID_JSON",
message: "Request body must contain valid JSON",
},
});
return;
}
const statusCode = error.statusCode || 500;
response.status(statusCode).json({
error: {
code: error.code || "INTERNAL_ERROR",
message:
statusCode >= 500 ? "An internal server error occurred" : error.message,
...(error.details ? { details: error.details } : {}),
},
});
});
return app;
}
module.exports = {
createApp,
};