"use server" import { revalidatePath } from "next/cache" import { createId } from "@paralleldrive/cuid2" import { eq } from "drizzle-orm" import { db } from "@/shared/db" import { academicYears, departments, grades, schools } from "@/shared/db/schema" import type { ActionState } from "@/shared/types/action-state" import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard" import { Permissions } from "@/shared/types/permissions" import { logAudit } from "@/shared/lib/audit-logger" import { UpsertAcademicYearSchema, UpsertDepartmentSchema, UpsertGradeSchema, UpsertSchoolSchema } from "./schema" export async function createDepartmentAction( prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertDepartmentSchema.parse({ name: formData.get("name"), description: formData.get("description"), }) await db.insert(departments).values({ id: createId(), name: parsed.name, description: parsed.description ?? null, }) revalidatePath("/admin/school/departments") return { success: true, message: "Department created" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to create department" } } } export async function updateDepartmentAction( departmentId: string, prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertDepartmentSchema.parse({ name: formData.get("name"), description: formData.get("description"), }) await db .update(departments) .set({ name: parsed.name, description: parsed.description ?? null, }) .where(eq(departments.id, departmentId)) revalidatePath("/admin/school/departments") return { success: true, message: "Department updated" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to update department" } } } export async function deleteDepartmentAction(departmentId: string): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) await db.delete(departments).where(eq(departments.id, departmentId)) revalidatePath("/admin/school/departments") return { success: true, message: "Department deleted" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to delete department" } } } export async function createAcademicYearAction( prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertAcademicYearSchema.parse({ name: formData.get("name"), startDate: formData.get("startDate"), endDate: formData.get("endDate"), isActive: formData.get("isActive") ?? "false", }) await db.transaction(async (tx) => { if (parsed.isActive) { await tx.update(academicYears).set({ isActive: false }) } await tx.insert(academicYears).values({ id: createId(), name: parsed.name, startDate: new Date(parsed.startDate), endDate: new Date(parsed.endDate), isActive: parsed.isActive, }) }) revalidatePath("/admin/school/academic-year") return { success: true, message: "Academic year created" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to create academic year" } } } export async function updateAcademicYearAction( academicYearId: string, prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertAcademicYearSchema.parse({ name: formData.get("name"), startDate: formData.get("startDate"), endDate: formData.get("endDate"), isActive: formData.get("isActive") ?? "false", }) await db.transaction(async (tx) => { if (parsed.isActive) { await tx.update(academicYears).set({ isActive: false }) } await tx .update(academicYears) .set({ name: parsed.name, startDate: new Date(parsed.startDate), endDate: new Date(parsed.endDate), isActive: parsed.isActive, }) .where(eq(academicYears.id, academicYearId)) }) revalidatePath("/admin/school/academic-year") return { success: true, message: "Academic year updated" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to update academic year" } } } export async function deleteAcademicYearAction(academicYearId: string): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) await db.delete(academicYears).where(eq(academicYears.id, academicYearId)) revalidatePath("/admin/school/academic-year") return { success: true, message: "Academic year deleted" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to delete academic year" } } } export async function createSchoolAction( prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertSchoolSchema.parse({ name: formData.get("name"), code: formData.get("code"), }) await db.insert(schools).values({ id: createId(), name: parsed.name, code: parsed.code?.trim() ? parsed.code.trim() : null, }) await logAudit({ action: "school.create", module: "school", targetType: "school", detail: { name: parsed.name } }) revalidatePath("/admin/school/schools") return { success: true, message: "School created" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to create school" } } } export async function updateSchoolAction( schoolId: string, prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) const parsed = UpsertSchoolSchema.parse({ name: formData.get("name"), code: formData.get("code"), }) await db .update(schools) .set({ name: parsed.name, code: parsed.code?.trim() ? parsed.code.trim() : null, }) .where(eq(schools.id, schoolId)) await logAudit({ action: "school.update", module: "school", targetId: schoolId, targetType: "school", detail: { name: parsed.name } }) revalidatePath("/admin/school/schools") return { success: true, message: "School updated" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to update school" } } } export async function deleteSchoolAction(schoolId: string): Promise> { try { await requirePermission(Permissions.SCHOOL_MANAGE) await db.delete(schools).where(eq(schools.id, schoolId)) await logAudit({ action: "school.delete", module: "school", targetId: schoolId, targetType: "school" }) revalidatePath("/admin/school/schools") revalidatePath("/admin/school/grades") return { success: true, message: "School deleted" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to delete school" } } } export async function createGradeAction( prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.GRADE_MANAGE) const parsed = UpsertGradeSchema.parse({ schoolId: formData.get("schoolId"), name: formData.get("name"), order: formData.get("order"), gradeHeadId: formData.get("gradeHeadId"), teachingHeadId: formData.get("teachingHeadId"), }) await db.insert(grades).values({ id: createId(), schoolId: parsed.schoolId, name: parsed.name, order: parsed.order, gradeHeadId: parsed.gradeHeadId, teachingHeadId: parsed.teachingHeadId, }) revalidatePath("/admin/school/grades") return { success: true, message: "Grade created" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to create grade" } } } export async function updateGradeAction( gradeId: string, prevState: ActionState | undefined, formData: FormData ): Promise> { try { await requirePermission(Permissions.GRADE_MANAGE) const parsed = UpsertGradeSchema.parse({ schoolId: formData.get("schoolId"), name: formData.get("name"), order: formData.get("order"), gradeHeadId: formData.get("gradeHeadId"), teachingHeadId: formData.get("teachingHeadId"), }) await db .update(grades) .set({ schoolId: parsed.schoolId, name: parsed.name, order: parsed.order, gradeHeadId: parsed.gradeHeadId, teachingHeadId: parsed.teachingHeadId, }) .where(eq(grades.id, gradeId)) revalidatePath("/admin/school/grades") return { success: true, message: "Grade updated" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to update grade" } } } export async function deleteGradeAction(gradeId: string): Promise> { try { await requirePermission(Permissions.GRADE_MANAGE) await db.delete(grades).where(eq(grades.id, gradeId)) revalidatePath("/admin/school/grades") return { success: true, message: "Grade deleted" } } catch (error) { if (error instanceof PermissionDeniedError) return { success: false, message: error.message } if (error instanceof Error) return { success: false, message: error.message } return { success: false, message: "Failed to delete grade" } } }