@brite-future-schools-contracts/contracts 2.0.12 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,35 +1,47 @@
1
- import "./chunk-PDCM3NIB.js";
1
+ import "./chunk-NCAGCDZV.js";
2
2
  import {
3
3
  attendanceContract,
4
4
  authContract,
5
5
  bulkUploadStudentsContract,
6
+ calendarContract,
7
+ calendarListTermsContract,
6
8
  changePasswordContract,
7
9
  createDepartmentContract,
10
+ createGradeContract,
8
11
  createStaffContract,
9
12
  createStudentContract,
13
+ createTermContract,
14
+ createYearContract,
10
15
  getByClassContract,
11
16
  getByStudentContract,
12
17
  getMeContract,
13
18
  getStaffByIdContract,
14
19
  getStudentByIdContract,
20
+ gradesContract,
15
21
  hrContract,
16
22
  linkGuardianContract,
17
23
  listClassesContract,
18
24
  listDepartmentsContract,
25
+ listGradesContract,
19
26
  listStaffContract,
20
27
  listStudentsContract,
21
28
  listTermsContract,
29
+ listYearsContract,
22
30
  loginContract,
23
31
  logoutContract,
24
32
  markAttendanceContract,
25
33
  refreshTokenContract,
26
34
  requestPasswordResetContract,
27
35
  resetPasswordContract,
36
+ setCurrentTermContract,
37
+ setCurrentYearContract,
28
38
  studentsContract,
29
39
  switchBranchContract,
30
40
  updateStaffStatusContract
31
- } from "./chunk-YQELK62C.js";
41
+ } from "./chunk-ZHUFBLV5.js";
32
42
  import {
43
+ AcademicTermSchema,
44
+ AcademicYearSchema,
33
45
  AttendanceRecordInputSchema,
34
46
  AttendanceStatusSchema,
35
47
  BranchRefSchema,
@@ -40,20 +52,26 @@ import {
40
52
  ClassAttendanceRowSchema,
41
53
  ClassSummarySchema,
42
54
  CreateDepartmentInputSchema,
55
+ CreateGradeInputSchema,
43
56
  CreateStaffInputSchema,
44
57
  CreateStaffOutputSchema,
45
58
  CreateStudentInputSchema,
46
59
  CreateStudentOutputSchema,
60
+ CreateTermInputSchema,
61
+ CreateYearInputSchema,
47
62
  CuidSchema,
48
63
  DepartmentSchema,
49
64
  EmploymentTypeSchema,
65
+ GRADE_LEVELS,
50
66
  GenderSchema,
51
67
  GetByClassInputSchema,
52
68
  GetByStudentInputSchema,
53
69
  GradeLevelSchema,
70
+ GradeSchema,
54
71
  LinkGuardianInputSchema,
55
72
  ListStaffInputSchema,
56
73
  ListStudentsInputSchema,
74
+ ListTermsInputSchema,
57
75
  LoginInputSchema,
58
76
  LoginOutputSchema,
59
77
  LogoutInputSchema,
@@ -64,10 +82,11 @@ import {
64
82
  RefreshTokenOutputSchema,
65
83
  RequestPasswordResetInputSchema,
66
84
  ResetPasswordInputSchema,
67
- RoleNameSchema,
68
85
  SessionUserOutputSchema,
69
86
  SessionUserRoleSchema,
70
87
  SessionUserSubRoleSchema,
88
+ SetCurrentTermInputSchema,
89
+ SetCurrentYearInputSchema,
71
90
  SoftDeleteSchema,
72
91
  StaffListItemSchema,
73
92
  StaffProfileSchema,
@@ -80,7 +99,7 @@ import {
80
99
  TimestampsSchema,
81
100
  UuidSchema,
82
101
  paginatedOutputSchema
83
- } from "./chunk-TTAZOH4Y.js";
102
+ } from "./chunk-TBCAMVHG.js";
84
103
 
85
104
  // src/roles/helpers.ts
86
105
  function hasRole(user, role) {
@@ -238,6 +257,8 @@ function canAccessAdminDashboard(user) {
238
257
  return !isStudent(user) && !isParent(user) && !isPrefect(user) && !isOrgSponsor(user) && !isIndividualSponsor(user);
239
258
  }
240
259
  export {
260
+ AcademicTermSchema,
261
+ AcademicYearSchema,
241
262
  AttendanceRecordInputSchema,
242
263
  AttendanceStatusSchema,
243
264
  BranchRefSchema,
@@ -248,20 +269,26 @@ export {
248
269
  ClassAttendanceRowSchema,
249
270
  ClassSummarySchema,
250
271
  CreateDepartmentInputSchema,
272
+ CreateGradeInputSchema,
251
273
  CreateStaffInputSchema,
252
274
  CreateStaffOutputSchema,
253
275
  CreateStudentInputSchema,
254
276
  CreateStudentOutputSchema,
277
+ CreateTermInputSchema,
278
+ CreateYearInputSchema,
255
279
  CuidSchema,
256
280
  DepartmentSchema,
257
281
  EmploymentTypeSchema,
282
+ GRADE_LEVELS,
258
283
  GenderSchema,
259
284
  GetByClassInputSchema,
260
285
  GetByStudentInputSchema,
261
286
  GradeLevelSchema,
287
+ GradeSchema,
262
288
  LinkGuardianInputSchema,
263
289
  ListStaffInputSchema,
264
290
  ListStudentsInputSchema,
291
+ ListTermsInputSchema,
265
292
  LoginInputSchema,
266
293
  LoginOutputSchema,
267
294
  LogoutInputSchema,
@@ -272,10 +299,11 @@ export {
272
299
  RefreshTokenOutputSchema,
273
300
  RequestPasswordResetInputSchema,
274
301
  ResetPasswordInputSchema,
275
- RoleNameSchema,
276
302
  SessionUserOutputSchema,
277
303
  SessionUserRoleSchema,
278
304
  SessionUserSubRoleSchema,
305
+ SetCurrentTermInputSchema,
306
+ SetCurrentYearInputSchema,
279
307
  SoftDeleteSchema,
280
308
  StaffListItemSchema,
281
309
  StaffProfileSchema,
@@ -290,6 +318,8 @@ export {
290
318
  attendanceContract,
291
319
  authContract,
292
320
  bulkUploadStudentsContract,
321
+ calendarContract,
322
+ calendarListTermsContract,
293
323
  canAccessAdminDashboard,
294
324
  canAssignClassTeacher,
295
325
  canManageStaff,
@@ -303,13 +333,17 @@ export {
303
333
  canViewStudentList,
304
334
  changePasswordContract,
305
335
  createDepartmentContract,
336
+ createGradeContract,
306
337
  createStaffContract,
307
338
  createStudentContract,
339
+ createTermContract,
340
+ createYearContract,
308
341
  getByClassContract,
309
342
  getByStudentContract,
310
343
  getMeContract,
311
344
  getStaffByIdContract,
312
345
  getStudentByIdContract,
346
+ gradesContract,
313
347
  hrContract,
314
348
  isBoardingMaster,
315
349
  isBursar,
@@ -343,9 +377,11 @@ export {
343
377
  linkGuardianContract,
344
378
  listClassesContract,
345
379
  listDepartmentsContract,
380
+ listGradesContract,
346
381
  listStaffContract,
347
382
  listStudentsContract,
348
383
  listTermsContract,
384
+ listYearsContract,
349
385
  loginContract,
350
386
  logoutContract,
351
387
  markAttendanceContract,
@@ -353,6 +389,8 @@ export {
353
389
  refreshTokenContract,
354
390
  requestPasswordResetContract,
355
391
  resetPasswordContract,
392
+ setCurrentTermContract,
393
+ setCurrentYearContract,
356
394
  studentsContract,
357
395
  switchBranchContract,
358
396
  updateStaffStatusContract
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/roles/helpers.ts","../src/permissions/index.ts"],"sourcesContent":["/**\n * Brite Future Schools — bfs-contracts\n * Role helper functions.\n *\n * Every helper takes a SessionUser and returns a boolean.\n * Use these instead of hardcoded role string comparisons everywhere.\n *\n * Usage:\n * import { isProprietor, isPrincipal } from '@brite-future-schools-contracts/contracts'\n * if (isProprietor(user)) { ... }\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n * Phase 0.2 (2026-06-06): Roles reconciled against schema — added\n * SCHOOL_NURSE, LAB_TECHNICIAN, SPORTS_COACH,\n * CARETAKER, SECURITY, KITCHEN_STAFF, IT_ADMIN,\n * ORG_SPONSOR, INDIVIDUAL_SPONSOR, KITCHEN_MANAGER,\n * BOARDING_MASTER, PREFECT\n *\n * @module src/roles/helpers\n * @since Phase 0.1\n */\n\nimport type { RoleName, SessionUser } from './types.js'\n\n// ── Private helper ─────────────────────────────────────────────────────────────\n\nfunction hasRole(user: SessionUser, role: RoleName): boolean {\n return user.roles.some(\n (r) => r.name === role && r.branchId === user.activeBranchId,\n )\n}\n\n// ── Senior leadership ──────────────────────────────────────────────────────────\n\nexport function isProprietor(user: SessionUser): boolean {\n return hasRole(user, 'PROPRIETOR')\n}\n\nexport function isDirector(user: SessionUser): boolean {\n return hasRole(user, 'DIRECTOR')\n}\n\nexport function isSystemAdmin(user: SessionUser): boolean {\n return hasRole(user, 'SYSTEM_ADMIN')\n}\n\nexport function isPrincipal(user: SessionUser): boolean {\n return hasRole(user, 'PRINCIPAL')\n}\n\nexport function isDeputyPrincipal(user: SessionUser): boolean {\n return hasRole(user, 'DEPUTY_PRINCIPAL')\n}\n\nexport function isSeniorLeadership(user: SessionUser): boolean {\n return (\n isProprietor(user) ||\n isDirector(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user)\n )\n}\n\n// ── Academic staff ─────────────────────────────────────────────────────────────\n\nexport function isHOD(user: SessionUser): boolean {\n return hasRole(user, 'HOD')\n}\n\nexport function isClassTeacher(user: SessionUser): boolean {\n return hasRole(user, 'CLASS_TEACHER')\n}\n\nexport function isSubjectTeacher(user: SessionUser): boolean {\n return hasRole(user, 'SUBJECT_TEACHER')\n}\n\n// ── Support staff ──────────────────────────────────────────────────────────────\n\nexport function isSchoolNurse(user: SessionUser): boolean {\n return hasRole(user, 'SCHOOL_NURSE')\n}\n\nexport function isLibrarian(user: SessionUser): boolean {\n return hasRole(user, 'LIBRARIAN')\n}\n\nexport function isLabTechnician(user: SessionUser): boolean {\n return hasRole(user, 'LAB_TECHNICIAN')\n}\n\nexport function isSportsCoach(user: SessionUser): boolean {\n return hasRole(user, 'SPORTS_COACH')\n}\n\nexport function isCounsellor(user: SessionUser): boolean {\n return hasRole(user, 'COUNSELLOR')\n}\n\nexport function isCaretaker(user: SessionUser): boolean {\n return hasRole(user, 'CARETAKER')\n}\n\nexport function isSecurity(user: SessionUser): boolean {\n return hasRole(user, 'SECURITY')\n}\n\nexport function isBoardingMaster(user: SessionUser): boolean {\n return hasRole(user, 'BOARDING_MASTER')\n}\n\n// ── Operations ─────────────────────────────────────────────────────────────────\n\nexport function isBursar(user: SessionUser): boolean {\n return hasRole(user, 'BURSAR')\n}\n\nexport function isHrAdmin(user: SessionUser): boolean {\n return hasRole(user, 'HR_ADMIN')\n}\n\nexport function isDriver(user: SessionUser): boolean {\n return hasRole(user, 'DRIVER')\n}\n\nexport function isKitchenStaff(user: SessionUser): boolean {\n return hasRole(user, 'KITCHEN_STAFF')\n}\n\nexport function isKitchenManager(user: SessionUser): boolean {\n return hasRole(user, 'KITCHEN_MANAGER')\n}\n\nexport function isItAdmin(user: SessionUser): boolean {\n return hasRole(user, 'IT_ADMIN')\n}\n\n// ── Students and parents ───────────────────────────────────────────────────────\n\nexport function isPrefect(user: SessionUser): boolean {\n return hasRole(user, 'PREFECT')\n}\n\nexport function isStudent(user: SessionUser): boolean {\n return hasRole(user, 'STUDENT')\n}\n\nexport function isParent(user: SessionUser): boolean {\n return hasRole(user, 'PARENT')\n}\n\n// ── Sponsors ───────────────────────────────────────────────────────────────────\n\nexport function isOrgSponsor(user: SessionUser): boolean {\n return hasRole(user, 'ORG_SPONSOR')\n}\n\nexport function isIndividualSponsor(user: SessionUser): boolean {\n return hasRole(user, 'INDIVIDUAL_SPONSOR')\n}\n\n// ── Broad groupings ────────────────────────────────────────────────────────────\n\nexport function isStaff(user: SessionUser): boolean {\n const staffRoles: RoleName[] = [\n 'PROPRIETOR',\n 'DIRECTOR',\n 'SYSTEM_ADMIN',\n 'PRINCIPAL',\n 'DEPUTY_PRINCIPAL',\n 'HOD',\n 'CLASS_TEACHER',\n 'SUBJECT_TEACHER',\n 'BURSAR',\n 'HR_ADMIN',\n 'SCHOOL_NURSE',\n 'LIBRARIAN',\n 'LAB_TECHNICIAN',\n 'SPORTS_COACH',\n 'COUNSELLOR',\n 'CARETAKER',\n 'SECURITY',\n 'KITCHEN_STAFF',\n 'KITCHEN_MANAGER',\n 'DRIVER',\n 'IT_ADMIN',\n 'BOARDING_MASTER',\n 'PREFECT',\n ]\n return user.roles.some(\n (r) =>\n staffRoles.includes(r.name) && r.branchId === user.activeBranchId,\n )\n}","/**\n * Brite Future Schools — bfs-contracts\n * Permission helper functions.\n *\n * Answer \"can this user do X?\" — not \"is this user role Y?\".\n * Every UI gate and API guard must use these instead of raw role checks.\n *\n * Phase History:\n * Phase 2 (2026-06-08): Initial creation — attendance, staff, students,\n * dashboard permissions\n * Phase 3 (2026-06-10): Added canAssignClassTeacher, canViewClasses\n *\n * @module src/permissions/index\n * @since Phase 2\n */\n\nimport type { SessionUser } from '../roles/types.js'\nimport {\n isProprietor,\n isDirector,\n isSystemAdmin,\n isPrincipal,\n isDeputyPrincipal,\n isHOD,\n isClassTeacher,\n isHrAdmin,\n isStudent,\n isParent,\n isOrgSponsor,\n isIndividualSponsor,\n isPrefect,\n} from '../roles/helpers.js'\n\n// ── Attendance ─────────────────────────────────────────────────────────────────\n\n/** Class teacher marks roll for their own class; senior staff can mark any. */\nexport function canMarkClassAttendance(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user)\n )\n}\n\n/** Who can read class attendance records. */\nexport function canViewClassAttendance(user: SessionUser): boolean {\n return (\n canMarkClassAttendance(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can record staff attendance. */\nexport function canMarkStaffAttendance(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user)\n )\n}\n\n/** Who can view staff attendance records. */\nexport function canViewStaffAttendance(user: SessionUser): boolean {\n return (\n canMarkStaffAttendance(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Staff ──────────────────────────────────────────────────────────────────────\n\n/** Who can view the staff list. */\nexport function canViewStaffList(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can create or edit staff records. */\nexport function canManageStaff(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Students ───────────────────────────────────────────────────────────────────\n\n/** Who can view the student list. */\nexport function canViewStudentList(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isHrAdmin(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can enrol or edit student records. */\nexport function canManageStudents(user: SessionUser): boolean {\n return (\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isHrAdmin(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Classes ────────────────────────────────────────────────────────────────────\n\n/** Who can view the classes list and class detail. */\nexport function canViewClasses(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can assign or reassign a class teacher to a class. */\nexport function canAssignClassTeacher(user: SessionUser): boolean {\n return (\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Dashboard ──────────────────────────────────────────────────────────────────\n\n/** Anyone with a staff-level or above role can access the admin dashboard. */\nexport function canAccessAdminDashboard(user: SessionUser): boolean {\n return (\n !isStudent(user) &&\n !isParent(user) &&\n !isPrefect(user) &&\n !isOrgSponsor(user) &&\n !isIndividualSponsor(user)\n )\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/roles/helpers.ts","../src/permissions/index.ts"],"sourcesContent":["/**\n * Brite Future Schools — bfs-contracts\n * Role helper functions.\n *\n * Every helper takes a SessionUser and returns a boolean.\n * Use these instead of hardcoded role string comparisons everywhere.\n *\n * Usage:\n * import { isProprietor, isPrincipal } from '@brite-future-schools-contracts/contracts'\n * if (isProprietor(user)) { ... }\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n * Phase 0.2 (2026-06-06): Roles reconciled against schema — added\n * SCHOOL_NURSE, LAB_TECHNICIAN, SPORTS_COACH,\n * CARETAKER, SECURITY, KITCHEN_STAFF, IT_ADMIN,\n * ORG_SPONSOR, INDIVIDUAL_SPONSOR, KITCHEN_MANAGER,\n * BOARDING_MASTER, PREFECT\n *\n * @module src/roles/helpers\n * @since Phase 0.1\n */\n\nimport type { RoleName, SessionUser } from './types.js'\n\n// ── Private helper ─────────────────────────────────────────────────────────────\n\nfunction hasRole(user: SessionUser, role: RoleName): boolean {\n return user.roles.some(\n (r) => r.name === role && r.branchId === user.activeBranchId,\n )\n}\n\n// ── Senior leadership ──────────────────────────────────────────────────────────\n\nexport function isProprietor(user: SessionUser): boolean {\n return hasRole(user, 'PROPRIETOR')\n}\n\nexport function isDirector(user: SessionUser): boolean {\n return hasRole(user, 'DIRECTOR')\n}\n\nexport function isSystemAdmin(user: SessionUser): boolean {\n return hasRole(user, 'SYSTEM_ADMIN')\n}\n\nexport function isPrincipal(user: SessionUser): boolean {\n return hasRole(user, 'PRINCIPAL')\n}\n\nexport function isDeputyPrincipal(user: SessionUser): boolean {\n return hasRole(user, 'DEPUTY_PRINCIPAL')\n}\n\nexport function isSeniorLeadership(user: SessionUser): boolean {\n return (\n isProprietor(user) ||\n isDirector(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user)\n )\n}\n\n// ── Academic staff ─────────────────────────────────────────────────────────────\n\nexport function isHOD(user: SessionUser): boolean {\n return hasRole(user, 'HOD')\n}\n\nexport function isClassTeacher(user: SessionUser): boolean {\n return hasRole(user, 'CLASS_TEACHER')\n}\n\nexport function isSubjectTeacher(user: SessionUser): boolean {\n return hasRole(user, 'SUBJECT_TEACHER')\n}\n\n// ── Support staff ──────────────────────────────────────────────────────────────\n\nexport function isSchoolNurse(user: SessionUser): boolean {\n return hasRole(user, 'SCHOOL_NURSE')\n}\n\nexport function isLibrarian(user: SessionUser): boolean {\n return hasRole(user, 'LIBRARIAN')\n}\n\nexport function isLabTechnician(user: SessionUser): boolean {\n return hasRole(user, 'LAB_TECHNICIAN')\n}\n\nexport function isSportsCoach(user: SessionUser): boolean {\n return hasRole(user, 'SPORTS_COACH')\n}\n\nexport function isCounsellor(user: SessionUser): boolean {\n return hasRole(user, 'COUNSELLOR')\n}\n\nexport function isCaretaker(user: SessionUser): boolean {\n return hasRole(user, 'CARETAKER')\n}\n\nexport function isSecurity(user: SessionUser): boolean {\n return hasRole(user, 'SECURITY')\n}\n\nexport function isBoardingMaster(user: SessionUser): boolean {\n return hasRole(user, 'BOARDING_MASTER')\n}\n\n// ── Operations ─────────────────────────────────────────────────────────────────\n\nexport function isBursar(user: SessionUser): boolean {\n return hasRole(user, 'BURSAR')\n}\n\nexport function isHrAdmin(user: SessionUser): boolean {\n return hasRole(user, 'HR_ADMIN')\n}\n\nexport function isDriver(user: SessionUser): boolean {\n return hasRole(user, 'DRIVER')\n}\n\nexport function isKitchenStaff(user: SessionUser): boolean {\n return hasRole(user, 'KITCHEN_STAFF')\n}\n\nexport function isKitchenManager(user: SessionUser): boolean {\n return hasRole(user, 'KITCHEN_MANAGER')\n}\n\nexport function isItAdmin(user: SessionUser): boolean {\n return hasRole(user, 'IT_ADMIN')\n}\n\n// ── Students and parents ───────────────────────────────────────────────────────\n\nexport function isPrefect(user: SessionUser): boolean {\n return hasRole(user, 'PREFECT')\n}\n\nexport function isStudent(user: SessionUser): boolean {\n return hasRole(user, 'STUDENT')\n}\n\nexport function isParent(user: SessionUser): boolean {\n return hasRole(user, 'PARENT')\n}\n\n// ── Sponsors ───────────────────────────────────────────────────────────────────\n\nexport function isOrgSponsor(user: SessionUser): boolean {\n return hasRole(user, 'ORG_SPONSOR')\n}\n\nexport function isIndividualSponsor(user: SessionUser): boolean {\n return hasRole(user, 'INDIVIDUAL_SPONSOR')\n}\n\n// ── Broad groupings ────────────────────────────────────────────────────────────\n\nexport function isStaff(user: SessionUser): boolean {\n const staffRoles: RoleName[] = [\n 'PROPRIETOR',\n 'DIRECTOR',\n 'SYSTEM_ADMIN',\n 'PRINCIPAL',\n 'DEPUTY_PRINCIPAL',\n 'HOD',\n 'CLASS_TEACHER',\n 'SUBJECT_TEACHER',\n 'BURSAR',\n 'HR_ADMIN',\n 'SCHOOL_NURSE',\n 'LIBRARIAN',\n 'LAB_TECHNICIAN',\n 'SPORTS_COACH',\n 'COUNSELLOR',\n 'CARETAKER',\n 'SECURITY',\n 'KITCHEN_STAFF',\n 'KITCHEN_MANAGER',\n 'DRIVER',\n 'IT_ADMIN',\n 'BOARDING_MASTER',\n 'PREFECT',\n ]\n return user.roles.some(\n (r) =>\n staffRoles.includes(r.name) && r.branchId === user.activeBranchId,\n )\n}","/**\n * Brite Future Schools — bfs-contracts\n * Permission helper functions.\n *\n * Answer \"can this user do X?\" — not \"is this user role Y?\".\n * Every UI gate and API guard must use these instead of raw role checks.\n *\n * Phase History:\n * Phase 2 (2026-06-08): Initial creation — attendance, staff, students,\n * dashboard permissions\n * Phase 3 (2026-06-10): Added canAssignClassTeacher, canViewClasses\n *\n * @module src/permissions/index\n * @since Phase 2\n */\n\nimport type { SessionUser } from '../roles/types.js'\nimport {\n isProprietor,\n isDirector,\n isSystemAdmin,\n isPrincipal,\n isDeputyPrincipal,\n isHOD,\n isClassTeacher,\n isHrAdmin,\n isStudent,\n isParent,\n isOrgSponsor,\n isIndividualSponsor,\n isPrefect,\n} from '../roles/helpers.js'\n\n// ── Attendance ─────────────────────────────────────────────────────────────────\n\n/** Class teacher marks roll for their own class; senior staff can mark any. */\nexport function canMarkClassAttendance(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user)\n )\n}\n\n/** Who can read class attendance records. */\nexport function canViewClassAttendance(user: SessionUser): boolean {\n return (\n canMarkClassAttendance(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can record staff attendance. */\nexport function canMarkStaffAttendance(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user)\n )\n}\n\n/** Who can view staff attendance records. */\nexport function canViewStaffAttendance(user: SessionUser): boolean {\n return (\n canMarkStaffAttendance(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Staff ──────────────────────────────────────────────────────────────────────\n\n/** Who can view the staff list. */\nexport function canViewStaffList(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can create or edit staff records. */\nexport function canManageStaff(user: SessionUser): boolean {\n return (\n isHrAdmin(user) ||\n isPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Students ───────────────────────────────────────────────────────────────────\n\n/** Who can view the student list. */\nexport function canViewStudentList(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isHrAdmin(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can enrol or edit student records. */\nexport function canManageStudents(user: SessionUser): boolean {\n return (\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isHrAdmin(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Classes ────────────────────────────────────────────────────────────────────\n\n/** Who can view the classes list and class detail. */\nexport function canViewClasses(user: SessionUser): boolean {\n return (\n isClassTeacher(user) ||\n isHOD(user) ||\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n/** Who can assign or reassign a class teacher to a class. */\nexport function canAssignClassTeacher(user: SessionUser): boolean {\n return (\n isPrincipal(user) ||\n isDeputyPrincipal(user) ||\n isSystemAdmin(user) ||\n isDirector(user) ||\n isProprietor(user)\n )\n}\n\n// ── Dashboard ──────────────────────────────────────────────────────────────────\n\n/** Anyone with a staff-level or above role can access the admin dashboard. */\nexport function canAccessAdminDashboard(user: SessionUser): boolean {\n return (\n !isStudent(user) &&\n !isParent(user) &&\n !isPrefect(user) &&\n !isOrgSponsor(user) &&\n !isIndividualSponsor(user)\n )\n}"],"mappings":"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","names":[]}
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/schemas/index.ts
31
31
  var schemas_exports = {};
32
32
  __export(schemas_exports, {
33
+ AcademicTermSchema: () => AcademicTermSchema,
34
+ AcademicYearSchema: () => AcademicYearSchema,
33
35
  AttendanceRecordInputSchema: () => AttendanceRecordInputSchema,
34
36
  AttendanceStatusSchema: () => AttendanceStatusSchema,
35
37
  BranchRefSchema: () => BranchRefSchema,
@@ -40,20 +42,26 @@ __export(schemas_exports, {
40
42
  ClassAttendanceRowSchema: () => ClassAttendanceRowSchema,
41
43
  ClassSummarySchema: () => ClassSummarySchema,
42
44
  CreateDepartmentInputSchema: () => CreateDepartmentInputSchema,
45
+ CreateGradeInputSchema: () => CreateGradeInputSchema,
43
46
  CreateStaffInputSchema: () => CreateStaffInputSchema,
44
47
  CreateStaffOutputSchema: () => CreateStaffOutputSchema,
45
48
  CreateStudentInputSchema: () => CreateStudentInputSchema,
46
49
  CreateStudentOutputSchema: () => CreateStudentOutputSchema,
50
+ CreateTermInputSchema: () => CreateTermInputSchema,
51
+ CreateYearInputSchema: () => CreateYearInputSchema,
47
52
  CuidSchema: () => CuidSchema,
48
53
  DepartmentSchema: () => DepartmentSchema,
49
54
  EmploymentTypeSchema: () => EmploymentTypeSchema,
55
+ GRADE_LEVELS: () => GRADE_LEVELS,
50
56
  GenderSchema: () => GenderSchema,
51
57
  GetByClassInputSchema: () => GetByClassInputSchema,
52
58
  GetByStudentInputSchema: () => GetByStudentInputSchema,
53
59
  GradeLevelSchema: () => GradeLevelSchema,
60
+ GradeSchema: () => GradeSchema,
54
61
  LinkGuardianInputSchema: () => LinkGuardianInputSchema,
55
62
  ListStaffInputSchema: () => ListStaffInputSchema,
56
63
  ListStudentsInputSchema: () => ListStudentsInputSchema,
64
+ ListTermsInputSchema: () => ListTermsInputSchema,
57
65
  LoginInputSchema: () => LoginInputSchema,
58
66
  LoginOutputSchema: () => LoginOutputSchema,
59
67
  LogoutInputSchema: () => LogoutInputSchema,
@@ -64,10 +72,11 @@ __export(schemas_exports, {
64
72
  RefreshTokenOutputSchema: () => RefreshTokenOutputSchema,
65
73
  RequestPasswordResetInputSchema: () => RequestPasswordResetInputSchema,
66
74
  ResetPasswordInputSchema: () => ResetPasswordInputSchema,
67
- RoleNameSchema: () => RoleNameSchema,
68
75
  SessionUserOutputSchema: () => SessionUserOutputSchema,
69
76
  SessionUserRoleSchema: () => SessionUserRoleSchema,
70
77
  SessionUserSubRoleSchema: () => SessionUserSubRoleSchema,
78
+ SetCurrentTermInputSchema: () => SetCurrentTermInputSchema,
79
+ SetCurrentYearInputSchema: () => SetCurrentYearInputSchema,
71
80
  SoftDeleteSchema: () => SoftDeleteSchema,
72
81
  StaffListItemSchema: () => StaffListItemSchema,
73
82
  StaffProfileSchema: () => StaffProfileSchema,
@@ -98,15 +107,15 @@ var SoftDeleteSchema = z.object({
98
107
  })
99
108
  });
100
109
  var PaginationInputSchema = z.object({
101
- cursor: CuidSchema.optional().meta({
110
+ cursor: z.string().optional().meta({
102
111
  description: "Opaque cursor from the previous page response"
103
112
  }),
104
- limit: z.int().min(1).max(100).default(20).meta({ description: "Number of items to return (1\u2013100, default 20)" })
113
+ limit: z.int().min(1).max(200).default(20).meta({ description: "Number of items to return (1\u2013200, default 20)" })
105
114
  });
106
115
  function paginatedOutputSchema(itemSchema) {
107
116
  return z.object({
108
117
  items: z.array(itemSchema),
109
- nextCursor: CuidSchema.nullable().meta({
118
+ nextCursor: z.string().nullable().meta({
110
119
  description: "Pass as `cursor` on the next request; null when no more pages"
111
120
  }),
112
121
  total: z.int().nonnegative().meta({ description: "Total matching records (before pagination)" })
@@ -196,35 +205,6 @@ var EmploymentTypeSchema = z3.enum([
196
205
  "temporary",
197
206
  "intern"
198
207
  ]);
199
- var RoleNameSchema = z3.enum([
200
- "PROPRIETOR",
201
- "DIRECTOR",
202
- "SYSTEM_ADMIN",
203
- "PRINCIPAL",
204
- "DEPUTY_PRINCIPAL",
205
- "HOD",
206
- "CLASS_TEACHER",
207
- "SUBJECT_TEACHER",
208
- "BURSAR",
209
- "HR_ADMIN",
210
- "SCHOOL_NURSE",
211
- "LIBRARIAN",
212
- "LAB_TECHNICIAN",
213
- "SPORTS_COACH",
214
- "COUNSELLOR",
215
- "CARETAKER",
216
- "SECURITY",
217
- "KITCHEN_STAFF",
218
- "KITCHEN_MANAGER",
219
- "DRIVER",
220
- "IT_ADMIN",
221
- "BOARDING_MASTER",
222
- "PREFECT",
223
- "STUDENT",
224
- "PARENT",
225
- "ORG_SPONSOR",
226
- "INDIVIDUAL_SPONSOR"
227
- ]);
228
208
  var CreateStaffInputSchema = z3.object({
229
209
  // Personal details
230
210
  firstName: z3.string().min(1).max(100),
@@ -233,9 +213,9 @@ var CreateStaffInputSchema = z3.object({
233
213
  email: z3.email(),
234
214
  phone: z3.string().min(9).max(30),
235
215
  nationalId: z3.string().min(1).max(20),
236
- // Role assignment
237
- roleName: RoleNameSchema.meta({
238
- description: "System role to assign \u2014 determines dashboard access and permissions"
216
+ // Role assignment — DB-driven, any valid role code accepted
217
+ roleName: z3.string().min(1).meta({
218
+ description: "Role code from the roles table \u2014 e.g. TEACHER, PRINCIPAL"
239
219
  }),
240
220
  isPrimaryRole: z3.boolean().default(true),
241
221
  // Employment details
@@ -246,24 +226,19 @@ var CreateStaffInputSchema = z3.object({
246
226
  employmentType: EmploymentTypeSchema,
247
227
  contractStart: z3.iso.date().meta({ description: "ISO date, e.g. 2026-01-15" }),
248
228
  contractEnd: z3.iso.date().optional(),
249
- // Payroll
250
- basicSalary: z3.number().positive(),
251
- houseAllowance: z3.number().nonnegative().default(0),
252
- transportAllowance: z3.number().nonnegative().default(0),
253
- helbDeduction: z3.number().nonnegative().default(0),
254
- saccoDeduction: z3.number().nonnegative().default(0),
255
- // Banking
229
+ // Banking (optional at creation — can be completed later)
256
230
  bankName: z3.string().max(100).optional(),
257
231
  bankAccount: z3.string().max(30).optional(),
258
232
  bankBranch: z3.string().max(100).optional(),
259
- // Statutory
233
+ // Statutory (optional at creation)
260
234
  tscNumber: z3.string().max(30).optional(),
261
235
  kraPin: z3.string().max(20).optional(),
262
236
  nhifNo: z3.string().max(20).optional(),
263
- nssfNo: z3.string().max(20).optional()
237
+ nssfNo: z3.string().max(20).optional(),
238
+ helbNo: z3.string().max(20).optional(),
239
+ saccoNo: z3.string().max(20).optional()
264
240
  });
265
241
  var StaffProfileSchema = z3.object({
266
- // Staff record
267
242
  id: UuidSchema,
268
243
  userId: UuidSchema,
269
244
  branchId: UuidSchema,
@@ -276,28 +251,23 @@ var StaffProfileSchema = z3.object({
276
251
  kraPin: z3.string().nullable(),
277
252
  nhifNo: z3.string().nullable(),
278
253
  nssfNo: z3.string().nullable(),
254
+ helbNo: z3.string().nullable(),
255
+ saccoNo: z3.string().nullable(),
279
256
  designation: z3.string(),
280
257
  employmentType: EmploymentTypeSchema,
281
258
  contractStart: z3.string(),
282
259
  contractEnd: z3.string().nullable(),
283
- basicSalary: z3.string(),
284
- houseAllowance: z3.string(),
285
- transportAllowance: z3.string(),
286
- helbDeduction: z3.string().nullable(),
287
- saccoDeduction: z3.string().nullable(),
288
260
  bankName: z3.string().nullable(),
289
261
  bankAccount: z3.string().nullable(),
290
262
  bankBranch: z3.string().nullable(),
291
263
  status: z3.string(),
292
264
  createdAt: z3.string(),
293
- // From users join
294
265
  email: z3.string(),
295
266
  mustChangePassword: z3.boolean(),
296
- // Department (nullable — not all staff are in a department)
297
267
  departmentId: UuidSchema.nullable(),
298
268
  departmentName: z3.string().nullable(),
299
- // Primary role
300
- roleName: RoleNameSchema.nullable(),
269
+ // Role — DB-driven code string, not a fixed enum
270
+ roleName: z3.string().nullable(),
301
271
  roleId: UuidSchema.nullable()
302
272
  });
303
273
  var StaffListItemSchema = z3.object({
@@ -312,7 +282,7 @@ var StaffListItemSchema = z3.object({
312
282
  employmentType: EmploymentTypeSchema,
313
283
  status: z3.string(),
314
284
  departmentName: z3.string().nullable(),
315
- roleName: RoleNameSchema.nullable(),
285
+ roleName: z3.string().nullable(),
316
286
  createdAt: z3.string()
317
287
  });
318
288
  var ListStaffInputSchema = PaginationInputSchema.extend({
@@ -320,14 +290,13 @@ var ListStaffInputSchema = PaginationInputSchema.extend({
320
290
  description: "Search by name or email"
321
291
  }),
322
292
  departmentId: UuidSchema.optional(),
323
- roleName: RoleNameSchema.optional(),
293
+ roleName: z3.string().optional(),
324
294
  status: z3.enum(["active", "inactive"]).optional()
325
295
  });
326
296
  var CreateStaffOutputSchema = z3.object({
327
297
  staffId: UuidSchema,
328
298
  userId: UuidSchema,
329
299
  email: z3.string(),
330
- /** Temp password was emailed — not returned in response for security */
331
300
  emailSent: z3.boolean()
332
301
  });
333
302
  var DepartmentSchema = z3.object({
@@ -578,8 +547,80 @@ var StudentAttendanceRowSchema = z5.object({
578
547
  classId: UuidSchema,
579
548
  className: z5.string()
580
549
  });
550
+
551
+ // src/schemas/calendar.ts
552
+ var z6 = __toESM(require("zod"), 1);
553
+ var AcademicYearSchema = z6.object({
554
+ id: z6.string().uuid(),
555
+ branchId: z6.string().uuid(),
556
+ name: z6.string(),
557
+ startDate: z6.string(),
558
+ endDate: z6.string(),
559
+ isCurrent: z6.boolean(),
560
+ createdAt: z6.string()
561
+ });
562
+ var CreateYearInputSchema = z6.object({
563
+ name: z6.string().min(1).max(50),
564
+ startDate: z6.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD"),
565
+ endDate: z6.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD")
566
+ });
567
+ var SetCurrentYearInputSchema = z6.object({
568
+ yearId: z6.string().uuid()
569
+ });
570
+ var AcademicTermSchema = z6.object({
571
+ id: z6.string().uuid(),
572
+ branchId: z6.string().uuid(),
573
+ academicYearId: z6.string().uuid(),
574
+ name: z6.string(),
575
+ startDate: z6.string(),
576
+ endDate: z6.string(),
577
+ isCurrent: z6.boolean(),
578
+ createdAt: z6.string()
579
+ });
580
+ var CreateTermInputSchema = z6.object({
581
+ academicYearId: z6.string().uuid(),
582
+ name: z6.string().min(1).max(50),
583
+ startDate: z6.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD"),
584
+ endDate: z6.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD")
585
+ });
586
+ var SetCurrentTermInputSchema = z6.object({
587
+ termId: z6.string().uuid()
588
+ });
589
+ var ListTermsInputSchema = z6.object({
590
+ yearId: z6.string().uuid().optional()
591
+ });
592
+
593
+ // src/schemas/grades.ts
594
+ var z7 = __toESM(require("zod"), 1);
595
+ var GRADE_LEVELS = [
596
+ "PP1",
597
+ "PP2",
598
+ "G1",
599
+ "G2",
600
+ "G3",
601
+ "G4",
602
+ "G5",
603
+ "G6",
604
+ "G7",
605
+ "G8",
606
+ "G9"
607
+ ];
608
+ var GradeSchema = z7.object({
609
+ id: z7.string().uuid(),
610
+ branchId: z7.string().uuid(),
611
+ name: z7.string(),
612
+ level: GradeLevelSchema,
613
+ description: z7.string().nullable()
614
+ });
615
+ var CreateGradeInputSchema = z7.object({
616
+ name: z7.string().min(1).max(50),
617
+ level: GradeLevelSchema,
618
+ description: z7.string().max(300).optional()
619
+ });
581
620
  // Annotate the CommonJS export names for ESM import in node:
582
621
  0 && (module.exports = {
622
+ AcademicTermSchema,
623
+ AcademicYearSchema,
583
624
  AttendanceRecordInputSchema,
584
625
  AttendanceStatusSchema,
585
626
  BranchRefSchema,
@@ -590,20 +631,26 @@ var StudentAttendanceRowSchema = z5.object({
590
631
  ClassAttendanceRowSchema,
591
632
  ClassSummarySchema,
592
633
  CreateDepartmentInputSchema,
634
+ CreateGradeInputSchema,
593
635
  CreateStaffInputSchema,
594
636
  CreateStaffOutputSchema,
595
637
  CreateStudentInputSchema,
596
638
  CreateStudentOutputSchema,
639
+ CreateTermInputSchema,
640
+ CreateYearInputSchema,
597
641
  CuidSchema,
598
642
  DepartmentSchema,
599
643
  EmploymentTypeSchema,
644
+ GRADE_LEVELS,
600
645
  GenderSchema,
601
646
  GetByClassInputSchema,
602
647
  GetByStudentInputSchema,
603
648
  GradeLevelSchema,
649
+ GradeSchema,
604
650
  LinkGuardianInputSchema,
605
651
  ListStaffInputSchema,
606
652
  ListStudentsInputSchema,
653
+ ListTermsInputSchema,
607
654
  LoginInputSchema,
608
655
  LoginOutputSchema,
609
656
  LogoutInputSchema,
@@ -614,10 +661,11 @@ var StudentAttendanceRowSchema = z5.object({
614
661
  RefreshTokenOutputSchema,
615
662
  RequestPasswordResetInputSchema,
616
663
  ResetPasswordInputSchema,
617
- RoleNameSchema,
618
664
  SessionUserOutputSchema,
619
665
  SessionUserRoleSchema,
620
666
  SessionUserSubRoleSchema,
667
+ SetCurrentTermInputSchema,
668
+ SetCurrentYearInputSchema,
621
669
  SoftDeleteSchema,
622
670
  StaffListItemSchema,
623
671
  StaffProfileSchema,