import { Router } from "@oak/oak"; import { db } from "../config/database.ts"; import { authenticateToken, authorize, getCurrentUser } from "../middleware/auth.ts"; import { sanitizeInput } from "../middleware/security.ts"; import type { Department, SubDepartment } from "../types/index.ts"; const router = new Router(); // Get all departments router.get("/", authenticateToken, async (ctx) => { try { const departments = await db.query( "SELECT * FROM departments ORDER BY name" ); ctx.response.body = departments; } catch (error) { console.error("Get departments error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }); // Get department by ID router.get("/:id", authenticateToken, async (ctx) => { try { const deptId = ctx.params.id; const departments = await db.query( "SELECT * FROM departments WHERE id = ?", [deptId] ); if (departments.length === 0) { ctx.response.status = 404; ctx.response.body = { error: "Department not found" }; return; } ctx.response.body = departments[0]; } catch (error) { console.error("Get department error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }); // Get sub-departments by department ID router.get("/:id/sub-departments", authenticateToken, async (ctx) => { try { const deptId = ctx.params.id; const subDepartments = await db.query( "SELECT * FROM sub_departments WHERE department_id = ? ORDER BY name", [deptId] ); ctx.response.body = subDepartments; } catch (error) { console.error("Get sub-departments error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }); // Create department (SuperAdmin only) router.post("/", authenticateToken, authorize("SuperAdmin"), async (ctx) => { try { const body = await ctx.request.body.json() as { name: string }; const { name } = body; if (!name) { ctx.response.status = 400; ctx.response.body = { error: "Department name required" }; return; } const sanitizedName = sanitizeInput(name); const result = await db.execute( "INSERT INTO departments (name) VALUES (?)", [sanitizedName] ); const newDepartment = await db.query( "SELECT * FROM departments WHERE id = ?", [result.insertId] ); ctx.response.status = 201; ctx.response.body = newDepartment[0]; } catch (error) { const err = error as { code?: string }; if (err.code === "ER_DUP_ENTRY") { ctx.response.status = 400; ctx.response.body = { error: "Department already exists" }; return; } console.error("Create department error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }); // Create sub-department (SuperAdmin only) router.post("/:id/sub-departments", authenticateToken, authorize("SuperAdmin"), async (ctx) => { try { const deptId = ctx.params.id; const body = await ctx.request.body.json() as { name: string; primaryActivity: string }; const { name, primaryActivity } = body; if (!name || !primaryActivity) { ctx.response.status = 400; ctx.response.body = { error: "Name and primary activity required" }; return; } const sanitizedName = sanitizeInput(name); const sanitizedActivity = sanitizeInput(primaryActivity); const result = await db.execute( "INSERT INTO sub_departments (department_id, name, primary_activity) VALUES (?, ?, ?)", [deptId, sanitizedName, sanitizedActivity] ); const newSubDepartment = await db.query( "SELECT * FROM sub_departments WHERE id = ?", [result.insertId] ); ctx.response.status = 201; ctx.response.body = newSubDepartment[0]; } catch (error) { console.error("Create sub-department error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }); export default router;