# Database Control Matrix (`datacontrol.md`) This document maps all available backend controllers to the SQLite database tables they interact with, detailing the operations performed (reads, writes, updates, soft-deletes) and the transaction patterns they use. --- ## Design Principles & Patterns * **Write Operations (`INSERT` / `UPDATE`)**: Under nextgen server conventions, all direct write operations set `sync_status = 'pending'`, generate a new UUIDv4 `uid` on creation, and stamp the local timestamp `updated_at`. * **Soft Deletes**: Deletion operations do not drop DB table records. Instead, they run an `UPDATE` command setting `is_deleted = 1` (and often set `is_active = 0` or similar lifecycle flags when relevant). * **Transactional Integrity**: Multi-step operations (e.g. bulk CSV marks upload in `marks.controller.js`, bulk attendance marks, or invoice calculations) use explicit database transactions (via `better-sqlite3`'s `db.transaction(...)`) to guarantee all-or-nothing execution. * **Read Scoping**: Read operations are filtered globally on `is_deleted = 0` and scoped appropriately (e.g., student/parent portals only view records matched to their specific user or linked dependent IDs). * **Grading Scale Resolutions**: Complex entities like `grades.controller.js` and `exams.controller.js` dynamically resolve percentages against a cascading grading-scale chain (specific row scale override -> default school configuration scale -> ZIMSEC standard fallback bands). --- ## Controllers & Database Interactions ### 1. [academic-rollover.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/academic-rollover.controller.js) * **`academic_years`**: * `SELECT` (retrieve status, lists) * `INSERT` (create new year: `uid`, `name`, `status = 'draft'`, `start_date`, `end_date`) * `UPDATE` (change status to `'active'`, `'completed'`; soft-delete with `is_deleted = 1`) * **`classes`**: * `SELECT` (fetch classes to rollover) * `INSERT` (clone/rollover classes into new academic year) * **`subjects`**: * `SELECT` (fetch subjects to rollover) * `INSERT` (clone/rollover subjects into new academic year) * **`enrollments`**: * `SELECT` (active enrollment state checks) * `INSERT` (auto-promote students to new classes in the rolling year) * **`users`**: * `SELECT` (link student roles) ### 2. [assignments.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/assignments.controller.js) * **`assignments`**: * `SELECT` (list active assignments with class/subject boundaries) * `INSERT` (create assignment: `uid`, `title`, `description`, `subject_id`, `due_date`, `max_score`, `created_by`) * `UPDATE` (edit fields; soft-delete with `is_deleted = 1`) * **`submissions`**: * `SELECT` (check user submissions history) * `INSERT` (create draft/initial submission: `uid`, `assignment_id`, `student_id`, `status = 'submitted'`, `submitted_at`) * `UPDATE` (grade submission: `grade`, `feedback`, `graded_by`, `graded_at`, `status = 'graded'`; soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (joining names for graders/students) * **`enrollments`**: * `SELECT` (verify active student status in target class) ### 3. [attendance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/attendance.controller.js) * **`attendance_new`**: * `SELECT` (retrieve rosters, historical summaries) * `INSERT` (bulk insert roll-call records: `uid`, `student_id`, `class_id`, `date`, `status`, `remarks`, `marked_by`) * `UPDATE` (modify status, remarks, marked_by, or soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (verify students name) * **`enrollments`**: * `SELECT` (active student list for class roster) * **`classes`**: * `SELECT` (validate target class) * **`parent_students`**: * `SELECT` (scoped lookup for parent portal self-read) ### 4. [audit.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/audit.controller.js) * **`audit_logs`**: * `SELECT` (list recent events filtered by email, action, date) * `INSERT` (log technical actions/events: `uid`, `user_id`, `user_email`, `action`, `entity_type`, `entity_id`, `old_data`, `new_data`, `ip_address`, `user_agent`) * **`users`**: * `SELECT` (look up user emails) ### 5. [calendar.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/calendar.controller.js) * **`events`**: * `SELECT` (list active events filterable by category, date range) * `INSERT` (create calendar event: `uid`, `title`, `description`, `start_time`, `end_time`, `category`, `is_all_day`, `location`, `created_by`) * `UPDATE` (modify properties; soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (join creator profile) ### 6. [classes.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/classes.controller.js) * **`classes`**: * `SELECT` (list active classes with counts) * `INSERT` (create class: `uid`, `name`, `section`, `grade_level`, `room_number`, `class_teacher_id`) * `UPDATE` (modify properties; soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (join teacher names) * **`enrollments`**: * `SELECT` (calculate active student roll counts) ### 7. [club-attendance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/club-attendance.controller.js) * **`club_attendance`**: * `SELECT` (list roll-call entries) * `INSERT` (bulk insert club logs: `uid`, `club_id`, `student_id`, `date`, `status`, `remarks`, `marked_by`) * `UPDATE` (modify attendance details; soft-delete with `is_deleted = 1`) * **`clubs`**: * `SELECT` (verify active status) * **`users`**: * `SELECT` (verify students) ### 8. [clubs.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/clubs.controller.js) * **`clubs`**: * `SELECT` (active clubs catalog list) * `INSERT` (create club: `uid`, `name`, `type`, `description`, `teacher_in_charge_id`, `schedule`, `max_members`) * `UPDATE` (modify properties, status; soft-delete with `is_deleted = 1`) * **`club_memberships`**: * `SELECT` (check active student enrollments) * `INSERT` (join a club: `uid`, `club_id`, `student_id`, `status = 'active'`, `join_date = CURRENT_DATE`) * `UPDATE` (re-enroll/join; leave a club: set `status = 'inactive'`) * **`club_announcements`**: * `SELECT` (list recent club notices) * `INSERT` (post notice: `uid`, `club_id`, `title`, `content`, `created_by`) * **`club_attendance`**: * `SELECT` (active roll-call records) * `INSERT` / `UPDATE` (bulk upsert marks matching `(club_id, student_id, date)`) * **`club_chats`**: * `SELECT` (list messages) * `INSERT` (post message: `uid`, `club_id`, `sender_id`, `message`, `image_url`) * **`users`**: * `SELECT` (joining names for dashboard/contacts) ### 9. [courseGrades.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/courseGrades.controller.js) * **`course_grades`**: * `SELECT` (list student performance scores) * `INSERT` (record grade: `uid`, `student_id`, `course_id`, `grade_letter`, `grade_points`, `percentage`, `remarks`, `graded_by`) * `UPDATE` (modify grade letter, percentage, remarks, graded_by; soft-delete with `is_deleted = 1`) * **`course_enrolments`**: * `SELECT` (verify active status in courses) * **`courses`**: * `SELECT` (verify existence) * **`users`**: * `SELECT` (verify roles) ### 10. [course_enrolments.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/course_enrolments.controller.js) * **`course_enrolments`**: * `SELECT` (active, pending, and filterable enrolment requests lists) * `INSERT` (create enrolment: `uid`, `student_id`, `course_id`, `status`, `request_status`, `requested_at`, `approved_by`, `approved_at`, `progress = 0`, `sync_status = 'pending'`) * `UPDATE` (modify `request_status` to `'approved'`, `'rejected'`, or `'withdrawn'`; modify `status` to `'active'` or `'dropped'`; modify `approved_by`, `approved_at`, `rejection_reason`, `updated_at`, `sync_status = 'pending'`, soft-delete `is_deleted = 1`) * **`courses`**: * `SELECT` (existence checks) * **`users`**: * `SELECT` (joining student profiles) ### 11. [courses.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/courses.controller.js) * **`subjects`**: (Note: The routes query/modify `subjects` table name, not a `courses` table name directly, although the controller is called `courses.controller.js`). * `SELECT` (catalog list with filters) * `INSERT` (create course: `uid`, `name`, `code`, `class_id`, `teacher_id`, `description`, `credit_hours`) * `UPDATE` (modify attributes, or soft-delete with `is_deleted = 1`) * **`classes`**: * `SELECT` (class details) * **`users`**: * `SELECT` (teacher and student directories) * **`enrollments`**: * `SELECT` (verify class list) * **`grades`**: * `SELECT` (calculate percentage average and recent history list) ### 12. [crossword.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/crossword.controller.js) * **`crossword_games`**: * `SELECT` (active games lists with role/status filters, metadata detail fetch) * `INSERT` (create game layout details: `uid`, `title`, `description`, `subject_id`, `class_id`, `created_by`, `status = 'ready'`, `grid_layout` JSON, `word_count`, `difficulty`, `reward_points`, `time_limit_seconds`, `is_published = 0`, `sync_status = 'pending'`, `created_at`, `updated_at`) * `UPDATE` (modify game attributes: `title`, `description`, `reward_points`, `time_limit_seconds`, `is_published`, `updated_at`, soft-delete with `is_deleted = 1`) * **`crossword_clues`**: * `SELECT` (clues details for active games) * `INSERT` (create clues per placement: `uid`, `game_id`, `clue_text`, `answer`, `direction`, `start_row`, `start_col`, `clue_number`, `hint`, `sync_status = 'pending'`, `created_at`, `updated_at`) * `UPDATE` (soft-delete with `is_deleted = 1`) * **`crossword_sessions`**: * `SELECT` (active/completed history matching student user, leaderboard statistics) * `INSERT` (start new session: `uid`, `game_id`, `student_id`, `current_state = '{}'`, `correct_count = 0`, `total_count`, `points_earned = 0`, `sync_status = 'pending'`, `created_at`, `updated_at`) * `UPDATE` (save debounced state `current_state`; submit completion updates: `correct_count`, `total_count`, `points_earned`, `time_taken_seconds`, `completed_at = CURRENT_TIMESTAMP`, `updated_at = CURRENT_TIMESTAMP`, `sync_status = 'pending'`) * **`users`**: * `SELECT` (joining student profiles for dashboard ranking leaderboard counts) ### 13. [dashboard.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/dashboard.controller.js) *(Note: Completely READ-ONLY SELECT operations)* * **`enrollments`**, **`attendance`** / **`attendance_new`**, **`grades`**, **`subjects_new`** / **`subjects`**, **`classes`**, **`users`**, **`payments`**, **`student_fees`**, **`audit_logs`**, **`courses`**, **`course_enrolments`**, **`course_grades`**, **`submissions`**, **`assignments`**, **`crossword_sessions`**, **`parent_students`**, **`messages`**, **`events`**: * `SELECT` (aggregate dashboard stats, unread announcements, schedule items) ### 14. [departments.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/departments.controller.js) * **`departments`**: * `SELECT` (flat lists and tree detail views) * `INSERT` (create department: `uid`, `name`, `code`, `head_teacher_id`, `description`) * `UPDATE` (modify attributes, or soft-delete with `is_deleted = 1` if no active subjects link) * **`subjects_new`**: * `SELECT` (active subject counts checks) * **`staff_records`**: * `SELECT` (fetch head teachers), `UPDATE` (modify `department` name reference if changed) * **`users`**: * `SELECT` (teacher links), `UPDATE` (modify `department_id` assignment) * **`enrollments`**: * `SELECT` (count active students) ### 15. [edutainment.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/edutainment.controller.js) * **`edutainment_content`**: * `SELECT` (scramble and trivia pool lists) * `INSERT` (create catalog content: `uid`, `game_type`, `subject_id`, `created_by`, `question_text`, `hint_text`, `options` JSON, `correct_answer`) * `UPDATE` (soft-delete with `is_deleted = 1`) * **`edutainment_games`**: * `SELECT` (list custom puzzles) * `INSERT` (create custom game template: `uid`, `game_type`, `title`, `description`, `subject_id`, `created_by`, `difficulty`, `reward_points`, `time_limit_seconds`, `game_config` JSON, `is_published = 1`) * `UPDATE` (soft-delete with `is_deleted = 1`) * **`edutainment_sessions`**: * `SELECT` (attempt count summaries) * `INSERT` (record student game attempt session: `uid`, `game_id`, `student_id`, `score`, `completed_at = CURRENT_TIMESTAMP`, `points_earned`) * **`subjects_new`**: * `SELECT` (joining subject names) * **`users`**: * `SELECT` (joining teacher names) ### 16. [enrollments.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/enrollments.controller.js) * **`enrollments`**: * `SELECT` (enrolment request lists, active/pending profiles) * `INSERT` (create request: `uid`, `student_id`, `class_id`, `roll_number`, `academic_year`, `section`, `status`, `request_status`, `requested_at`, `approved_by`, `approved_at`, `sync_status = 'pending'`) * `UPDATE` (approve request: status `'active'`, request_status `'approved'`; reject request: status `'inactive'`, request_status `'rejected'`, `rejection_reason`; withdraw request: status `'inactive'`, request_status `'withdrawn'`; soft-delete with `is_deleted = 1` and status `'inactive'`) * **`classes`**: * `SELECT` (checking class properties and sections) * **`users`**: * `SELECT` (verifying active student roles) ### 17. [exams.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/exams.controller.js) * **`exam_groups`**: * `SELECT` (list templates) * `INSERT` (create exam group: `uid`, `name`, `description`, `exam_type`, `duration_minutes`, `total_marks`, `passing_marks`, `is_random_order`, `show_results`, `allow_review`, `max_attempts`, `academic_year`, `term`, `grading_scale`) * `UPDATE` (modify mutable fields, grading_scale; soft-delete with `is_deleted = 1`) * **`question_banks`**: * `SELECT` (questions with difficulty lists) * `INSERT` (single and bulk insert: `uid`, `exam_group_id`, `subject_id`, `question_type`, `question`, `options`, `correct_answer`, `marks`, `difficulty`, `tags`) * `UPDATE` (modify question attributes; soft-delete with `is_deleted = 1`) * **`exam_schedules`**: * `SELECT` (scheduled exams index) * `INSERT` (create schedule: `uid`, `exam_group_id`, `class_id`, `subject_id`, `start_time`, `end_time`, `duration_minutes`, `instructions`) * **`exam_attempts`**: * `SELECT` (attempt counts and performance averages) * `INSERT` (start new attempt: `uid`, `student_id`, `exam_group_id`, `schedule_id`, `started_at`) * `UPDATE` (submit attempt: `submitted_at`, `time_spent_seconds`, `total_marks`, `obtained_marks`, `percentage`, `status = 'submitted'`, `ip_address`, `user_agent`) * **`exam_answers`**: * `SELECT` (fetch student answers) * `INSERT` / `UPDATE` (upsert answer: `answer`, `answered_at` / write grade results: `is_correct`, `marks_obtained`) * **`enrollments`**, **`subjects`**, **`classes`**, **`users`**: * `SELECT` (verify relationship linkages) ### 18. [fees.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/fees.controller.js) * **`fee_groups`**: * `SELECT` (list definitions) * `INSERT` (create fee type: `uid`, `name`, `description`, `amount`, `type`, `frequency`, `academic_year`, `due_date`) * `UPDATE` (modify attributes; soft-delete with `is_deleted = 1`) * **`student_fees`**: * `SELECT` (student ledger profiles list) * `INSERT` (assign fee type: `uid`, `student_id`, `fee_group_id`, `amount`, `due_date`) * **`fee_plans`**: * `SELECT` (list schedules) * `INSERT` (create plan: `uid`, `name`, `fee_group_id`, `total_amount`, `installments_count`, `start_date`, `end_date`, `academic_year`, `auto_apply_to_class_id`, `notes`, `created_by`) * `UPDATE` (modify mutable fields; soft-delete with `is_deleted = 1`) * **`fee_plan_installments`**: * `SELECT` (fetch split amounts) * `INSERT` (create installment rows: `uid`, `fee_plan_id`, `sequence`, `label`, `amount`, `due_date`) * `UPDATE` (soft-delete with `is_deleted = 1` on plan delete/reset) * **`discounts`**: * `SELECT` (list discounts) * `INSERT` (create discount rate: `uid`, `name`, `kind`, `value`, `scope`, `scope_id`, `reason`, `valid_from`, `valid_to`, `academic_year`, `created_by`) * `UPDATE` (modify details; soft-delete with `is_deleted = 1`) * **`student_fee_discounts`**: * `UPDATE` (soft-delete with `is_deleted = 1` on discount delete) * **`users`**, **`enrollments`**, **`classes`**: * `SELECT` (validate student scopes) ### 19. [finance-banking.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-banking.controller.js) * **`bank_accounts`**: * `SELECT` (list cash/assets balances) * `INSERT` (create account: `uid`, `name`, `bank_name`, `account_number`, `account_type`, `currency`, `opening_balance`, `current_balance`, `chart_account_id`, `is_active`) * `UPDATE` (modify account settings; soft-delete with `is_deleted = 1`, `is_active = 0`) * **`bank_reconciliations`**: * `SELECT` (list bank recon history) * `INSERT` (create draft recon: `uid`, `bank_account_id`, `period_start`, `period_end`, `statement_balance`, `status = 'draft'`, `created_by`) * `UPDATE` (modify status: `'balanced'` or `'discrepancy'`, setting `book_balance`) * **`bank_reconciliation_lines`**: * `SELECT` (fetch lines list) * `INSERT` (auto-match statement lines: `uid`, `reconciliation_id`, `payment_id`, `statement_date`, `statement_amount`, `statement_reference`, `match_status`) * `UPDATE` (resolve line match: update `match_status` and `payment_id`) * **`chart_of_accounts`**, **`payments`**: * `SELECT` (verify transaction linkages) ### 20. [finance-coa.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-coa.controller.js) * **`chart_of_accounts`**: * `SELECT` (ledger codes flat lists and tree hierarchies) * `INSERT` (create account: `uid`, `code`, `name`, `type`, `parent_id`, `color`, `is_active`) * `UPDATE` (modify codes attributes; soft-delete with `is_deleted = 1`, `is_active = 0`) * **`bank_accounts`**: * `SELECT` (constraint validation checks) ### 21. [finance-engine.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-engine.controller.js) * **`student_groups`**: * `SELECT` (groups search and detail metrics) * `INSERT` (create student cohort: `uid`, `name`, `description`, `type`, `color`, `class_id`, `capacity`, `auto_track_class`, `created_by`) * `UPDATE` (modify properties; soft-delete with `is_deleted = 1`) * **`student_group_members`**: * `SELECT` (member details and student count calculations) * `INSERT` (add member mapping: `uid`, `group_id`, `student_id`) * `UPDATE` (soft-delete with `is_deleted = 1`) * **`student_fees`**: * `SELECT` (check applied plans) * `INSERT` (apply plan installment: `uid`, `student_id`, `fee_group_id`, `plan_id`, `amount`, `due_date`, `status = 'pending'`, `sync_status = 'pending'`) * `UPDATE` (re-aggregate discount_amount; soft-delete with `is_deleted = 1` and `sync_status = 'pending'` when revoking unpaid plans) * **`student_fee_discounts`**: * `SELECT` (applied discount lines checks) * `INSERT` (apply discount: `uid`, `student_fee_id`, `discount_id`, `amount_applied`, `applied_by`) * `UPDATE` (modify amount_applied, or soft-delete with `is_deleted = 1`) * **`classes`**, **`users`**, **`enrollments`**, **`fee_plans`**, **`fee_plan_installments`**, **`discounts`**, **`fee_groups`**: * `SELECT` (scope verification checks) ### 22. [finance-invoices.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-invoices.controller.js) * **`invoices`**: * `SELECT` (invoice search pages index) * `INSERT` (create invoice: `uid`, `invoice_number`, `student_id`, `fee_group_id`, `plan_id`, `period_label`, `subtotal`, `discount_amount`, `total`, `paid_amount = 0`, `currency`, `status = 'issued'`, `issued_at`, `due_date`, `notes`, `created_by`) * `UPDATE` (modify status, notes, subtotal; soft-delete with `is_deleted = 1` and status `'cancelled'`) * **`users`**, **`fee_groups`**, **`student_fees`**, **`fee_plans`**: * `SELECT` (verify billing components) ### 23. [finance-suppliers.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-suppliers.controller.js) * **`suppliers`**: * `SELECT` (supplier details search catalog list) * `INSERT` (create supplier: `uid`, `name`, `code`, `contact_person`, `email`, `phone`, `address`, `city`, `country`, `tax_id`, `bank_details`, `notes`, `is_active`, `sync_status = 'pending'`) * `UPDATE` (modify supplier details; soft-delete with `is_deleted = 1`, `is_active = 0`) ### 24. [finance-trips.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance-trips.controller.js) * **`trips`**: * `SELECT` (bookings catalog) * `INSERT` (create field trip: `uid`, `name`, `destination`, `departure_date`, `return_date`, `cost_per_student`, `total_capacity`, `status = 'draft'`, `description`, `created_by`) * `UPDATE` (modify trip details; soft-delete with `is_deleted = 1`, `status = 'cancelled'`) * **`trip_payments`**: * `SELECT` (passenger booking accounts checks) * `INSERT` (assign student passenger: `uid`, `trip_id`, `student_id`, `invoiced_amount`, `status = 'pending'`, `created_by`) * `UPDATE` (pay/refund: `paid_amount`, `status`, `paid_at`, `updated_at`; soft-delete with `is_deleted = 1` and `status = 'cancelled'`) * **`users`**, **`enrollments`**: * `SELECT` (look up student eligibility) ### 25. [finance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/finance.controller.js) *(Note: Proxies payroll routes to `hr.controller.js`)* * **`payments`**: * `SELECT` (sum payment amounts this month) * **`student_fees`**: * `SELECT` (sum outstanding amount: `amount - paid_amount`) * **`payroll_runs`**: * `SELECT` (details of latest run) * **`expenses`**: * `SELECT` (list with filters/pagination) * `INSERT` (create expense: `uid`, `category`, `subcategory`, `description`, `amount`, `expense_date`, `vendor`, `invoice_number`, `payment_method`, `status`, `receipt_image`, `created_by`) * `UPDATE` (modify fields, change status to `'approved'`/`'rejected'`, or soft-delete with `is_deleted = 1`) * **`invoices`**, **`trips`**, **`bank_reconciliations`**, **`student_groups`**: * `SELECT` (additional tile aggregations) ### 26. [front-office.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/front-office.controller.js) * **`visitor_logs`**: * `SELECT` (visitor log registry) * `INSERT` (log visitor check-in: `uid`, `visitor_name`, `visitor_type`, `phone`, `email`, `id_number`, `purpose`, `person_to_visit`, `badge_number`, `remarks`, `created_by`) * `UPDATE` (check out: set `check_out` time; soft-delete with `is_deleted = 1`) * **`admission_enquiries`**: * `SELECT` (enquiry follow-up checklist) * `INSERT` (create enquiry: `uid`, `full_name`, `email`, `phone`, `address`, `class_interested`, `source`, `follow_up_date`, `notes`, `next_action`, `assigned_to`) * `UPDATE` (modify enquiry details; soft-delete with `is_deleted = 1`) * **`complaints`**: * `SELECT` (complaint tracking files) * `INSERT` (file complaint: `uid`, `complainant_name`, `complainant_type`, `contact_phone`, `contact_email`, `category`, `priority`, `subject`, `description`, `assigned_to`, `status = 'open'`) * `UPDATE` (resolve complaint: set `status = 'resolved'`, `resolution`, `resolved_by`, `resolved_at`) * **`phone_call_logs`**: * `SELECT` (phone checklists logs) * `INSERT` (single / bulk record phone logs: `uid`, `caller_name`, `caller_phone`, `caller_type`, `direction`, `call_time`, `duration_seconds`, `purpose`, `response`, `follow_up_required`, `follow_up_date`, `handled_by`, `notes`) * `UPDATE` (modify details; clear follow-up: set `follow_up_required = 0`; soft-delete with `is_deleted = 1`) * **`postal_dispatch`**: * `SELECT` (mailroom delivery registries) * `INSERT` (single / bulk log mail items: `uid`, `type`, `reference_number`, `sender`, `receiver`, `address`, `courier`, `tracking_number`, `dispatch_date`, `description`, `status = 'pending'`, `created_by`) * `UPDATE` (modify details; mark sent: set `status = 'sent'`; mark delivered: set `status = 'delivered'`, `received_date`; soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (consultant names check) ### 27. [grades.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/grades.controller.js) * **`grades`**: * `SELECT` (list results with filters, calculate average summaries) * `INSERT` (single and bulk: `uid`, `student_id`, `subject_id`, `exam_type`, `marks`, `total_marks`, `grade`, `grading_scale`, `remarks`, `graded_by`, `academic_year`, `term`) * `UPDATE` (modify marks, grade letter, remarks, grading_scale, graded_by; soft-delete with `is_deleted = 1`) * **`users`**, **`subjects`**, **`classes`**, **`enrollments`**: * `SELECT` (verify relationships) ### 28. [hostel-attendance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/hostel-attendance.controller.js) * **`hostel_attendance`**: * `SELECT` (hostel attendance counts checklist) * `INSERT` (record check-in: `uid`, `hostel_id`, `room_id`, `student_id`, `date`, `status`, `marked_by`) * `UPDATE` (modify status, marked_by, updated_at) * **`hostels`**, **`rooms`**, **`room_assignments`**: * `SELECT` (verify boarding occupancy) * **`users`**, **`parent_students`**: * `SELECT` (verify child boundaries) ### 29. [hostel.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/hostel.controller.js) * **`hostels`**: * `SELECT` (active hostels catalog list) * `INSERT` (create hostel: `uid`, `name`, `code`, `type`, `address`, `warden_id`, `phone`, `description`) * **`rooms`**: * `SELECT` (rooms in hostel catalog) * `INSERT` (create room: `uid`, `hostel_id`, `room_type_id`, `room_number`, `floor`, `bed_count`, `status = 'available'`, `description`) * `UPDATE` (change status to `'available'`/`'occupied'`) * **`room_assignments`**: * `SELECT` (list assignments) * `INSERT` (assign student to bed: `uid`, `student_id`, `room_id`, `bed_number`, `start_date`, `end_date`, `status = 'active'`, `remarks`, `assigned_by`) * `UPDATE` (check out assignment: set `status = 'inactive'`, `end_date = today`) * **`room_types`**: * `SELECT` (list room configurations) * **`hostel_attendance`**: * `SELECT` (attendance logs index) * `INSERT` / `UPDATE` (bulk upsert hostel attendance matching `(hostel_id, student_id, date)`) * **`users`**: * `SELECT` (warden/student validation checks) ### 30. [hr.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/hr.controller.js) * **`staff_roles`**: * `SELECT` (list active roles) * `INSERT` (create role: `uid`, `name`, `description`, `is_teaching_role`, `permissions`) * **`salary_grades`**: * `SELECT` (list pay grades) * `INSERT` (create salary grade: `uid`, `name`, `grade_level`, `basic_salary`, `housing_allowance`, `transport_allowance`, `medical_allowance`, `other_allowances`, `description`, `effective_date`) * **`staff_records`**: * `SELECT` (list employment cards details) * `INSERT` (create record: `uid`, `user_id`, `staff_number`, `role_id`, `salary_grade_id`, `employment_type`, `appointment_date`, `bank_name`, `account_number`, `department`, `designation`) * `UPDATE` (modify role, pay scale, active status; soft-delete with `is_deleted = 1`) * **`leave_types`**: * `SELECT` (list categories) * **`leave_requests`**: * `SELECT` (requests history lists) * `INSERT` (submit request: `uid`, `staff_id`, `leave_type_id`, `start_date`, `end_date`, `days_count`, `reason`) * `UPDATE` (approve/reject: set `status`, `rejection_reason`, `approved_by`, `approved_at`) * **`staff_attendance`**: * `SELECT` (roster index) * `INSERT` (log day check: `uid`, `staff_id`, `date`, `status`, `remarks`, `marked_by`) * **`payroll_runs`**: * `SELECT` (list runs) * `INSERT` (create run: `uid`, `period_month`, `period_year`, `description`, `status = 'draft'`, `created_by`) * `UPDATE` (calculate totals: `total_gross`, `total_deductions`, `total_net`, `status = 'calculated'`; mark paid: set `status = 'paid'`, `paid_at`; cancel run: reset status to `'draft'`, zero out totals) * **`payslips`**: * `SELECT` (list slips) * `INSERT` (generate payslips for run) * `UPDATE` (cascading update to status `'paid'` and `paid_at`) * `DELETE` (recalculating run deletes old slips) * **`vacancies`**: * `SELECT` (list vacancies) * `INSERT` (create job posting: `uid`, `title`, `description`, `requirements`, `department`, `status = 'open'`, `closing_date`) * `UPDATE` (modify details, status; soft-delete with `is_deleted = 1`) * **`applicants`**: * `SELECT` (list candidates) * `INSERT` (add applicant: `uid`, `vacancy_id`, `first_name`, `last_name`, `email`, `phone`, `resume_url`, `status = 'pending'`, `notes`) * `UPDATE` (modify status, interview_date, notes) * **`users`**: * `SELECT` (validate identities) ### 31. [inventory.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/inventory.controller.js) * **`item_categories`**: * `SELECT` (list categories) * `INSERT` (create category: `uid`, `name`, `code`, `description`, `parent_id`) * **`suppliers`**: * `SELECT` (list vendors) * `INSERT` (create vendor: `uid`, `name`, `code`, `contact_person`, `email`, `phone`) * **`store_locations`**: * `SELECT` (list store spaces) * **`items`**: * `SELECT` (list items) * `INSERT` (create item card: `uid`, `name`, `code`, `barcode`, `description`, `category_id`, `unit`, `purchase_price`, `selling_price`, `reorder_level`, `supplier_id`) * **`item_stock`**: * `SELECT` (current inventory balances list) * `INSERT` (create stock row if missing) * `UPDATE` (increment/decrement quantity) * **`stock_transactions`**: * `INSERT` (record ledger transaction: `uid`, `item_id`, `store_id`, `type`, `quantity`, `unit_price`, `total_amount`, `reference_number`, `supplier_id`, `notes`, `created_by`) * **`item_issues`**: * `SELECT` (issued items tracking list) * `INSERT` (issue item: `uid`, `item_id`, `issued_to_type`, `issued_to_id`, `quantity`, `purpose`, `return_due_date`, `notes`, `issued_by`) * `UPDATE` (return items: update `returned_quantity`, `returned_date`, `status = 'returned'|'partially_returned'`, `condition_on_return`) * **`users`**: * `SELECT` (join issuer profile) ### 32. [library.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/library.controller.js) * **`library_books`**: * `SELECT` (catalog lists) * `INSERT` (single and bulk book import: `uid`, `isbn`, `title`, `author`, `category`, `publisher`, `year_published`, `total_copies`, `available_copies`, `shelf_location`) * `UPDATE` (modify book attributes, increase/decrease total/available copies; soft-delete with `is_deleted = 1`) * **`library_issues`**: * `SELECT` (borrow logs history) * `INSERT` (borrow book copy: `uid`, `book_id`, `user_id`, `issue_date`, `due_date`, `status = 'issued'`, `issued_by`) * `UPDATE` (return book: set `return_date`, `status = 'returned'|'lost'`) * **`library_reservations`**: * `SELECT` (booking reserves lists) * `INSERT` (reserve copies: `uid`, `book_id`, `user_id`, `notes`) * `UPDATE` (auto-fulfill when book is issued: set `status = 'fulfilled'`; cancel reservation: set `status = 'cancelled'`) * **`library_fines`**: * `SELECT` (fine accounts details) * `INSERT` (fine citation: `uid`, `issue_id`, `user_id`, `amount`, `reason`, `status = 'unpaid'`) * `UPDATE` (pay/waive: set `status = 'paid'|'waived'`) * **`users`**: * `SELECT` (verify member roles) ### 33. [marks.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/marks.controller.js) * **`assignments`**: * `SELECT` (caching max score scales verification checks) * **`users`**: * `SELECT` (caching student roles checks) * **`submissions`**: * `SELECT` (find existing submission matching student/assignment) * `INSERT` (create submission: `uid`, `assignment_id`, `student_id`, `status = 'graded'`, `grade`, `feedback`, `graded_by`, `graded_at`) * `UPDATE` (grade modification: `grade`, `feedback`, `graded_by`, `graded_at`, `status = 'graded'`) ### 34. [medical.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/medical.controller.js) * **`student_medical_profiles`**: * `SELECT` (retrieve student health profile cards) * `INSERT` (create profile: `uid`, `student_id`, `blood_group`, `allergies`, `dietary_restrictions`, `contraindications`, `chronic_conditions`, `emergency_instructions`, `updated_by`) * `UPDATE` (modify profile settings, emergency contacts; update last modifier `updated_by`) * **`student_medication_logs`**: * `SELECT` (list administrations history) * `INSERT` (record dispensation: `uid`, `student_id`, `medication_name`, `dosage`, `administered_at`, `administered_by`, `reason`, `notes`) * **`student_medical_history`**: * `SELECT` (illness/injury history) * `INSERT` (record diagnostic event: `uid`, `student_id`, `event_type`, `description`, `severity`, `onset_date`, `resolution_date`, `treatment_details`, `doctor_notes`, `is_visible_to_teachers`, `reported_by`) * **`users`**, **`parent_students`**, **`enrollments`**, **`classes`**: * `SELECT` (verify student access scope boundaries) ### 35. [messages.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/messages.controller.js) * **`messages`**: * `SELECT` (inbox/sent directories index, conversations threads) * `INSERT` (send direct/group/announcement message: `uid`, `sender_id`, `recipient_id`, `body`, `subject`, `is_announcement`, `attachment_url`, `attachment_name`, `attachment_type`) * `UPDATE` (mark read: `is_read = 1`; mark delivered: `is_delivered = 1`; soft-delete with `is_deleted = 1`) * **`chat_groups`**: * `SELECT` (conversations lists) * **`chat_group_members`**: * `SELECT` (membership access checks) * **`clubs`**, **`club_chats`**, **`club_memberships`**: * `SELECT` (extracurricular messages thread index) * **`users`**: * `SELECT` (recipient search directories) ### 36. [notices.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/notices.controller.js) * **`notices`**: * `SELECT` (pinboard index, detail fetch with audience filters) * `INSERT` (create notice: `uid`, `title`, `content`, `category`, `priority`, `audience`, `is_pinned`, `created_by`, `expiry_date`) * `UPDATE` (modify notice attributes; soft-delete with `is_deleted = 1`) * **`users`**: * `SELECT` (join creator names) ### 37. [payments.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/payments.controller.js) * **`payments`**: * `SELECT` (lists of invoices paid) * `INSERT` (record transaction payment: `uid`, `student_fee_id`, `amount`, `payment_method`, `transaction_reference`, `payment_date`, `created_by`, `sync_status = 'pending'`) * `UPDATE` (modify notes details; soft-delete with `is_deleted = 1`) * **`student_fees`**: * `SELECT` (check fee balances), `UPDATE` (increment `paid_amount`, modify status to `'paid'` / `'partial'`) * **`users`**: * `SELECT` (validate student name) ### 38. [reports.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/reports.controller.js) *(Note: Completely READ-ONLY SELECT operations)* * **`grades`**, **`attendance_new`**, **`student_fees`**, **`enrollments`**, **`users`**, **`classes`**, **`subjects`**: * `SELECT` (aggregate term averages, attendance percentages, unpaid balances summaries) ### 39. [schoolSettings.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/schoolSettings.controller.js) * **`school_settings`**: * `SELECT` (get system details) * `INSERT` / `UPDATE` (upsert global key-value preferences: `setting_key`, `setting_value`, `category`, `updated_by`) ### 40. [settings.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/settings.controller.js) * **`settings`**: * `SELECT` (list system configuration keys) * `INSERT` / `UPDATE` (upsert preferences: `key`, `value`, `category`, `description`) ### 41. [social.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/social.controller.js) * **`posts`**: * `SELECT` (feed index) * `INSERT` (create social post: `uid`, `author_id`, `content`, `image_url`) * `UPDATE` (modify post; soft-delete with `is_deleted = 1`) * **`post_comments`**: * `SELECT` (comments for post) * `INSERT` (post comment: `uid`, `post_id`, `author_id`, `content`) * `UPDATE` (soft-delete with `is_deleted = 1`) * **`post_likes`**: * `SELECT` (likes count checks) * `INSERT` (like a post: `uid`, `post_id`, `user_id`) * `DELETE` (unlike a post: remove row matching user/post) * **`users`**: * `SELECT` (join author names) ### 42. [staff-attendance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/staff-attendance.controller.js) * **`staff_attendance`**: * `SELECT` (attendance status details roster checklist) * `INSERT` / `UPDATE` (bulk upsert checklist logs: `uid`, `staff_id`, `date`, `status`, `remarks`, `marked_by`, `sync_status = 'pending'`) * **`users`**: * `SELECT` (joining active staff names) ### 43. [students-fees.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/students-fees.controller.js) *(Note: Completely READ-ONLY SELECT operations)* * **`student_fees`**, **`fee_groups`**, **`fee_plans`**, **`student_fee_discounts`**, **`discounts`**, **`trip_payments`**, **`trips`**, **`users`**, **`parent_students`**: * `SELECT` (scoped lookup of child balances, travel bookings, installment plans) ### 44. [students.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/students.controller.js) *(Note: Completely READ-ONLY SELECT operations)* * **`users`**, **`parent_students`**, **`enrollments`**, **`subjects`**, **`grades`**, **`submissions`**, **`assignments`**, **`exam_attempts`**, **`exam_schedules`**, **`exam_groups`**, **`attendance_new`**: * `SELECT` (academic dashboard grade averages, term attendance percentages, exam schedule bounds) ### 45. [subjects.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/subjects.controller.js) * **`subjects`**: * `SELECT` (list classes courses) * `INSERT` (create subject: `uid`, `name`, `code`, `class_id`, `teacher_id`, `description`, `credit_hours`) * `UPDATE` (modify subject details; soft-delete with `is_deleted = 1`) * **`classes`**, **`users`**: * `SELECT` (validate bounds) ### 46. [sync.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/sync.controller.js) * **SyncEngine Tables**: * This controller initiates standard manual cloud sync cycles. Under the hood, the transaction engine targets **all sync-aware tables** having the `sync_status` column (including `users`, `grades`, `attendance_new`, `student_fees`, `expenses`, `visitor_logs`, `notices`, `assignments`, `classes`, etc.). * `SELECT` (fetch rows where `sync_status = 'pending'`) * `UPDATE` (update target rows to `sync_status = 'synced'` or `sync_status = 'conflict'` upon completion) ### 47. [sysadmin.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/sysadmin.controller.js) *(Note: Technical infrastructure telemetry and diagnostics)* * **`audit_logs`**: * `SELECT` (count active logins last 24h, list recent technical audit lines) * **`sqlite_master`**: * `SELECT` (find tables containing `sync_status` column to verify conflicts) ### 48. [teacher.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/teacher.controller.js) * **`syllabuses`**: * `SELECT` (list syllabus catalog filterable by subject) * `INSERT` (create syllabus: `uid`, `subject_id`, `title`, `description`, `file_path`, `version`, `created_by`) * **`schemes_of_work`**: * `SELECT` (list schemes) * `INSERT` (create scheme: `uid`, `subject_id`, `teacher_id`, `term`, `academic_year`, `content`) * **`focus_points`**: * `SELECT` (topic items catalog) * `INSERT` (create focus point: `uid`, `scheme_id`, `topic`, `objectives`, `key_concepts`, `resources_needed`) * **`lesson_plans`**: * `SELECT` (lesson plans details lists) * `INSERT` (create plan: `uid`, `teacher_id`, `subject_id`, `scheme_id`, `focus_point_id`, `date`, `topic`, `objectives`, `introduction`, `development`, `conclusion`, `assessment_method`, `homework`, `reflections`) * **`departments`**, **`subjects_new`**, **`users`**: * `SELECT` (verify teacher departments constraints) ### 49. [transport-attendance.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/transport-attendance.controller.js) * **`transport_attendance`**: * `SELECT` (attendance logs lists) * `INSERT` / `UPDATE` (bulk upsert roll-call logs matching `(route_id, student_id, date)`) * **`routes`**, **`users`**, **`parent_students`**, **`transport_allocations`**: * `SELECT` (check active student allocations on route) ### 50. [transport.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/transport.controller.js) * **`vehicles`**: * `SELECT` (list vehicles catalog) * `INSERT` (create vehicle: `uid`, `registration_number`, `model`, `capacity`, `vehicle_type`, `fuel_type`, `status = 'active'`, `description`) * **`routes`**: * `SELECT` (list routes catalog) * `INSERT` (create route: `uid`, `name`, `code`, `start_point`, `end_point`, `distance_km`, `estimated_time_minutes`, `status = 'active'`, `description`) * **`vehicle_routes`**: * `SELECT` (active assignments catalog) * `INSERT` (create assignment: `uid`, `vehicle_id`, `route_id`, `driver_id`, `start_time = '07:00'`, `end_time = '16:00'`, `is_active = 1`) * `UPDATE` (modify vehicle/driver details) * **`transport_allocations`**: * `SELECT` (active student passenger rolls) * `INSERT` (allocate student passenger: `uid`, `student_id`, `route_id`, `pickup_point_id`, `vehicle_route_id`, `fee_amount`, `effective_from`, `effective_to`, `is_active = 1`) * `UPDATE` (deallocate passenger: set `is_active = 0`, `is_deleted = 1`) * **`pickup_points`**: * `SELECT` (list pickup locations) * **`transport_attendance`**: * `SELECT` (list attendance) * `INSERT` / `UPDATE` (bulk upsert attendance matching `(route_id, student_id, date)`) * **`users`**: * `SELECT` (verify drivers/students) ### 51. [users.controller.js](file:///E:/nextgen/next-gen/server/src/controllers/users.controller.js) * **`users`**: * `SELECT` (list directory, authentication detail fetch) * `INSERT` (register user: `uid`, `email`, `password`, `role`, `first_name`, `last_name`, `phone`, `is_active = 1`, `created_at`) * `UPDATE` (modify user details, profile_image, active status, reset password; soft-delete with `is_deleted = 1`) * **`parent_students`**: * `SELECT` (check linkages) * `INSERT` (link child student to parent: `uid`, `parent_id`, `student_id`) * `UPDATE` (unlink student: soft-delete with `is_deleted = 1`)