import { Application, Router } from "@oak/oak"; import { config } from "./config/env.ts"; import { db } from "./config/database.ts"; import { cors, rateLimit, requestLogger, securityHeaders, } from "./middleware/security.ts"; // Import routes import authRoutes from "./routes/auth.ts"; import userRoutes from "./routes/users.ts"; import departmentRoutes from "./routes/departments.ts"; import workAllocationRoutes from "./routes/work-allocations.ts"; import attendanceRoutes from "./routes/attendance.ts"; import contractorRateRoutes from "./routes/contractor-rates.ts"; import employeeSwapRoutes from "./routes/employee-swaps.ts"; import reportRoutes from "./routes/reports.ts"; import standardRateRoutes from "./routes/standard-rates.ts"; import activityRoutes from "./routes/activities.ts"; // Initialize database connection await db.connect(); // Create Oak application const app = new Application(); // Global error handler app.use(async (ctx, next) => { try { await next(); } catch (err) { const error = err as Error & { status?: number }; console.error("Error:", error.message); ctx.response.status = error.status || 500; ctx.response.body = { error: config.isDevelopment() ? error.message : "Internal server error", }; } }); // Apply security middleware app.use(cors); app.use(securityHeaders); app.use(requestLogger); // Rate limiting (only in production or if enabled) if (config.isProduction()) { app.use(rateLimit); } // Create main router const router = new Router(); // Health check endpoint router.get("/health", (ctx) => { ctx.response.body = { status: "ok", timestamp: new Date().toISOString(), version: "2.0.0-deno", runtime: "Deno", }; }); // Mount API routes router.use("/api/auth", authRoutes.routes(), authRoutes.allowedMethods()); router.use("/api/users", userRoutes.routes(), userRoutes.allowedMethods()); router.use( "/api/departments", departmentRoutes.routes(), departmentRoutes.allowedMethods(), ); router.use( "/api/work-allocations", workAllocationRoutes.routes(), workAllocationRoutes.allowedMethods(), ); router.use( "/api/attendance", attendanceRoutes.routes(), attendanceRoutes.allowedMethods(), ); router.use( "/api/contractor-rates", contractorRateRoutes.routes(), contractorRateRoutes.allowedMethods(), ); router.use( "/api/employee-swaps", employeeSwapRoutes.routes(), employeeSwapRoutes.allowedMethods(), ); router.use( "/api/reports", reportRoutes.routes(), reportRoutes.allowedMethods(), ); router.use( "/api/standard-rates", standardRateRoutes.routes(), standardRateRoutes.allowedMethods(), ); router.use( "/api/activities", activityRoutes.routes(), activityRoutes.allowedMethods(), ); // Apply routes app.use(router.routes()); app.use(router.allowedMethods()); // 404 handler app.use((ctx) => { ctx.response.status = 404; ctx.response.body = { error: "Route not found" }; }); // Graceful shutdown const controller = new AbortController(); Deno.addSignalListener("SIGINT", () => { console.log("\nšŸ›‘ Shutting down gracefully..."); controller.abort(); db.close(); Deno.exit(0); }); Deno.addSignalListener("SIGTERM", () => { console.log("\nšŸ›‘ Shutting down gracefully..."); controller.abort(); db.close(); Deno.exit(0); }); // Start server console.log(` ╔════════════════════════════════════════════════════════════╗ ā•‘ Work Allocation System - Deno Backend v2.0.0 ā•‘ ╠════════════════════════════════════════════════════════════╣ ā•‘ šŸ¦• Runtime: Deno ${Deno.version.deno} ā•‘ ā•‘ šŸ”’ TypeScript with strict type checking ā•‘ ā•‘ šŸ›”ļø Security: Rate limiting, CORS, XSS protection ā•‘ ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• `); console.log(`šŸš€ Server running on http://localhost:${config.PORT}`); console.log(`šŸ“Š Health check: http://localhost:${config.PORT}/health`); console.log(`šŸ”§ Environment: ${config.NODE_ENV}`); await app.listen({ port: config.PORT, signal: controller.signal });