Reference
API Reference
All business logic in AEGIS is implemented as Next.js Server Actions inside src/lib/actions.ts. These functions execute exclusively on the server, keeping all MongoDB logic and credentials out of the client bundle. Parameters are validated with Zod schemas before any database operation.
Authentication
authenticate(prevState, formData)
Validates admin credentials against the admins collection. On success, sets two HttpOnly cookies: auth=true and admin_user (containing username and role as JSON). Also writes an Admin Logged In audit log entry. Redirects to /dashboard on success.
| Parameter | Type | Description |
|---|---|---|
prevState | any | Previous form state (Next.js useFormState pattern) |
formData | FormData | Must contain username and password fields |
Returns: {"{"}message: string{"}"} on failure | Redirects on success
logout()
Reads the current admin_user cookie, writes an Admin Logged Out audit log entry, then deletes both auth and admin_user cookies. Redirects to /login.
Workstation (PC) Management
registerPc(prevState, formData)
Creates a PC registration request. Validates that pcName is at least 3 characters. Generates a unique 12-character random identifier (pc-id-xxxxxxxxxxxx) using a custom alphanumeric RNG and inserts a pending document into the pc_requests collection.
Returns: {"{"}message: string, status: 'success'|'error', identifier?: string{"}"}
getPcStatus(identifier: string)
The heartbeat check for client PCs. Performs a MongoDB aggregation pipeline with two $lookup stages: first joining the assigned student, then joining the student's assigned exam. Updates lastSeen timestamp on every call. Returns the full nested PC context (PC → Student → Exam) for client-side routing decisions.
Returns: {"{"}status: string | null, pcDetails: PC & {"{"}student: Student, exam: Exam{"}"} | null{"}"}
updatePcLiveStatus(identifier, status)
Atomically updates a PC's liveStatus field. Called by the exam page's heartbeat interval every 15 seconds and on lifecycle events (exam start, exam submit). Status values: 'Online' | 'Ready' | 'Waiting' | 'Attempting' | 'Finished'.
Student Management
bulkUploadStudents(csvData: string)
Processes a raw CSV string with a custom state-machine parser that handles RFC 4180 quoted fields containing commas. Expected columns: Name, Roll Number, Class/Batch, [Exam ID or Title].
Performs multi-layer validation: (1) field presence check, (2) in-memory duplicate roll number scan within the upload batch, (3) DB lookup for pre-existing roll numbers, (4) exam ID/title resolution with case-insensitive matching. Only inserts if all rows pass.
Returns: {"{"}success: boolean, successCount: number, errorCount: number, results: RowResult[]{"}"}
deleteStudent(studentId: string)
Performs a cascading delete. Before removing the student document, it calls pcsCollection.updateMany to null out assignedStudentId, assignedStudentName, and assignedStudentRollNumber on all PCs that referenced this student. This prevents dangling references that would break the admin dashboard's aggregation queries.
Question Bank
bulkUploadQuestions(csvData: string)
Accepts a 10-column CSV. Parses and validates each row independently, collecting results without failing the entire batch on a single error. Expected schema:
Correct Options: 0-based comma-separated indices (e.g.,0,2for multi-correct)Category: Case-sensitive — must be exactlyEasy,Medium, orHardTags: Semicolon-delimited (e.g.,Math;Algebra)Negative Marking:true/falseor1/0
Examination Engine
getExamDetails(examId, studentId, pcIdentifier?)
The primary security gate. Executes the following validation chain in order — any failure returns an error without revealing why:
- Verify
pcIdentifierexists in thepcscollection andstatus === 'Approved' - Verify the PC's
assignedStudentIdmatches the providedstudentId - Verify the student's
assignedExamIdmatches the providedexamId - Verify the exam's
status === 'In Progress' - Check the
exam_resultscollection — if a result exists for this student+exam, returnalreadyTaken: true
Returns: {"{"}exam: Exam, questions: Question[], alreadyTaken: boolean, error?: string{"}"}
submitExam(examId, studentId, answers, pcIdentifier?)
Re-validates the full security chain from getExamDetails. Then applies answer sanitization: filters the submitted answers array to include only entries whose questionId belongs to the exam's own questionIds list. This neutralizes injection attacks where a student submits answers for questions outside their exam.
Calculates the score by iterating validated answers against the question's correctOptions and weight fields. Inserts the result into exam_results, then sets only the submitting PC's liveStatus to Finished to prevent side-effects on other machines sharing the exam.
Returns: {"{"}success: boolean, error?: string{"}"}
Audit & Results
getAdminLogs()Returns all entries from admin_logs sorted by timestamp descending. Every admin action (login, CRUD operations, exam control) writes to this collection via the internal logAdminAction(action, details) helper, which reads the admin_user cookie to attribute the identity.