@brite-future-schools-contracts/contracts 2.0.10 → 2.0.15

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.
@@ -33,28 +33,38 @@ __export(contracts_exports, {
33
33
  attendanceContract: () => attendanceContract,
34
34
  authContract: () => authContract,
35
35
  bulkUploadStudentsContract: () => bulkUploadStudentsContract,
36
+ calendarContract: () => calendarContract,
37
+ calendarListTermsContract: () => calendarListTermsContract,
36
38
  changePasswordContract: () => changePasswordContract,
37
39
  createDepartmentContract: () => createDepartmentContract,
40
+ createGradeContract: () => createGradeContract,
38
41
  createStaffContract: () => createStaffContract,
39
42
  createStudentContract: () => createStudentContract,
43
+ createTermContract: () => createTermContract,
44
+ createYearContract: () => createYearContract,
40
45
  getByClassContract: () => getByClassContract,
41
46
  getByStudentContract: () => getByStudentContract,
42
47
  getMeContract: () => getMeContract,
43
48
  getStaffByIdContract: () => getStaffByIdContract,
44
49
  getStudentByIdContract: () => getStudentByIdContract,
50
+ gradesContract: () => gradesContract,
45
51
  hrContract: () => hrContract,
46
52
  linkGuardianContract: () => linkGuardianContract,
47
53
  listClassesContract: () => listClassesContract,
48
54
  listDepartmentsContract: () => listDepartmentsContract,
55
+ listGradesContract: () => listGradesContract,
49
56
  listStaffContract: () => listStaffContract,
50
57
  listStudentsContract: () => listStudentsContract,
51
58
  listTermsContract: () => listTermsContract,
59
+ listYearsContract: () => listYearsContract,
52
60
  loginContract: () => loginContract,
53
61
  logoutContract: () => logoutContract,
54
62
  markAttendanceContract: () => markAttendanceContract,
55
63
  refreshTokenContract: () => refreshTokenContract,
56
64
  requestPasswordResetContract: () => requestPasswordResetContract,
57
65
  resetPasswordContract: () => resetPasswordContract,
66
+ setCurrentTermContract: () => setCurrentTermContract,
67
+ setCurrentYearContract: () => setCurrentYearContract,
58
68
  studentsContract: () => studentsContract,
59
69
  switchBranchContract: () => switchBranchContract,
60
70
  updateStaffStatusContract: () => updateStaffStatusContract
@@ -63,108 +73,82 @@ module.exports = __toCommonJS(contracts_exports);
63
73
 
64
74
  // src/contracts/auth.ts
65
75
  var import_contract = require("@orpc/contract");
66
- var z3 = __toESM(require("zod"), 1);
67
-
68
- // src/schemas/auth.ts
69
76
  var z2 = __toESM(require("zod"), 1);
70
77
 
71
- // src/schemas/base.ts
72
- var z = __toESM(require("zod"), 1);
73
- var CuidSchema = z.string().regex(/^[a-z][a-z0-9]{24}$/, "Invalid cuid2 identifier").meta({ description: "cuid2 \u2014 prefixed, collision-resistant identifier" });
74
- var UuidSchema = z.uuidv4().meta({ description: "RFC-4122 UUID v4" });
75
- var IsoDatetime = z.iso.datetime();
76
- var TimestampsSchema = z.object({
77
- createdAt: IsoDatetime.meta({ description: "ISO-8601 creation time (UTC)" }),
78
- updatedAt: IsoDatetime.meta({ description: "ISO-8601 last update time (UTC)" })
79
- });
80
- var SoftDeleteSchema = z.object({
81
- deletedAt: IsoDatetime.nullable().meta({
82
- description: "Set when the record is soft-deleted; null if active"
83
- })
84
- });
85
- var PaginationInputSchema = z.object({
86
- cursor: CuidSchema.optional().meta({
87
- description: "Opaque cursor from the previous page response"
88
- }),
89
- limit: z.int().min(1).max(100).default(20).meta({ description: "Number of items to return (1\u2013100, default 20)" })
90
- });
91
- var BranchRefSchema = z.object({
92
- branchId: CuidSchema.meta({ description: "The branch this record belongs to" })
93
- });
94
-
95
78
  // src/schemas/auth.ts
96
- var SessionUserRoleSchema = z2.object({
97
- id: CuidSchema,
98
- name: z2.string().meta({ description: "Role name, e.g. PRINCIPAL" }),
99
- branchId: CuidSchema,
100
- isPrimary: z2.boolean()
101
- });
102
- var SessionUserSubRoleSchema = z2.object({
103
- id: CuidSchema,
104
- name: z2.string().meta({ description: "Sub-role name, e.g. HEAD_PREFECT" }),
105
- branchId: CuidSchema
106
- });
107
- var SessionUserOutputSchema = z2.object({
108
- id: CuidSchema,
109
- email: z2.email(),
110
- firstName: z2.string(),
111
- lastName: z2.string(),
112
- activeBranchId: CuidSchema,
113
- roles: z2.array(SessionUserRoleSchema),
114
- subRoles: z2.array(SessionUserSubRoleSchema),
115
- isActive: z2.boolean(),
116
- mustChangePassword: z2.boolean()
117
- });
118
- var LoginInputSchema = z2.object({
119
- email: z2.email().meta({ description: "User email address" }),
120
- password: z2.string().min(1).meta({ description: "Plain-text password (sent over TLS)" }),
121
- branchId: CuidSchema.optional().meta({
79
+ var z = __toESM(require("zod"), 1);
80
+ var SessionUserRoleSchema = z.object({
81
+ id: z.string().uuid(),
82
+ name: z.string().meta({ description: "Role name, e.g. PRINCIPAL" }),
83
+ branchId: z.string().uuid(),
84
+ isPrimary: z.boolean()
85
+ });
86
+ var SessionUserSubRoleSchema = z.object({
87
+ id: z.string().uuid(),
88
+ name: z.string().meta({ description: "Sub-role name, e.g. HEAD_PREFECT" }),
89
+ branchId: z.string().uuid()
90
+ });
91
+ var SessionUserOutputSchema = z.object({
92
+ id: z.string().uuid(),
93
+ email: z.email(),
94
+ firstName: z.string(),
95
+ lastName: z.string(),
96
+ activeBranchId: z.string().uuid(),
97
+ roles: z.array(SessionUserRoleSchema),
98
+ subRoles: z.array(SessionUserSubRoleSchema),
99
+ isActive: z.boolean(),
100
+ mustChangePassword: z.boolean()
101
+ });
102
+ var LoginInputSchema = z.object({
103
+ email: z.email().meta({ description: "User email address" }),
104
+ password: z.string().min(1).meta({ description: "Plain-text password (sent over TLS)" }),
105
+ branchId: z.string().uuid().optional().meta({
122
106
  description: "Branch to activate on login; defaults to user primary branch"
123
107
  })
124
108
  });
125
- var LoginOutputSchema = z2.object({
126
- accessToken: z2.string().meta({ description: "Short-lived JWT (15 min)" }),
127
- refreshToken: z2.string().meta({ description: "Long-lived opaque refresh token (7 days)" }),
128
- expiresIn: z2.int().positive().meta({ description: "Access token TTL in seconds" }),
109
+ var LoginOutputSchema = z.object({
110
+ accessToken: z.string().meta({ description: "Short-lived JWT (15 min)" }),
111
+ refreshToken: z.string().meta({ description: "Long-lived opaque refresh token (7 days)" }),
112
+ expiresIn: z.int().positive().meta({ description: "Access token TTL in seconds" }),
129
113
  user: SessionUserOutputSchema
130
114
  });
131
- var RefreshTokenInputSchema = z2.object({
132
- refreshToken: z2.string().min(1)
115
+ var RefreshTokenInputSchema = z.object({
116
+ refreshToken: z.string().min(1)
133
117
  });
134
- var RefreshTokenOutputSchema = z2.object({
135
- accessToken: z2.string(),
136
- expiresIn: z2.int().positive()
118
+ var RefreshTokenOutputSchema = z.object({
119
+ accessToken: z.string(),
120
+ expiresIn: z.int().positive()
137
121
  });
138
- var LogoutInputSchema = z2.object({
139
- refreshToken: z2.string().min(1).meta({
122
+ var LogoutInputSchema = z.object({
123
+ refreshToken: z.string().min(1).meta({
140
124
  description: "The refresh token to revoke; also invalidated server-side"
141
125
  })
142
126
  });
143
- var ChangePasswordInputSchema = z2.object({
144
- currentPassword: z2.string().min(1),
145
- newPassword: z2.string().min(8, { error: "Password must be at least 8 characters" }),
146
- confirmPassword: z2.string().min(1)
127
+ var ChangePasswordInputSchema = z.object({
128
+ currentPassword: z.string().min(1),
129
+ newPassword: z.string().min(8, { error: "Password must be at least 8 characters" }),
130
+ confirmPassword: z.string().min(1)
147
131
  }).refine((v) => v.newPassword === v.confirmPassword, {
148
132
  error: "Passwords do not match",
149
133
  path: ["confirmPassword"]
150
134
  });
151
- var RequestPasswordResetInputSchema = z2.object({
152
- email: z2.email()
135
+ var RequestPasswordResetInputSchema = z.object({
136
+ email: z.email()
153
137
  });
154
- var ResetPasswordInputSchema = z2.object({
155
- token: z2.string().min(1).meta({ description: "One-time reset token from email link" }),
156
- newPassword: z2.string().min(8, { error: "Password must be at least 8 characters" }),
157
- confirmPassword: z2.string().min(1)
138
+ var ResetPasswordInputSchema = z.object({
139
+ token: z.string().min(1).meta({ description: "One-time reset token from email link" }),
140
+ newPassword: z.string().min(8, { error: "Password must be at least 8 characters" }),
141
+ confirmPassword: z.string().min(1)
158
142
  }).refine((v) => v.newPassword === v.confirmPassword, {
159
143
  error: "Passwords do not match",
160
144
  path: ["confirmPassword"]
161
145
  });
162
- var SwitchBranchInputSchema = z2.object({
163
- branchId: z2.string().uuid().meta({ description: "Branch to switch the active session to" })
146
+ var SwitchBranchInputSchema = z.object({
147
+ branchId: z.string().uuid().meta({ description: "Branch to switch the active session to" })
164
148
  });
165
149
 
166
150
  // src/contracts/auth.ts
167
- var EmptyOutputSchema = z3.object({}).meta({ description: "Empty success response" });
151
+ var EmptyOutputSchema = z2.object({}).meta({ description: "Empty success response" });
168
152
  var loginContract = import_contract.oc.route({ method: "POST", path: "/auth/login" }).input(LoginInputSchema).output(LoginOutputSchema);
169
153
  var refreshTokenContract = import_contract.oc.route({ method: "POST", path: "/auth/refresh" }).input(RefreshTokenInputSchema).output(RefreshTokenOutputSchema);
170
154
  var logoutContract = import_contract.oc.route({ method: "POST", path: "/auth/logout" }).input(LogoutInputSchema).output(EmptyOutputSchema);
@@ -188,6 +172,30 @@ var authContract = {
188
172
  var import_contract2 = require("@orpc/contract");
189
173
  var z5 = __toESM(require("zod"), 1);
190
174
 
175
+ // src/schemas/base.ts
176
+ var z3 = __toESM(require("zod"), 1);
177
+ var CuidSchema = z3.string().regex(/^[a-z][a-z0-9]{24}$/, "Invalid cuid2 identifier").meta({ description: "cuid2 \u2014 prefixed, collision-resistant identifier" });
178
+ var UuidSchema = z3.uuidv4().meta({ description: "RFC-4122 UUID v4" });
179
+ var IsoDatetime = z3.iso.datetime();
180
+ var TimestampsSchema = z3.object({
181
+ createdAt: IsoDatetime.meta({ description: "ISO-8601 creation time (UTC)" }),
182
+ updatedAt: IsoDatetime.meta({ description: "ISO-8601 last update time (UTC)" })
183
+ });
184
+ var SoftDeleteSchema = z3.object({
185
+ deletedAt: IsoDatetime.nullable().meta({
186
+ description: "Set when the record is soft-deleted; null if active"
187
+ })
188
+ });
189
+ var PaginationInputSchema = z3.object({
190
+ cursor: CuidSchema.optional().meta({
191
+ description: "Opaque cursor from the previous page response"
192
+ }),
193
+ limit: z3.int().min(1).max(100).default(20).meta({ description: "Number of items to return (1\u2013100, default 20)" })
194
+ });
195
+ var BranchRefSchema = z3.object({
196
+ branchId: CuidSchema.meta({ description: "The branch this record belongs to" })
197
+ });
198
+
191
199
  // src/schemas/hr.ts
192
200
  var z4 = __toESM(require("zod"), 1);
193
201
  var EmploymentTypeSchema = z4.enum([
@@ -196,35 +204,6 @@ var EmploymentTypeSchema = z4.enum([
196
204
  "temporary",
197
205
  "intern"
198
206
  ]);
199
- var RoleNameSchema = z4.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
207
  var CreateStaffInputSchema = z4.object({
229
208
  // Personal details
230
209
  firstName: z4.string().min(1).max(100),
@@ -233,9 +212,9 @@ var CreateStaffInputSchema = z4.object({
233
212
  email: z4.email(),
234
213
  phone: z4.string().min(9).max(30),
235
214
  nationalId: z4.string().min(1).max(20),
236
- // Role assignment
237
- roleName: RoleNameSchema.meta({
238
- description: "System role to assign \u2014 determines dashboard access and permissions"
215
+ // Role assignment — DB-driven, any valid role code accepted
216
+ roleName: z4.string().min(1).meta({
217
+ description: "Role code from the roles table \u2014 e.g. TEACHER, PRINCIPAL"
239
218
  }),
240
219
  isPrimaryRole: z4.boolean().default(true),
241
220
  // Employment details
@@ -246,24 +225,19 @@ var CreateStaffInputSchema = z4.object({
246
225
  employmentType: EmploymentTypeSchema,
247
226
  contractStart: z4.iso.date().meta({ description: "ISO date, e.g. 2026-01-15" }),
248
227
  contractEnd: z4.iso.date().optional(),
249
- // Payroll
250
- basicSalary: z4.number().positive(),
251
- houseAllowance: z4.number().nonnegative().default(0),
252
- transportAllowance: z4.number().nonnegative().default(0),
253
- helbDeduction: z4.number().nonnegative().default(0),
254
- saccoDeduction: z4.number().nonnegative().default(0),
255
- // Banking
228
+ // Banking (optional at creation — can be completed later)
256
229
  bankName: z4.string().max(100).optional(),
257
230
  bankAccount: z4.string().max(30).optional(),
258
231
  bankBranch: z4.string().max(100).optional(),
259
- // Statutory
232
+ // Statutory (optional at creation)
260
233
  tscNumber: z4.string().max(30).optional(),
261
234
  kraPin: z4.string().max(20).optional(),
262
235
  nhifNo: z4.string().max(20).optional(),
263
- nssfNo: z4.string().max(20).optional()
236
+ nssfNo: z4.string().max(20).optional(),
237
+ helbNo: z4.string().max(20).optional(),
238
+ saccoNo: z4.string().max(20).optional()
264
239
  });
265
240
  var StaffProfileSchema = z4.object({
266
- // Staff record
267
241
  id: UuidSchema,
268
242
  userId: UuidSchema,
269
243
  branchId: UuidSchema,
@@ -276,28 +250,23 @@ var StaffProfileSchema = z4.object({
276
250
  kraPin: z4.string().nullable(),
277
251
  nhifNo: z4.string().nullable(),
278
252
  nssfNo: z4.string().nullable(),
253
+ helbNo: z4.string().nullable(),
254
+ saccoNo: z4.string().nullable(),
279
255
  designation: z4.string(),
280
256
  employmentType: EmploymentTypeSchema,
281
257
  contractStart: z4.string(),
282
258
  contractEnd: z4.string().nullable(),
283
- basicSalary: z4.string(),
284
- houseAllowance: z4.string(),
285
- transportAllowance: z4.string(),
286
- helbDeduction: z4.string().nullable(),
287
- saccoDeduction: z4.string().nullable(),
288
259
  bankName: z4.string().nullable(),
289
260
  bankAccount: z4.string().nullable(),
290
261
  bankBranch: z4.string().nullable(),
291
262
  status: z4.string(),
292
263
  createdAt: z4.string(),
293
- // From users join
294
264
  email: z4.string(),
295
265
  mustChangePassword: z4.boolean(),
296
- // Department (nullable — not all staff are in a department)
297
266
  departmentId: UuidSchema.nullable(),
298
267
  departmentName: z4.string().nullable(),
299
- // Primary role
300
- roleName: RoleNameSchema.nullable(),
268
+ // Role — DB-driven code string, not a fixed enum
269
+ roleName: z4.string().nullable(),
301
270
  roleId: UuidSchema.nullable()
302
271
  });
303
272
  var StaffListItemSchema = z4.object({
@@ -312,7 +281,7 @@ var StaffListItemSchema = z4.object({
312
281
  employmentType: EmploymentTypeSchema,
313
282
  status: z4.string(),
314
283
  departmentName: z4.string().nullable(),
315
- roleName: RoleNameSchema.nullable(),
284
+ roleName: z4.string().nullable(),
316
285
  createdAt: z4.string()
317
286
  });
318
287
  var ListStaffInputSchema = PaginationInputSchema.extend({
@@ -320,14 +289,13 @@ var ListStaffInputSchema = PaginationInputSchema.extend({
320
289
  description: "Search by name or email"
321
290
  }),
322
291
  departmentId: UuidSchema.optional(),
323
- roleName: RoleNameSchema.optional(),
292
+ roleName: z4.string().optional(),
324
293
  status: z4.enum(["active", "inactive"]).optional()
325
294
  });
326
295
  var CreateStaffOutputSchema = z4.object({
327
296
  staffId: UuidSchema,
328
297
  userId: UuidSchema,
329
298
  email: z4.string(),
330
- /** Temp password was emailed — not returned in response for security */
331
299
  emailSent: z4.boolean()
332
300
  });
333
301
  var DepartmentSchema = z4.object({
@@ -646,33 +614,132 @@ var attendanceContract = {
646
614
  getByStudent: getByStudentContract,
647
615
  listTerms: listTermsContract
648
616
  };
617
+
618
+ // src/contracts/calendar.ts
619
+ var import_contract5 = require("@orpc/contract");
620
+ var z11 = __toESM(require("zod"), 1);
621
+
622
+ // src/schemas/calendar.ts
623
+ var z10 = __toESM(require("zod"), 1);
624
+ var AcademicYearSchema = z10.object({
625
+ id: z10.string().uuid(),
626
+ branchId: z10.string().uuid(),
627
+ name: z10.string(),
628
+ startDate: z10.string(),
629
+ endDate: z10.string(),
630
+ isCurrent: z10.boolean(),
631
+ createdAt: z10.string()
632
+ });
633
+ var CreateYearInputSchema = z10.object({
634
+ name: z10.string().min(1).max(50),
635
+ startDate: z10.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD"),
636
+ endDate: z10.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD")
637
+ });
638
+ var SetCurrentYearInputSchema = z10.object({
639
+ yearId: z10.string().uuid()
640
+ });
641
+ var AcademicTermSchema = z10.object({
642
+ id: z10.string().uuid(),
643
+ branchId: z10.string().uuid(),
644
+ academicYearId: z10.string().uuid(),
645
+ name: z10.string(),
646
+ startDate: z10.string(),
647
+ endDate: z10.string(),
648
+ isCurrent: z10.boolean(),
649
+ createdAt: z10.string()
650
+ });
651
+ var CreateTermInputSchema = z10.object({
652
+ academicYearId: z10.string().uuid(),
653
+ name: z10.string().min(1).max(50),
654
+ startDate: z10.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD"),
655
+ endDate: z10.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD")
656
+ });
657
+ var SetCurrentTermInputSchema = z10.object({
658
+ termId: z10.string().uuid()
659
+ });
660
+ var ListTermsInputSchema = z10.object({
661
+ yearId: z10.string().uuid().optional()
662
+ });
663
+
664
+ // src/contracts/calendar.ts
665
+ var listYearsContract = import_contract5.oc.route({ method: "GET", path: "/calendar/years" }).input(z11.object({})).output(z11.array(AcademicYearSchema));
666
+ var createYearContract = import_contract5.oc.route({ method: "POST", path: "/calendar/years" }).input(CreateYearInputSchema).output(AcademicYearSchema);
667
+ var setCurrentYearContract = import_contract5.oc.route({ method: "POST", path: "/calendar/years/current" }).input(SetCurrentYearInputSchema).output(AcademicYearSchema);
668
+ var calendarListTermsContract = import_contract5.oc.route({ method: "GET", path: "/calendar/terms" }).input(ListTermsInputSchema).output(z11.array(AcademicTermSchema));
669
+ var createTermContract = import_contract5.oc.route({ method: "POST", path: "/calendar/terms" }).input(CreateTermInputSchema).output(AcademicTermSchema);
670
+ var setCurrentTermContract = import_contract5.oc.route({ method: "POST", path: "/calendar/terms/current" }).input(SetCurrentTermInputSchema).output(AcademicTermSchema);
671
+ var calendarContract = {
672
+ listYears: listYearsContract,
673
+ createYear: createYearContract,
674
+ setCurrentYear: setCurrentYearContract,
675
+ listTerms: calendarListTermsContract,
676
+ createTerm: createTermContract,
677
+ setCurrentTerm: setCurrentTermContract
678
+ };
679
+
680
+ // src/contracts/grades.ts
681
+ var import_contract6 = require("@orpc/contract");
682
+ var z13 = __toESM(require("zod"), 1);
683
+
684
+ // src/schemas/grades.ts
685
+ var z12 = __toESM(require("zod"), 1);
686
+ var GradeSchema = z12.object({
687
+ id: z12.string().uuid(),
688
+ branchId: z12.string().uuid(),
689
+ name: z12.string(),
690
+ level: GradeLevelSchema,
691
+ description: z12.string().nullable()
692
+ });
693
+ var CreateGradeInputSchema = z12.object({
694
+ name: z12.string().min(1).max(50),
695
+ level: GradeLevelSchema,
696
+ description: z12.string().max(300).optional()
697
+ });
698
+
699
+ // src/contracts/grades.ts
700
+ var listGradesContract = import_contract6.oc.route({ method: "GET", path: "/grades" }).input(z13.object({})).output(z13.array(GradeSchema));
701
+ var createGradeContract = import_contract6.oc.route({ method: "POST", path: "/grades" }).input(CreateGradeInputSchema).output(GradeSchema);
702
+ var gradesContract = {
703
+ list: listGradesContract,
704
+ create: createGradeContract
705
+ };
649
706
  // Annotate the CommonJS export names for ESM import in node:
650
707
  0 && (module.exports = {
651
708
  attendanceContract,
652
709
  authContract,
653
710
  bulkUploadStudentsContract,
711
+ calendarContract,
712
+ calendarListTermsContract,
654
713
  changePasswordContract,
655
714
  createDepartmentContract,
715
+ createGradeContract,
656
716
  createStaffContract,
657
717
  createStudentContract,
718
+ createTermContract,
719
+ createYearContract,
658
720
  getByClassContract,
659
721
  getByStudentContract,
660
722
  getMeContract,
661
723
  getStaffByIdContract,
662
724
  getStudentByIdContract,
725
+ gradesContract,
663
726
  hrContract,
664
727
  linkGuardianContract,
665
728
  listClassesContract,
666
729
  listDepartmentsContract,
730
+ listGradesContract,
667
731
  listStaffContract,
668
732
  listStudentsContract,
669
733
  listTermsContract,
734
+ listYearsContract,
670
735
  loginContract,
671
736
  logoutContract,
672
737
  markAttendanceContract,
673
738
  refreshTokenContract,
674
739
  requestPasswordResetContract,
675
740
  resetPasswordContract,
741
+ setCurrentTermContract,
742
+ setCurrentYearContract,
676
743
  studentsContract,
677
744
  switchBranchContract,
678
745
  updateStaffStatusContract