import Fastify from "fastify"; import cors from "@fastify/cors"; import helmet from "@fastify/helmet"; import rateLimit from "@fastify/rate-limit"; import jwt from "@fastify/jwt"; import cookie from "@fastify/cookie"; import { env } from "@/config/env.js"; import { RATE_LIMITS } from "@/config/constants.js"; import { authRoutes } from "@/routes/auth.routes.js"; import { storeRoutes } from "@/routes/store.routes.js"; import { paymentRoutes } from "@/routes/payment.routes.js"; import { feedbackRoutes, adminFeedbackRoutes } from "@/routes/feedback.routes.js"; import { externalApiRoutes } from "@/routes/external.routes.js"; import { adminProductsRoutes } from "@/routes/admin/products.routes.js"; import { adminStockRoutes } from "@/routes/admin/stock.routes.js"; import { adminOrdersRoutes } from "@/routes/admin/orders.routes.js"; import { adminCouponsRoutes } from "@/routes/admin/coupons.routes.js"; import { adminCategoriesRoutes } from "@/routes/admin/categories.routes.js"; import { adminCustomersRoutes } from "@/routes/admin/customers.routes.js"; import { adminAnalyticsRoutes } from "@/routes/admin/analytics.routes.js"; import { adminSettingsRoutes } from "@/routes/admin/settings.routes.js"; import { adminBlacklistRoutes } from "@/routes/admin/blacklist.routes.js"; import { adminWebhooksRoutes } from "@/routes/admin/webhooks.routes.js"; import { adminApiKeysRoutes } from "@/routes/admin/apikeys.routes.js"; import { adminAuditLogRoutes } from "@/routes/admin/auditlog.routes.js"; import { healthRoutes } from "@/routes/health.routes.js"; export async function buildApp() { const app = Fastify({ logger: { level: env.NODE_ENV === "development" ? "debug" : "info", transport: env.NODE_ENV === "development" ? { target: "pino-pretty", options: { colorize: true } } : undefined, }, trustProxy: true, }); await app.register(cors, { origin: [env.FRONTEND_URL], credentials: true, methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], }); await app.register(helmet, { contentSecurityPolicy: false, }); await app.register(rateLimit, { max: RATE_LIMITS.STORE.max, timeWindow: RATE_LIMITS.STORE.timeWindow, }); await app.register(jwt, { secret: env.JWT_SECRET, }); await app.register(cookie, { secret: env.JWT_SECRET, }); await app.register(healthRoutes, { prefix: "/api/health" }); await app.register(authRoutes, { prefix: "/api/admin/auth" }); await app.register(storeRoutes, { prefix: "/api/store" }); await app.register(feedbackRoutes, { prefix: "/api/store" }); await app.register(paymentRoutes, { prefix: "/api/webhooks" }); await app.register(externalApiRoutes, { prefix: "/api/v1" }); await app.register(adminProductsRoutes, { prefix: "/api/admin/products" }); await app.register(adminStockRoutes, { prefix: "/api/admin" }); await app.register(adminOrdersRoutes, { prefix: "/api/admin/orders" }); await app.register(adminCouponsRoutes, { prefix: "/api/admin/coupons" }); await app.register(adminCategoriesRoutes, { prefix: "/api/admin/categories" }); await app.register(adminCustomersRoutes, { prefix: "/api/admin/customers" }); await app.register(adminAnalyticsRoutes, { prefix: "/api/admin/analytics" }); await app.register(adminSettingsRoutes, { prefix: "/api/admin/settings" }); await app.register(adminBlacklistRoutes, { prefix: "/api/admin/blacklist" }); await app.register(adminWebhooksRoutes, { prefix: "/api/admin/webhooks" }); await app.register(adminApiKeysRoutes, { prefix: "/api/admin/apikeys" }); await app.register(adminAuditLogRoutes, { prefix: "/api/admin/audit-log" }); await app.register(adminFeedbackRoutes, { prefix: "/api/admin/feedback" }); app.setErrorHandler((error, request, reply) => { request.log.error(error); if (error.validation) { return reply.status(400).send({ success: false, error: "Validation Error", details: error.validation, }); } const statusCode = error.statusCode ?? 500; const message = statusCode === 500 ? "Internal Server Error" : error.message; return reply.status(statusCode).send({ success: false, error: message, }); }); app.setNotFoundHandler((request, reply) => { return reply.status(404).send({ success: false, error: "Route not found", }); }); return app; }