Skip to content

Server Actions ​

Almost all database operations are implemented as Next.js Server Actions in src/app/actions/, each file beginning with "use server";. Every action verifies the session and role before doing any work, and most mutations return a { success: boolean; message: string } object.

Read vs. write

Read helpers (e.g. getMasterlist, getAdminDashboardStats) also live here and enforce authorization the same way; they return data instead of a { success, message } result.

attendance.ts ​

ActionAuthPurpose
updateAttendance(studentId, subjectId, newStatus, oldStatus?, customDate?)Any non-studentManual toggle. Enforces the time-lock for non-admins; upserts attendance + writes AttendanceAudit.
scanQrAttendance(qrToken, subjectId)TEACHERThe QR scan path. Validates student → subject ownership → enrollment → not-already-present, then marks PRESENT. See QR Attendance Flow.

masterlist.ts ​

Reads: getMasterlist, getSectionMasterlist, getSubjectMasterlist, getAttendanceRange (export; teachers limited to their own subjects).

Writes (all ADMIN unless noted):

ActionPurpose
addStudent / updateStudent / removeStudentStudent CRUD (creates/deletes the linked User).
addSection / updateSection / removeSectionSection CRUD (blocks delete if students remain).
addSubject / updateSubject / removeSubjectSubject CRUD (blocks delete if enrollments/attendance exist).
enrollStudentInSubject / unenrollStudentFromSubject / updateStudentEnrollmentsManage enrollments.
adminUpdateAttendance / deleteAttendanceAdmin attendance edits (bypass time-lock; optional exact time).
resetStudentPasswordToTempSet a temporary student password.
regenerateQrTokenIssue a new QR token (revocation).
importMasterlist(parsed)Apply a parsed CSV masterlist. See CSV Import.

admin.ts ​

All ADMIN (via a requireAdmin() helper):

ActionPurpose
getAdminDashboardStatsTotals, today's attendance rate, pending appeals, recent activity.
getSystemSettings / updateSystemSettingRead/update settings (creates attendance_lock_hours default on first read).
getStaff / addStaff / removeStaffStaff management (guards: no self-removal, no removing last admin).
resetStaffPasswordToTempSet a temporary staff password.
exportAllDataBuild the JSON backup (excludes passwords).
resetAllDataDestructive reset preserving admins + settings.

appeals.ts ​

ActionAuthPurpose
submitAppeal(studentId, description)STUDENTCreate a PENDING appeal.
getTeacherAppeals()TEACHERAppeals from students enrolled in the teacher's subjects.
reviewAppeal(appealId, status)TEACHER/ADMINApprove/reject; approval marks the student PRESENT today.

password.ts ​

ActionPurpose
changeOwnPasswordSelf-service change (verifies current password; min length enforced).
requestPasswordResetIssue a reset token (VerificationToken, 30-min, single-use).
consumePasswordResetValidate the token and set the new password.

Standard mutation shape ​

ts
"use server";
export async function doSomething(/* args */) {
  const session = await getServerSession(authOptions);
  if (!session || (session.user as any).role !== UserRole.ADMIN) {
    throw new Error("Unauthorized");            // or return { success:false, ... }
  }

  // ...business-rule checks...

  const result = await prisma.$transaction(async (tx) => {
    // writes (+ audit rows where relevant)
  });

  await logActivity("SOME_TYPE", "human-readable description", { /* metadata */ });
  revalidatePath("/affected/route");
  return { success: true, message: "Done." };
}

See Conventions & Utilities for the rules behind this pattern.

Documentation for the Secure QR Attendance System.