Import source: backend/src/app
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,120 @@
|
|||||||
|
import Fastify from "fastify";
|
||||||
|
import cors from "@fastify/cors";
|
||||||
|
import helmet from "@fastify/helmet";
|
||||||
|
import jwt from "@fastify/jwt";
|
||||||
|
import {
|
||||||
|
serializerCompiler,
|
||||||
|
validatorCompiler,
|
||||||
|
ZodTypeProvider,
|
||||||
|
} from "fastify-type-provider-zod";
|
||||||
|
|
||||||
|
import { env } from "./config/env.js";
|
||||||
|
import { prismaPlugin } from "./plugins/prisma.js";
|
||||||
|
import { errorHandler } from "./plugins/error-handler.js";
|
||||||
|
import { fail } from "./lib/envelope.js";
|
||||||
|
import { authRoutes } from "./routes/auth.js";
|
||||||
|
import { websiteRoutes } from "./routes/websites.js";
|
||||||
|
import { domainRoutes } from "./routes/domains.js";
|
||||||
|
import { panelRoutes } from "./routes/panel.js";
|
||||||
|
import { moduleRoutes } from "./routes/modules.js";
|
||||||
|
|
||||||
|
export function buildApp() {
|
||||||
|
const app = Fastify({
|
||||||
|
logger:
|
||||||
|
env.NODE_ENV === "development"
|
||||||
|
? {
|
||||||
|
transport: { target: "pino-pretty" },
|
||||||
|
}
|
||||||
|
: false,
|
||||||
|
}).withTypeProvider<ZodTypeProvider>();
|
||||||
|
|
||||||
|
// Register JSON schemas compilers for Zod
|
||||||
|
app.setValidatorCompiler(validatorCompiler);
|
||||||
|
app.setSerializerCompiler(serializerCompiler);
|
||||||
|
app.removeContentTypeParser("application/json");
|
||||||
|
app.addContentTypeParser(
|
||||||
|
"application/json",
|
||||||
|
{ parseAs: "string" },
|
||||||
|
(_request, body, done) => {
|
||||||
|
const text = typeof body === "string" ? body : body.toString("utf8");
|
||||||
|
if (text.trim() === "") {
|
||||||
|
done(null, undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
done(null, JSON.parse(text));
|
||||||
|
} catch (error) {
|
||||||
|
done(error as Error, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Security Plugins
|
||||||
|
app.register(helmet);
|
||||||
|
app.register(cors, { origin: true, credentials: true });
|
||||||
|
app.register(jwt, { secret: env.JWT_SECRET });
|
||||||
|
|
||||||
|
// Custom Plugins
|
||||||
|
app.register(prismaPlugin);
|
||||||
|
app.setErrorHandler(errorHandler);
|
||||||
|
|
||||||
|
app.get("/api/rate-limited", async (request, reply) =>
|
||||||
|
fail(
|
||||||
|
request,
|
||||||
|
reply,
|
||||||
|
429,
|
||||||
|
{
|
||||||
|
code: "RATE_LIMIT_ERROR",
|
||||||
|
message: "Too many requests. Please try again later.",
|
||||||
|
},
|
||||||
|
{ rateLimit: { limit: 5, remaining: 0, reset: 100 } },
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/api/simulate-500", async () => {
|
||||||
|
throw new Error("Internal server error simulated successfully.");
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/auth/login", async (request, reply) =>
|
||||||
|
fail(request, reply, 405, {
|
||||||
|
code: "METHOD_NOT_ALLOWED",
|
||||||
|
message: "GET is not allowed for this endpoint.",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
app.register(authRoutes);
|
||||||
|
app.register(websiteRoutes);
|
||||||
|
app.register(domainRoutes);
|
||||||
|
app.register(panelRoutes);
|
||||||
|
app.register(moduleRoutes);
|
||||||
|
|
||||||
|
// Health check route
|
||||||
|
app.get("/health", async (request, reply) => {
|
||||||
|
try {
|
||||||
|
// Verify database connection using Prisma
|
||||||
|
await app.prisma.$queryRaw`SELECT 1`;
|
||||||
|
return {
|
||||||
|
status: "ok",
|
||||||
|
database: "connected",
|
||||||
|
};
|
||||||
|
} catch (err: unknown) {
|
||||||
|
app.log.error(err);
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
return reply.status(500).send({
|
||||||
|
status: "error",
|
||||||
|
database: "disconnected",
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.setNotFoundHandler((request, reply) =>
|
||||||
|
fail(request, reply, 404, {
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: `Route ${request.method} ${request.url} was not found.`,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user