(Feat-Fix): New Activity Creation system, fixed activities being hardcoded and not displaying properly in the dropdown, added dynamic subdepartment activity fetching.

This commit is contained in:
2025-12-18 09:30:44 +00:00
parent ac29bb2882
commit 2a38cf372a
8 changed files with 698 additions and 21 deletions

View File

@@ -101,35 +101,140 @@ router.post("/", authenticateToken, authorize("SuperAdmin"), async (ctx) => {
}
});
// Create sub-department (SuperAdmin only)
router.post("/:id/sub-departments", authenticateToken, authorize("SuperAdmin"), async (ctx) => {
// Create sub-department (SuperAdmin or Supervisor for their own department)
router.post("/sub-departments", authenticateToken, async (ctx) => {
try {
const deptId = ctx.params.id;
const body = await ctx.request.body.json() as { name: string; primaryActivity: string };
const { name, primaryActivity } = body;
const user = getCurrentUser(ctx);
const body = await ctx.request.body.json() as { department_id: number; name: string };
const { department_id, name } = body;
if (!name || !primaryActivity) {
if (!name || !department_id) {
ctx.response.status = 400;
ctx.response.body = { error: "Name and primary activity required" };
ctx.response.body = { error: "Department ID and name are required" };
return;
}
// Check authorization
if (user.role === 'Supervisor' && user.departmentId !== department_id) {
ctx.response.status = 403;
ctx.response.body = { error: "You can only create sub-departments for your own department" };
return;
}
if (user.role !== 'SuperAdmin' && user.role !== 'Supervisor') {
ctx.response.status = 403;
ctx.response.body = { error: "Unauthorized" };
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]
"INSERT INTO sub_departments (department_id, name) VALUES (?, ?)",
[department_id, sanitizedName]
);
const newSubDepartment = await db.query<SubDepartment[]>(
"SELECT * FROM sub_departments WHERE id = ?",
[result.insertId]
[result.lastInsertId]
);
ctx.response.status = 201;
ctx.response.body = newSubDepartment[0];
} catch (error) {
const err = error as { code?: string };
if (err.code === "ER_DUP_ENTRY") {
ctx.response.status = 400;
ctx.response.body = { error: "Sub-department already exists in this department" };
return;
}
console.error("Create sub-department error:", error);
ctx.response.status = 500;
ctx.response.body = { error: "Internal server error" };
}
});
// Delete sub-department (SuperAdmin or Supervisor for their own department)
router.delete("/sub-departments/:id", authenticateToken, async (ctx) => {
try {
const user = getCurrentUser(ctx);
const subDeptId = ctx.params.id;
// Get the sub-department to check department ownership
const subDepts = await db.query<SubDepartment[]>(
"SELECT * FROM sub_departments WHERE id = ?",
[subDeptId]
);
if (subDepts.length === 0) {
ctx.response.status = 404;
ctx.response.body = { error: "Sub-department not found" };
return;
}
const subDept = subDepts[0];
// Check authorization
if (user.role === 'Supervisor' && user.departmentId !== subDept.department_id) {
ctx.response.status = 403;
ctx.response.body = { error: "You can only delete sub-departments from your own department" };
return;
}
if (user.role !== 'SuperAdmin' && user.role !== 'Supervisor') {
ctx.response.status = 403;
ctx.response.body = { error: "Unauthorized" };
return;
}
// Delete associated activities first (cascade should handle this, but being explicit)
await db.execute("DELETE FROM activities WHERE sub_department_id = ?", [subDeptId]);
// Delete the sub-department
await db.execute("DELETE FROM sub_departments WHERE id = ?", [subDeptId]);
ctx.response.body = { message: "Sub-department deleted successfully" };
} catch (error) {
console.error("Delete sub-department error:", error);
ctx.response.status = 500;
ctx.response.body = { error: "Internal server error" };
}
});
// Legacy route for creating sub-department under specific 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 };
const { name } = body;
if (!name) {
ctx.response.status = 400;
ctx.response.body = { error: "Name is required" };
return;
}
const sanitizedName = sanitizeInput(name);
const result = await db.execute(
"INSERT INTO sub_departments (department_id, name) VALUES (?, ?)",
[deptId, sanitizedName]
);
const newSubDepartment = await db.query<SubDepartment[]>(
"SELECT * FROM sub_departments WHERE id = ?",
[result.lastInsertId]
);
ctx.response.status = 201;
ctx.response.body = newSubDepartment[0];
} catch (error) {
const err = error as { code?: string };
if (err.code === "ER_DUP_ENTRY") {
ctx.response.status = 400;
ctx.response.body = { error: "Sub-department already exists in this department" };
return;
}
console.error("Create sub-department error:", error);
ctx.response.status = 500;
ctx.response.body = { error: "Internal server error" };