@brite-future-schools-contracts/contracts 2.0.4 → 2.0.6
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/{chunk-S3BK5YEH.js → chunk-3IZCDZ2P.js} +29 -3
- package/dist/chunk-3IZCDZ2P.js.map +1 -0
- package/dist/{chunk-3OMU2YSE.js → chunk-7Q4RWA5S.js} +73 -2
- package/dist/chunk-7Q4RWA5S.js.map +1 -0
- package/dist/chunk-PDCM3NIB.js +1 -0
- package/dist/contracts/index.cjs +88 -0
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.d.cts +132 -1
- package/dist/contracts/index.d.ts +132 -1
- package/dist/contracts/index.js +12 -2
- package/dist/index.cjs +125 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.cjs +80 -0
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +105 -1
- package/dist/schemas/index.d.ts +105 -1
- package/dist/schemas/index.js +20 -2
- package/package.json +1 -1
- package/dist/chunk-3OMU2YSE.js.map +0 -1
- package/dist/chunk-R4XE3SFR.js +0 -1
- package/dist/chunk-S3BK5YEH.js.map +0 -1
- /package/dist/{chunk-R4XE3SFR.js.map → chunk-PDCM3NIB.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -30,11 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
AttendanceRecordInputSchema: () => AttendanceRecordInputSchema,
|
|
34
|
+
AttendanceStatusSchema: () => AttendanceStatusSchema,
|
|
33
35
|
BranchRefSchema: () => BranchRefSchema,
|
|
34
36
|
BulkUploadStudentRowSchema: () => BulkUploadStudentRowSchema,
|
|
35
37
|
BulkUploadStudentsInputSchema: () => BulkUploadStudentsInputSchema,
|
|
36
38
|
BulkUploadStudentsOutputSchema: () => BulkUploadStudentsOutputSchema,
|
|
37
39
|
ChangePasswordInputSchema: () => ChangePasswordInputSchema,
|
|
40
|
+
ClassAttendanceRowSchema: () => ClassAttendanceRowSchema,
|
|
38
41
|
ClassSummarySchema: () => ClassSummarySchema,
|
|
39
42
|
CreateDepartmentInputSchema: () => CreateDepartmentInputSchema,
|
|
40
43
|
CreateStaffInputSchema: () => CreateStaffInputSchema,
|
|
@@ -45,6 +48,8 @@ __export(src_exports, {
|
|
|
45
48
|
DepartmentSchema: () => DepartmentSchema,
|
|
46
49
|
EmploymentTypeSchema: () => EmploymentTypeSchema,
|
|
47
50
|
GenderSchema: () => GenderSchema,
|
|
51
|
+
GetByClassInputSchema: () => GetByClassInputSchema,
|
|
52
|
+
GetByStudentInputSchema: () => GetByStudentInputSchema,
|
|
48
53
|
GradeLevelSchema: () => GradeLevelSchema,
|
|
49
54
|
LinkGuardianInputSchema: () => LinkGuardianInputSchema,
|
|
50
55
|
ListStaffInputSchema: () => ListStaffInputSchema,
|
|
@@ -52,6 +57,8 @@ __export(src_exports, {
|
|
|
52
57
|
LoginInputSchema: () => LoginInputSchema,
|
|
53
58
|
LoginOutputSchema: () => LoginOutputSchema,
|
|
54
59
|
LogoutInputSchema: () => LogoutInputSchema,
|
|
60
|
+
MarkAttendanceInputSchema: () => MarkAttendanceInputSchema,
|
|
61
|
+
MarkAttendanceOutputSchema: () => MarkAttendanceOutputSchema,
|
|
55
62
|
PaginationInputSchema: () => PaginationInputSchema,
|
|
56
63
|
RefreshTokenInputSchema: () => RefreshTokenInputSchema,
|
|
57
64
|
RefreshTokenOutputSchema: () => RefreshTokenOutputSchema,
|
|
@@ -64,12 +71,15 @@ __export(src_exports, {
|
|
|
64
71
|
SoftDeleteSchema: () => SoftDeleteSchema,
|
|
65
72
|
StaffListItemSchema: () => StaffListItemSchema,
|
|
66
73
|
StaffProfileSchema: () => StaffProfileSchema,
|
|
74
|
+
StudentAttendanceRowSchema: () => StudentAttendanceRowSchema,
|
|
67
75
|
StudentListItemSchema: () => StudentListItemSchema,
|
|
68
76
|
StudentProfileSchema: () => StudentProfileSchema,
|
|
69
77
|
StudentStatusSchema: () => StudentStatusSchema,
|
|
70
78
|
SwitchBranchInputSchema: () => SwitchBranchInputSchema,
|
|
79
|
+
TermSchema: () => TermSchema,
|
|
71
80
|
TimestampsSchema: () => TimestampsSchema,
|
|
72
81
|
UuidSchema: () => UuidSchema,
|
|
82
|
+
attendanceContract: () => attendanceContract,
|
|
73
83
|
authContract: () => authContract,
|
|
74
84
|
bulkUploadStudentsContract: () => bulkUploadStudentsContract,
|
|
75
85
|
canAccessAdminDashboard: () => canAccessAdminDashboard,
|
|
@@ -85,6 +95,8 @@ __export(src_exports, {
|
|
|
85
95
|
createDepartmentContract: () => createDepartmentContract,
|
|
86
96
|
createStaffContract: () => createStaffContract,
|
|
87
97
|
createStudentContract: () => createStudentContract,
|
|
98
|
+
getByClassContract: () => getByClassContract,
|
|
99
|
+
getByStudentContract: () => getByStudentContract,
|
|
88
100
|
getMeContract: () => getMeContract,
|
|
89
101
|
getStaffByIdContract: () => getStaffByIdContract,
|
|
90
102
|
getStudentByIdContract: () => getStudentByIdContract,
|
|
@@ -123,8 +135,10 @@ __export(src_exports, {
|
|
|
123
135
|
listDepartmentsContract: () => listDepartmentsContract,
|
|
124
136
|
listStaffContract: () => listStaffContract,
|
|
125
137
|
listStudentsContract: () => listStudentsContract,
|
|
138
|
+
listTermsContract: () => listTermsContract,
|
|
126
139
|
loginContract: () => loginContract,
|
|
127
140
|
logoutContract: () => logoutContract,
|
|
141
|
+
markAttendanceContract: () => markAttendanceContract,
|
|
128
142
|
paginatedOutputSchema: () => paginatedOutputSchema,
|
|
129
143
|
refreshTokenContract: () => refreshTokenContract,
|
|
130
144
|
requestPasswordResetContract: () => requestPasswordResetContract,
|
|
@@ -569,10 +583,72 @@ var ClassSummarySchema = z4.object({
|
|
|
569
583
|
classTeacherId: UuidSchema.nullable()
|
|
570
584
|
});
|
|
571
585
|
|
|
586
|
+
// src/schemas/attendance.ts
|
|
587
|
+
var z5 = __toESM(require("zod"), 1);
|
|
588
|
+
var AttendanceStatusSchema = z5.enum([
|
|
589
|
+
"present",
|
|
590
|
+
"absent",
|
|
591
|
+
"late",
|
|
592
|
+
"excused"
|
|
593
|
+
]);
|
|
594
|
+
var TermSchema = z5.object({
|
|
595
|
+
id: UuidSchema,
|
|
596
|
+
branchId: UuidSchema,
|
|
597
|
+
academicYearId: UuidSchema,
|
|
598
|
+
name: z5.string(),
|
|
599
|
+
startDate: z5.string(),
|
|
600
|
+
endDate: z5.string(),
|
|
601
|
+
isCurrent: z5.boolean()
|
|
602
|
+
});
|
|
603
|
+
var AttendanceRecordInputSchema = z5.object({
|
|
604
|
+
studentId: UuidSchema,
|
|
605
|
+
status: AttendanceStatusSchema,
|
|
606
|
+
notes: z5.string().max(500).optional()
|
|
607
|
+
});
|
|
608
|
+
var MarkAttendanceInputSchema = z5.object({
|
|
609
|
+
classId: UuidSchema,
|
|
610
|
+
termId: UuidSchema,
|
|
611
|
+
date: z5.iso.date(),
|
|
612
|
+
records: z5.array(AttendanceRecordInputSchema).min(1)
|
|
613
|
+
});
|
|
614
|
+
var MarkAttendanceOutputSchema = z5.object({
|
|
615
|
+
count: z5.number(),
|
|
616
|
+
date: z5.string(),
|
|
617
|
+
classId: UuidSchema
|
|
618
|
+
});
|
|
619
|
+
var GetByClassInputSchema = z5.object({
|
|
620
|
+
classId: UuidSchema,
|
|
621
|
+
date: z5.iso.date()
|
|
622
|
+
});
|
|
623
|
+
var ClassAttendanceRowSchema = z5.object({
|
|
624
|
+
id: UuidSchema,
|
|
625
|
+
studentId: UuidSchema,
|
|
626
|
+
firstName: z5.string(),
|
|
627
|
+
middleName: z5.string().nullable(),
|
|
628
|
+
lastName: z5.string(),
|
|
629
|
+
admissionNo: z5.string(),
|
|
630
|
+
status: AttendanceStatusSchema,
|
|
631
|
+
notes: z5.string().nullable(),
|
|
632
|
+
markedBy: UuidSchema,
|
|
633
|
+
updatedAt: z5.string()
|
|
634
|
+
});
|
|
635
|
+
var GetByStudentInputSchema = z5.object({
|
|
636
|
+
studentId: UuidSchema,
|
|
637
|
+
termId: UuidSchema
|
|
638
|
+
});
|
|
639
|
+
var StudentAttendanceRowSchema = z5.object({
|
|
640
|
+
id: UuidSchema,
|
|
641
|
+
date: z5.string(),
|
|
642
|
+
status: AttendanceStatusSchema,
|
|
643
|
+
notes: z5.string().nullable(),
|
|
644
|
+
classId: UuidSchema,
|
|
645
|
+
className: z5.string()
|
|
646
|
+
});
|
|
647
|
+
|
|
572
648
|
// src/contracts/auth.ts
|
|
573
649
|
var import_contract = require("@orpc/contract");
|
|
574
|
-
var
|
|
575
|
-
var EmptyOutputSchema =
|
|
650
|
+
var z6 = __toESM(require("zod"), 1);
|
|
651
|
+
var EmptyOutputSchema = z6.object({}).meta({ description: "Empty success response" });
|
|
576
652
|
var loginContract = import_contract.oc.route({ method: "POST", path: "/auth/login" }).input(LoginInputSchema).output(LoginOutputSchema);
|
|
577
653
|
var refreshTokenContract = import_contract.oc.route({ method: "POST", path: "/auth/refresh" }).input(RefreshTokenInputSchema).output(RefreshTokenOutputSchema);
|
|
578
654
|
var logoutContract = import_contract.oc.route({ method: "POST", path: "/auth/logout" }).input(LogoutInputSchema).output(EmptyOutputSchema);
|
|
@@ -594,20 +670,20 @@ var authContract = {
|
|
|
594
670
|
|
|
595
671
|
// src/contracts/hr.ts
|
|
596
672
|
var import_contract2 = require("@orpc/contract");
|
|
597
|
-
var
|
|
598
|
-
var EmptyOutput =
|
|
673
|
+
var z7 = __toESM(require("zod"), 1);
|
|
674
|
+
var EmptyOutput = z7.object({});
|
|
599
675
|
var createStaffContract = import_contract2.oc.route({ method: "POST", path: "/hr/staff" }).input(CreateStaffInputSchema).output(CreateStaffOutputSchema);
|
|
600
|
-
var listStaffContract = import_contract2.oc.route({ method: "GET", path: "/hr/staff" }).input(ListStaffInputSchema).output(
|
|
601
|
-
items:
|
|
602
|
-
total:
|
|
676
|
+
var listStaffContract = import_contract2.oc.route({ method: "GET", path: "/hr/staff" }).input(ListStaffInputSchema).output(z7.object({
|
|
677
|
+
items: z7.array(StaffListItemSchema),
|
|
678
|
+
total: z7.number(),
|
|
603
679
|
nextCursor: UuidSchema.nullable()
|
|
604
680
|
}));
|
|
605
|
-
var getStaffByIdContract = import_contract2.oc.route({ method: "GET", path: "/hr/staff/{id}" }).input(
|
|
606
|
-
var updateStaffStatusContract = import_contract2.oc.route({ method: "PATCH", path: "/hr/staff/{id}/status" }).input(
|
|
681
|
+
var getStaffByIdContract = import_contract2.oc.route({ method: "GET", path: "/hr/staff/{id}" }).input(z7.object({ id: UuidSchema })).output(StaffProfileSchema);
|
|
682
|
+
var updateStaffStatusContract = import_contract2.oc.route({ method: "PATCH", path: "/hr/staff/{id}/status" }).input(z7.object({
|
|
607
683
|
id: UuidSchema,
|
|
608
|
-
status:
|
|
684
|
+
status: z7.enum(["active", "inactive", "suspended"])
|
|
609
685
|
})).output(EmptyOutput);
|
|
610
|
-
var listDepartmentsContract = import_contract2.oc.route({ method: "GET", path: "/hr/departments" }).input(
|
|
686
|
+
var listDepartmentsContract = import_contract2.oc.route({ method: "GET", path: "/hr/departments" }).input(z7.object({ branchId: UuidSchema.optional() })).output(z7.array(DepartmentSchema));
|
|
611
687
|
var createDepartmentContract = import_contract2.oc.route({ method: "POST", path: "/hr/departments" }).input(CreateDepartmentInputSchema).output(DepartmentSchema);
|
|
612
688
|
var hrContract = {
|
|
613
689
|
createStaff: createStaffContract,
|
|
@@ -620,21 +696,21 @@ var hrContract = {
|
|
|
620
696
|
|
|
621
697
|
// src/contracts/students.ts
|
|
622
698
|
var import_contract3 = require("@orpc/contract");
|
|
623
|
-
var
|
|
624
|
-
var EmptyOutput2 =
|
|
699
|
+
var z8 = __toESM(require("zod"), 1);
|
|
700
|
+
var EmptyOutput2 = z8.object({});
|
|
625
701
|
var createStudentContract = import_contract3.oc.route({ method: "POST", path: "/students" }).input(CreateStudentInputSchema).output(CreateStudentOutputSchema);
|
|
626
702
|
var bulkUploadStudentsContract = import_contract3.oc.route({ method: "POST", path: "/students/bulk" }).input(BulkUploadStudentsInputSchema).output(BulkUploadStudentsOutputSchema);
|
|
627
|
-
var listStudentsContract = import_contract3.oc.route({ method: "GET", path: "/students" }).input(ListStudentsInputSchema).output(
|
|
628
|
-
items:
|
|
629
|
-
total:
|
|
703
|
+
var listStudentsContract = import_contract3.oc.route({ method: "GET", path: "/students" }).input(ListStudentsInputSchema).output(z8.object({
|
|
704
|
+
items: z8.array(StudentListItemSchema),
|
|
705
|
+
total: z8.number(),
|
|
630
706
|
nextCursor: UuidSchema.nullable()
|
|
631
707
|
}));
|
|
632
|
-
var getStudentByIdContract = import_contract3.oc.route({ method: "GET", path: "/students/{id}" }).input(
|
|
633
|
-
var linkGuardianContract = import_contract3.oc.route({ method: "POST", path: "/students/guardians" }).input(LinkGuardianInputSchema).output(
|
|
634
|
-
var listClassesContract = import_contract3.oc.route({ method: "GET", path: "/students/classes" }).input(
|
|
708
|
+
var getStudentByIdContract = import_contract3.oc.route({ method: "GET", path: "/students/{id}" }).input(z8.object({ id: UuidSchema })).output(StudentProfileSchema);
|
|
709
|
+
var linkGuardianContract = import_contract3.oc.route({ method: "POST", path: "/students/guardians" }).input(LinkGuardianInputSchema).output(z8.object({ guardianId: UuidSchema }));
|
|
710
|
+
var listClassesContract = import_contract3.oc.route({ method: "GET", path: "/students/classes" }).input(z8.object({
|
|
635
711
|
termId: UuidSchema.optional(),
|
|
636
|
-
gradeLevel:
|
|
637
|
-
})).output(
|
|
712
|
+
gradeLevel: z8.string().optional()
|
|
713
|
+
})).output(z8.array(ClassSummarySchema));
|
|
638
714
|
var studentsContract = {
|
|
639
715
|
create: createStudentContract,
|
|
640
716
|
bulkUpload: bulkUploadStudentsContract,
|
|
@@ -644,6 +720,20 @@ var studentsContract = {
|
|
|
644
720
|
listClasses: listClassesContract
|
|
645
721
|
};
|
|
646
722
|
|
|
723
|
+
// src/contracts/attendance.ts
|
|
724
|
+
var import_contract4 = require("@orpc/contract");
|
|
725
|
+
var z9 = __toESM(require("zod"), 1);
|
|
726
|
+
var markAttendanceContract = import_contract4.oc.route({ method: "POST", path: "/attendance/class/mark" }).input(MarkAttendanceInputSchema).output(MarkAttendanceOutputSchema);
|
|
727
|
+
var getByClassContract = import_contract4.oc.route({ method: "GET", path: "/attendance/class" }).input(GetByClassInputSchema).output(z9.array(ClassAttendanceRowSchema));
|
|
728
|
+
var getByStudentContract = import_contract4.oc.route({ method: "GET", path: "/attendance/student" }).input(GetByStudentInputSchema).output(z9.array(StudentAttendanceRowSchema));
|
|
729
|
+
var listTermsContract = import_contract4.oc.route({ method: "GET", path: "/terms" }).input(z9.object({})).output(z9.array(TermSchema));
|
|
730
|
+
var attendanceContract = {
|
|
731
|
+
mark: markAttendanceContract,
|
|
732
|
+
getByClass: getByClassContract,
|
|
733
|
+
getByStudent: getByStudentContract,
|
|
734
|
+
listTerms: listTermsContract
|
|
735
|
+
};
|
|
736
|
+
|
|
647
737
|
// src/roles/helpers.ts
|
|
648
738
|
function hasRole(user, role) {
|
|
649
739
|
return user.roles.some(
|
|
@@ -795,11 +885,14 @@ function canAccessAdminDashboard(user) {
|
|
|
795
885
|
}
|
|
796
886
|
// Annotate the CommonJS export names for ESM import in node:
|
|
797
887
|
0 && (module.exports = {
|
|
888
|
+
AttendanceRecordInputSchema,
|
|
889
|
+
AttendanceStatusSchema,
|
|
798
890
|
BranchRefSchema,
|
|
799
891
|
BulkUploadStudentRowSchema,
|
|
800
892
|
BulkUploadStudentsInputSchema,
|
|
801
893
|
BulkUploadStudentsOutputSchema,
|
|
802
894
|
ChangePasswordInputSchema,
|
|
895
|
+
ClassAttendanceRowSchema,
|
|
803
896
|
ClassSummarySchema,
|
|
804
897
|
CreateDepartmentInputSchema,
|
|
805
898
|
CreateStaffInputSchema,
|
|
@@ -810,6 +903,8 @@ function canAccessAdminDashboard(user) {
|
|
|
810
903
|
DepartmentSchema,
|
|
811
904
|
EmploymentTypeSchema,
|
|
812
905
|
GenderSchema,
|
|
906
|
+
GetByClassInputSchema,
|
|
907
|
+
GetByStudentInputSchema,
|
|
813
908
|
GradeLevelSchema,
|
|
814
909
|
LinkGuardianInputSchema,
|
|
815
910
|
ListStaffInputSchema,
|
|
@@ -817,6 +912,8 @@ function canAccessAdminDashboard(user) {
|
|
|
817
912
|
LoginInputSchema,
|
|
818
913
|
LoginOutputSchema,
|
|
819
914
|
LogoutInputSchema,
|
|
915
|
+
MarkAttendanceInputSchema,
|
|
916
|
+
MarkAttendanceOutputSchema,
|
|
820
917
|
PaginationInputSchema,
|
|
821
918
|
RefreshTokenInputSchema,
|
|
822
919
|
RefreshTokenOutputSchema,
|
|
@@ -829,12 +926,15 @@ function canAccessAdminDashboard(user) {
|
|
|
829
926
|
SoftDeleteSchema,
|
|
830
927
|
StaffListItemSchema,
|
|
831
928
|
StaffProfileSchema,
|
|
929
|
+
StudentAttendanceRowSchema,
|
|
832
930
|
StudentListItemSchema,
|
|
833
931
|
StudentProfileSchema,
|
|
834
932
|
StudentStatusSchema,
|
|
835
933
|
SwitchBranchInputSchema,
|
|
934
|
+
TermSchema,
|
|
836
935
|
TimestampsSchema,
|
|
837
936
|
UuidSchema,
|
|
937
|
+
attendanceContract,
|
|
838
938
|
authContract,
|
|
839
939
|
bulkUploadStudentsContract,
|
|
840
940
|
canAccessAdminDashboard,
|
|
@@ -850,6 +950,8 @@ function canAccessAdminDashboard(user) {
|
|
|
850
950
|
createDepartmentContract,
|
|
851
951
|
createStaffContract,
|
|
852
952
|
createStudentContract,
|
|
953
|
+
getByClassContract,
|
|
954
|
+
getByStudentContract,
|
|
853
955
|
getMeContract,
|
|
854
956
|
getStaffByIdContract,
|
|
855
957
|
getStudentByIdContract,
|
|
@@ -888,8 +990,10 @@ function canAccessAdminDashboard(user) {
|
|
|
888
990
|
listDepartmentsContract,
|
|
889
991
|
listStaffContract,
|
|
890
992
|
listStudentsContract,
|
|
993
|
+
listTermsContract,
|
|
891
994
|
loginContract,
|
|
892
995
|
logoutContract,
|
|
996
|
+
markAttendanceContract,
|
|
893
997
|
paginatedOutputSchema,
|
|
894
998
|
refreshTokenContract,
|
|
895
999
|
requestPasswordResetContract,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/schemas/base.ts","../src/schemas/auth.ts","../src/schemas/hr.ts","../src/schemas/students.ts","../src/contracts/auth.ts","../src/contracts/hr.ts","../src/contracts/students.ts","../src/roles/helpers.ts","../src/permissions/index.ts"],"sourcesContent":["export * from './schemas'\nexport * from './contracts'\nexport * from './roles'\nexport * from './permissions'","/**\n * Brite Future Schools — bfs-contracts\n * Base Zod schemas: reusable primitives shared across all domain schemas.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/schemas/base\n * @since Phase 0.1\n */\n\nimport * as z from 'zod'\n\n// ── ID ─────────────────────────────────────────────────────────────────────────\n\nexport const CuidSchema = z\n .string()\n .regex(/^[a-z][a-z0-9]{24}$/, 'Invalid cuid2 identifier')\n .meta({ description: 'cuid2 — prefixed, collision-resistant identifier' })\n\n// ── UUID ───────────────────────────────────────────────────────────────────────\n\nexport const UuidSchema = z\n .uuidv4()\n .meta({ description: 'RFC-4122 UUID v4' })\n\n// ── Timestamps ─────────────────────────────────────────────────────────────────\n\nconst IsoDatetime = z.iso.datetime()\n\nexport const TimestampsSchema = z.object({\n createdAt: IsoDatetime.meta({ description: 'ISO-8601 creation time (UTC)' }),\n updatedAt: IsoDatetime.meta({ description: 'ISO-8601 last update time (UTC)' }),\n})\n\n// ── Soft-delete ────────────────────────────────────────────────────────────────\n\nexport const SoftDeleteSchema = z.object({\n deletedAt: IsoDatetime.nullable().meta({\n description: 'Set when the record is soft-deleted; null if active',\n }),\n})\n\n// ── Pagination ─────────────────────────────────────────────────────────────────\n\nexport const PaginationInputSchema = z.object({\n cursor: CuidSchema.optional().meta({\n description: 'Opaque cursor from the previous page response',\n }),\n limit: z\n .int()\n .min(1)\n .max(100)\n .default(20)\n .meta({ description: 'Number of items to return (1–100, default 20)' }),\n})\n\nexport function paginatedOutputSchema<T extends z.ZodTypeAny>(itemSchema: T) {\n return z.object({\n items: z.array(itemSchema),\n nextCursor: CuidSchema.nullable().meta({\n description: 'Pass as `cursor` on the next request; null when no more pages',\n }),\n total: z\n .int()\n .nonnegative()\n .meta({ description: 'Total matching records (before pagination)' }),\n })\n}\n\n// ── Branch reference ───────────────────────────────────────────────────────────\n\nexport const BranchRefSchema = z.object({\n branchId: CuidSchema.meta({ description: 'The branch this record belongs to' }),\n})\n\n// ── Inferred types ─────────────────────────────────────────────────────────────\n\nexport type Timestamps = z.infer<typeof TimestampsSchema>\nexport type SoftDelete = z.infer<typeof SoftDeleteSchema>\nexport type PaginationInput = z.infer<typeof PaginationInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * Auth-related Zod schemas.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/schemas/auth\n * @since Phase 0.1\n */\n\nimport * as z from 'zod'\nimport { CuidSchema } from './base.js'\n\n// ── Session user (defined first — referenced by LoginOutputSchema below) ───────\n\nexport const SessionUserRoleSchema = z.object({\n id: CuidSchema,\n name: z.string().meta({ description: 'Role name, e.g. PRINCIPAL' }),\n branchId: CuidSchema,\n isPrimary: z.boolean(),\n})\n\nexport const SessionUserSubRoleSchema = z.object({\n id: CuidSchema,\n name: z.string().meta({ description: 'Sub-role name, e.g. HEAD_PREFECT' }),\n branchId: CuidSchema,\n})\n\nexport const SessionUserOutputSchema = z.object({\n id: CuidSchema,\n email: z.email(),\n firstName: z.string(),\n lastName: z.string(),\n activeBranchId: CuidSchema,\n roles: z.array(SessionUserRoleSchema),\n subRoles: z.array(SessionUserSubRoleSchema),\n isActive: z.boolean(),\n mustChangePassword: z.boolean(),\n})\n\n// ── Login ──────────────────────────────────────────────────────────────────────\n\nexport const LoginInputSchema = z.object({\n email: z.email().meta({ description: 'User email address' }),\n password: z.string().min(1).meta({ description: 'Plain-text password (sent over TLS)' }),\n branchId: CuidSchema.optional().meta({\n description: 'Branch to activate on login; defaults to user primary branch',\n }),\n})\n\nexport const LoginOutputSchema = z.object({\n accessToken: z.string().meta({ description: 'Short-lived JWT (15 min)' }),\n refreshToken: z.string().meta({ description: 'Long-lived opaque refresh token (7 days)' }),\n expiresIn: z.int().positive().meta({ description: 'Access token TTL in seconds' }),\n user: SessionUserOutputSchema,\n})\n\n// ── Token refresh ──────────────────────────────────────────────────────────────\n\nexport const RefreshTokenInputSchema = z.object({\n refreshToken: z.string().min(1),\n})\n\nexport const RefreshTokenOutputSchema = z.object({\n accessToken: z.string(),\n expiresIn: z.int().positive(),\n})\n\n// ── Logout ─────────────────────────────────────────────────────────────────────\n\nexport const LogoutInputSchema = z.object({\n refreshToken: z.string().min(1).meta({\n description: 'The refresh token to revoke; also invalidated server-side',\n }),\n})\n\n// ── Password change ─────────────────────────────────────────────────────────────\n\nexport const ChangePasswordInputSchema = z\n .object({\n currentPassword: z.string().min(1),\n newPassword: z\n .string()\n .min(8, { error: 'Password must be at least 8 characters' }),\n confirmPassword: z.string().min(1),\n })\n .refine((v) => v.newPassword === v.confirmPassword, {\n error: 'Passwords do not match',\n path: ['confirmPassword'],\n })\n\n// ── Password reset ─────────────────────────────────────────────────────────────\n\nexport const RequestPasswordResetInputSchema = z.object({\n email: z.email(),\n})\n\nexport const ResetPasswordInputSchema = z\n .object({\n token: z.string().min(1).meta({ description: 'One-time reset token from email link' }),\n newPassword: z.string().min(8, { error: 'Password must be at least 8 characters' }),\n confirmPassword: z.string().min(1),\n })\n .refine((v) => v.newPassword === v.confirmPassword, {\n error: 'Passwords do not match',\n path: ['confirmPassword'],\n })\n\n// ── Branch switch ───────────────────────────────────────────────────────────────\n\nexport const SwitchBranchInputSchema = z.object({\n branchId: CuidSchema.meta({ description: 'Branch to switch the active session to' }),\n})\n\n// ── Inferred types ──────────────────────────────────────────────────────────────\n\nexport type LoginInput = z.infer<typeof LoginInputSchema>\nexport type LoginOutput = z.infer<typeof LoginOutputSchema>\nexport type SessionUserOutput = z.infer<typeof SessionUserOutputSchema>\nexport type RefreshTokenInput = z.infer<typeof RefreshTokenInputSchema>\nexport type RefreshTokenOutput = z.infer<typeof RefreshTokenOutputSchema>\nexport type ChangePasswordInput = z.infer<typeof ChangePasswordInputSchema>\nexport type SwitchBranchInput = z.infer<typeof SwitchBranchInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * HR domain Zod schemas — staff creation, listing, and profiles.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation — staff.create, staff.list,\n * staff.getById wire types\n *\n * @module src/schemas/hr\n * @since Phase 1\n */\n\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from './base.js'\n\n// ── Enums ──────────────────────────────────────────────────────────────────────\n\nexport const EmploymentTypeSchema = z.enum([\n 'permanent',\n 'contract',\n 'temporary',\n 'intern',\n])\n\nexport const RoleNameSchema = z.enum([\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 'STUDENT',\n 'PARENT',\n 'ORG_SPONSOR',\n 'INDIVIDUAL_SPONSOR',\n])\n\n// ── Create staff ───────────────────────────────────────────────────────────────\n\nexport const CreateStaffInputSchema = z.object({\n // Personal details\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n email: z.email(),\n phone: z.string().min(9).max(30),\n nationalId: z.string().min(1).max(20),\n\n // Role assignment\n roleName: RoleNameSchema.meta({\n description: 'System role to assign — determines dashboard access and permissions',\n }),\n isPrimaryRole: z.boolean().default(true),\n\n // Employment details\n departmentId: UuidSchema.optional(),\n designation: z.string().min(1).max(100).meta({\n description: 'Job title, e.g. \"Mathematics Teacher\", \"Head of Finance\"',\n }),\n employmentType: EmploymentTypeSchema,\n contractStart: z.iso.date().meta({ description: 'ISO date, e.g. 2026-01-15' }),\n contractEnd: z.iso.date().optional(),\n\n // Payroll\n basicSalary: z.number().positive(),\n houseAllowance: z.number().nonnegative().default(0),\n transportAllowance: z.number().nonnegative().default(0),\n helbDeduction: z.number().nonnegative().default(0),\n saccoDeduction: z.number().nonnegative().default(0),\n\n // Banking\n bankName: z.string().max(100).optional(),\n bankAccount: z.string().max(30).optional(),\n bankBranch: z.string().max(100).optional(),\n\n // Statutory\n tscNumber: z.string().max(30).optional(),\n kraPin: z.string().max(20).optional(),\n nhifNo: z.string().max(20).optional(),\n nssfNo: z.string().max(20).optional(),\n})\n\nexport type CreateStaffInput = z.infer<typeof CreateStaffInputSchema>\n\n// ── Staff profile (output) ─────────────────────────────────────────────────────\n\nexport const StaffProfileSchema = z.object({\n // Staff record\n id: UuidSchema,\n userId: UuidSchema,\n branchId: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n phone: z.string(),\n nationalId: z.string(),\n tscNumber: z.string().nullable(),\n kraPin: z.string().nullable(),\n nhifNo: z.string().nullable(),\n nssfNo: z.string().nullable(),\n designation: z.string(),\n employmentType: EmploymentTypeSchema,\n contractStart: z.string(),\n contractEnd: z.string().nullable(),\n basicSalary: z.string(),\n houseAllowance: z.string(),\n transportAllowance: z.string(),\n helbDeduction: z.string().nullable(),\n saccoDeduction: z.string().nullable(),\n bankName: z.string().nullable(),\n bankAccount: z.string().nullable(),\n bankBranch: z.string().nullable(),\n status: z.string(),\n createdAt: z.string(),\n\n // From users join\n email: z.string(),\n mustChangePassword: z.boolean(),\n\n // Department (nullable — not all staff are in a department)\n departmentId: UuidSchema.nullable(),\n departmentName: z.string().nullable(),\n\n // Primary role\n roleName: RoleNameSchema.nullable(),\n roleId: UuidSchema.nullable(),\n})\n\nexport type StaffProfile = z.infer<typeof StaffProfileSchema>\n\n// ── Staff list item (lighter than full profile) ────────────────────────────────\n\nexport const StaffListItemSchema = z.object({\n id: UuidSchema,\n userId: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n email: z.string(),\n phone: z.string(),\n designation: z.string(),\n employmentType: EmploymentTypeSchema,\n status: z.string(),\n departmentName: z.string().nullable(),\n roleName: RoleNameSchema.nullable(),\n createdAt: z.string(),\n})\n\nexport type StaffListItem = z.infer<typeof StaffListItemSchema>\n\n// ── List staff input ───────────────────────────────────────────────────────────\n\nexport const ListStaffInputSchema = PaginationInputSchema.extend({\n search: z.string().optional().meta({\n description: 'Search by name or email',\n }),\n departmentId: UuidSchema.optional(),\n roleName: RoleNameSchema.optional(),\n status: z.enum(['active', 'inactive']).optional(),\n})\n\nexport type ListStaffInput = z.infer<typeof ListStaffInputSchema>\n\n// ── Create staff output ────────────────────────────────────────────────────────\n\nexport const CreateStaffOutputSchema = z.object({\n staffId: UuidSchema,\n userId: UuidSchema,\n email: z.string(),\n /** Temp password was emailed — not returned in response for security */\n emailSent: z.boolean(),\n})\n\nexport type CreateStaffOutput = z.infer<typeof CreateStaffOutputSchema>\n\n// ── Department ─────────────────────────────────────────────────────────────────\n\nexport const DepartmentSchema = z.object({\n id: UuidSchema,\n branchId: UuidSchema,\n name: z.string(),\n hodId: UuidSchema.nullable(),\n})\n\nexport type Department = z.infer<typeof DepartmentSchema>\n\nexport const CreateDepartmentInputSchema = z.object({\n name: z.string().min(1).max(100),\n hodId: UuidSchema.optional(),\n})\n\nexport type CreateDepartmentInput = z.infer<typeof CreateDepartmentInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * Students domain Zod schemas.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation — student create, list,\n * bulk upload, guardian linkage\n *\n * @module src/schemas/students\n * @since Phase 1\n */\n\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from './base.js'\n\n// ── Enums ──────────────────────────────────────────────────────────────────────\n\nexport const GenderSchema = z.enum(['male', 'female'])\n\nexport const StudentStatusSchema = z.enum([\n 'active',\n 'transferred',\n 'graduated',\n 'suspended',\n 'withdrawn',\n])\n\nexport const GradeLevelSchema = z.enum([\n 'PP1', 'PP2',\n 'G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9',\n])\n\n// ── Create single student ──────────────────────────────────────────────────────\n\nexport const CreateStudentInputSchema = z.object({\n // Identity\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n dateOfBirth: z.iso.date().meta({ description: 'ISO date, e.g. 2015-03-22' }),\n gender: GenderSchema,\n admissionNo: z.string().min(1).max(50).meta({\n description: 'School-assigned admission number — must be unique per branch',\n }),\n nemisNo: z.string().max(50).optional(),\n admissionDate: z.iso.date(),\n bloodGroup: z.string().max(10).optional(),\n medicalNotes: z.string().optional(),\n\n // Class placement (optional at creation — can be enrolled later)\n classId: UuidSchema.optional().meta({\n description: 'Class to enrol student in for the current term',\n }),\n termId: UuidSchema.optional().meta({\n description: 'Term for class enrolment — required if classId is provided',\n }),\n\n // Guardian (optional at creation — can be linked later)\n guardian: z.object({\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n relationship: z.string().min(1).max(50).meta({\n description: 'e.g. mother, father, uncle, guardian',\n }),\n phone: z.string().min(9).max(30),\n email: z.email().optional(),\n nationalId: z.string().max(20).optional(),\n occupation: z.string().max(100).optional(),\n }).optional(),\n})\n\nexport type CreateStudentInput = z.infer<typeof CreateStudentInputSchema>\n\n// ── Student profile (output) ───────────────────────────────────────────────────\n\nexport const StudentProfileSchema = z.object({\n id: UuidSchema,\n branchId: UuidSchema,\n admissionNo: z.string(),\n nemisNo: z.string().nullable(),\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n dateOfBirth: z.string(),\n gender: GenderSchema,\n photoUrl: z.string().nullable(),\n bloodGroup: z.string().nullable(),\n medicalNotes: z.string().nullable(),\n admissionDate: z.string(),\n status: StudentStatusSchema,\n createdAt: z.string(),\n\n // Current class (from latest enrollment)\n currentClass: z.object({\n classId: UuidSchema,\n className: z.string(),\n gradeLevel: GradeLevelSchema,\n termId: UuidSchema,\n termName: z.string(),\n }).nullable(),\n\n // Guardians\n guardians: z.array(z.object({\n id: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n relationship: z.string(),\n phone: z.string(),\n email: z.string().nullable(),\n isPrimary: z.boolean(),\n })),\n})\n\nexport type StudentProfile = z.infer<typeof StudentProfileSchema>\n\n// ── Student list item ──────────────────────────────────────────────────────────\n\nexport const StudentListItemSchema = z.object({\n id: UuidSchema,\n admissionNo: z.string(),\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n gender: GenderSchema,\n status: StudentStatusSchema,\n className: z.string().nullable(),\n gradeLevel: GradeLevelSchema.nullable(),\n primaryGuardianName: z.string().nullable(),\n primaryGuardianPhone: z.string().nullable(),\n createdAt: z.string(),\n})\n\nexport type StudentListItem = z.infer<typeof StudentListItemSchema>\n\n// ── List students input ────────────────────────────────────────────────────────\n\nexport const ListStudentsInputSchema = PaginationInputSchema.extend({\n search: z.string().optional().meta({\n description: 'Search by name or admission number',\n }),\n classId: UuidSchema.optional(),\n gradeLevel: GradeLevelSchema.optional(),\n status: StudentStatusSchema.optional(),\n termId: UuidSchema.optional(),\n})\n\nexport type ListStudentsInput = z.infer<typeof ListStudentsInputSchema>\n\n// ── Bulk upload ────────────────────────────────────────────────────────────────\n\n/**\n * One row from a CSV bulk upload.\n * Column mapping is flexible — the upload endpoint accepts this shape\n * after the CSV parser maps headers to these field names.\n */\nexport const BulkUploadStudentRowSchema = z.object({\n firstName: z.string().min(1),\n middleName: z.string().optional(),\n lastName: z.string().min(1),\n dateOfBirth: z.string().min(1).meta({ description: 'Any parseable date string' }),\n gender: z.string().min(1).meta({ description: 'male | female (case-insensitive)' }),\n admissionNo: z.string().min(1),\n nemisNo: z.string().optional(),\n admissionDate: z.string().optional(),\n bloodGroup: z.string().optional(),\n\n // Guardian columns (all optional in CSV)\n guardianFirstName: z.string().optional(),\n guardianLastName: z.string().optional(),\n guardianRelationship: z.string().optional(),\n guardianPhone: z.string().optional(),\n guardianEmail: z.string().optional(),\n})\n\nexport type BulkUploadStudentRow = z.infer<typeof BulkUploadStudentRowSchema>\n\nexport const BulkUploadStudentsInputSchema = z.object({\n classId: UuidSchema.meta({\n description: 'Class to enrol all uploaded students into',\n }),\n termId: UuidSchema,\n rows: z.array(BulkUploadStudentRowSchema).min(1).max(500),\n})\n\nexport type BulkUploadStudentsInput = z.infer<typeof BulkUploadStudentsInputSchema>\n\nexport const BulkUploadStudentsOutputSchema = z.object({\n created: z.int().nonnegative(),\n skipped: z.int().nonnegative(),\n errors: z.array(z.object({\n row: z.int().positive(),\n admissionNo: z.string().optional(),\n reason: z.string(),\n })),\n})\n\nexport type BulkUploadStudentsOutput = z.infer<typeof BulkUploadStudentsOutputSchema>\n\n// ── Create student output ──────────────────────────────────────────────────────\n\nexport const CreateStudentOutputSchema = z.object({\n studentId: UuidSchema,\n admissionNo: z.string(),\n})\n\nexport type CreateStudentOutput = z.infer<typeof CreateStudentOutputSchema>\n\n// ── Link guardian ──────────────────────────────────────────────────────────────\n\nexport const LinkGuardianInputSchema = z.object({\n studentId: UuidSchema,\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n relationship: z.string().min(1).max(50),\n phone: z.string().min(9).max(30),\n email: z.email().optional(),\n nationalId: z.string().max(20).optional(),\n occupation: z.string().max(100).optional(),\n isPrimary: z.boolean().default(false),\n})\n\nexport type LinkGuardianInput = z.infer<typeof LinkGuardianInputSchema>\n\n// ── Classes (for selectors) ────────────────────────────────────────────────────\n\nexport const ClassSummarySchema = z.object({\n id: UuidSchema,\n name: z.string(),\n gradeLevel: GradeLevelSchema,\n gradeName: z.string(),\n capacity: z.number().nullable(),\n enrolledCount: z.number(),\n classTeacherId: UuidSchema.nullable(),\n})\n\nexport type ClassSummary = z.infer<typeof ClassSummarySchema>","/**\n * Brite Future Schools — bfs-contracts\n * Auth oRPC contract.\n *\n * Defines the API surface for authentication. The bfs-api module\n * imports this and passes it to `implement()` — no logic lives here.\n *\n * HTTP method + path pairs follow REST conventions and feed into the\n * OpenAPI spec that oRPC generates automatically.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/contracts/auth\n * @since Phase 0.1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport {\n ChangePasswordInputSchema,\n LoginInputSchema,\n LoginOutputSchema,\n LogoutInputSchema,\n RefreshTokenInputSchema,\n RefreshTokenOutputSchema,\n RequestPasswordResetInputSchema,\n ResetPasswordInputSchema,\n SessionUserOutputSchema,\n SwitchBranchInputSchema,\n} from '../schemas/auth.js'\n\n/** Reusable empty-success output — used by mutations that return nothing */\nconst EmptyOutputSchema = z.object({}).meta({ description: 'Empty success response' })\n\n// ── Individual procedure contracts ────────────────────────────────────────────\n\n/** Exchange email + password for access/refresh token pair */\nexport const loginContract = oc\n .route({ method: 'POST', path: '/auth/login' })\n .input(LoginInputSchema)\n .output(LoginOutputSchema)\n\n/** Exchange a refresh token for a new access token */\nexport const refreshTokenContract = oc\n .route({ method: 'POST', path: '/auth/refresh' })\n .input(RefreshTokenInputSchema)\n .output(RefreshTokenOutputSchema)\n\n/** Revoke the current refresh token and end the session */\nexport const logoutContract = oc\n .route({ method: 'POST', path: '/auth/logout' })\n .input(LogoutInputSchema)\n .output(EmptyOutputSchema)\n\n/** Return the session user object for the current access token */\nexport const getMeContract = oc\n .route({ method: 'GET', path: '/auth/me' })\n .output(SessionUserOutputSchema)\n\n/** Change password (authenticated, requires current password) */\nexport const changePasswordContract = oc\n .route({ method: 'POST', path: '/auth/change-password' })\n .input(ChangePasswordInputSchema)\n .output(EmptyOutputSchema)\n\n/** Request a password-reset email */\nexport const requestPasswordResetContract = oc\n .route({ method: 'POST', path: '/auth/request-password-reset' })\n .input(RequestPasswordResetInputSchema)\n .output(EmptyOutputSchema)\n\n/** Complete a password reset using the emailed one-time token */\nexport const resetPasswordContract = oc\n .route({ method: 'POST', path: '/auth/reset-password' })\n .input(ResetPasswordInputSchema)\n .output(EmptyOutputSchema)\n\n/** Switch the active branch within an existing session */\nexport const switchBranchContract = oc\n .route({ method: 'POST', path: '/auth/switch-branch' })\n .input(SwitchBranchInputSchema)\n .output(SessionUserOutputSchema)\n\n// ── Auth contract router ──────────────────────────────────────────────────────\n\nexport const authContract = {\n login: loginContract,\n refreshToken: refreshTokenContract,\n logout: logoutContract,\n me: getMeContract,\n changePassword: changePasswordContract,\n requestPasswordReset: requestPasswordResetContract,\n resetPassword: resetPasswordContract,\n switchBranch: switchBranchContract,\n}\n","/**\n * Brite Future Schools — bfs-contracts\n * HR oRPC contract — staff and department procedure definitions.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation\n *\n * @module src/contracts/hr\n * @since Phase 1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from '../schemas/base.js'\nimport {\n CreateStaffInputSchema,\n CreateStaffOutputSchema,\n StaffProfileSchema,\n StaffListItemSchema,\n ListStaffInputSchema,\n DepartmentSchema,\n CreateDepartmentInputSchema,\n} from '../schemas/hr.js'\n\nconst EmptyOutput = z.object({})\n\n// ── Staff ──────────────────────────────────────────────────────────────────────\n\nexport const createStaffContract = oc\n .route({ method: 'POST', path: '/hr/staff' })\n .input(CreateStaffInputSchema)\n .output(CreateStaffOutputSchema)\n\nexport const listStaffContract = oc\n .route({ method: 'GET', path: '/hr/staff' })\n .input(ListStaffInputSchema)\n .output(z.object({\n items: z.array(StaffListItemSchema),\n total: z.number(),\n nextCursor: UuidSchema.nullable(),\n }))\n\nexport const getStaffByIdContract = oc\n .route({ method: 'GET', path: '/hr/staff/{id}' })\n .input(z.object({ id: UuidSchema }))\n .output(StaffProfileSchema)\n\nexport const updateStaffStatusContract = oc\n .route({ method: 'PATCH', path: '/hr/staff/{id}/status' })\n .input(z.object({\n id: UuidSchema,\n status: z.enum(['active', 'inactive', 'suspended']),\n }))\n .output(EmptyOutput)\n\n// ── Departments ────────────────────────────────────────────────────────────────\n\nexport const listDepartmentsContract = oc\n .route({ method: 'GET', path: '/hr/departments' })\n .input(z.object({ branchId: UuidSchema.optional() }))\n .output(z.array(DepartmentSchema))\n\nexport const createDepartmentContract = oc\n .route({ method: 'POST', path: '/hr/departments' })\n .input(CreateDepartmentInputSchema)\n .output(DepartmentSchema)\n\n// ── HR contract router ─────────────────────────────────────────────────────────\n\nexport const hrContract = {\n createStaff: createStaffContract,\n listStaff: listStaffContract,\n getStaffById: getStaffByIdContract,\n updateStaffStatus: updateStaffStatusContract,\n listDepartments: listDepartmentsContract,\n createDepartment: createDepartmentContract,\n}","/**\n * Brite Future Schools — bfs-contracts\n * Students oRPC contract — student and guardian procedure definitions.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation\n *\n * @module src/contracts/students\n * @since Phase 1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport { UuidSchema } from '../schemas/base.js'\nimport {\n CreateStudentInputSchema,\n CreateStudentOutputSchema,\n StudentProfileSchema,\n StudentListItemSchema,\n ListStudentsInputSchema,\n BulkUploadStudentsInputSchema,\n BulkUploadStudentsOutputSchema,\n LinkGuardianInputSchema,\n ClassSummarySchema,\n} from '../schemas/students.js'\n\nconst EmptyOutput = z.object({})\n\n// ── Students ───────────────────────────────────────────────────────────────────\n\nexport const createStudentContract = oc\n .route({ method: 'POST', path: '/students' })\n .input(CreateStudentInputSchema)\n .output(CreateStudentOutputSchema)\n\nexport const bulkUploadStudentsContract = oc\n .route({ method: 'POST', path: '/students/bulk' })\n .input(BulkUploadStudentsInputSchema)\n .output(BulkUploadStudentsOutputSchema)\n\nexport const listStudentsContract = oc\n .route({ method: 'GET', path: '/students' })\n .input(ListStudentsInputSchema)\n .output(z.object({\n items: z.array(StudentListItemSchema),\n total: z.number(),\n nextCursor: UuidSchema.nullable(),\n }))\n\nexport const getStudentByIdContract = oc\n .route({ method: 'GET', path: '/students/{id}' })\n .input(z.object({ id: UuidSchema }))\n .output(StudentProfileSchema)\n\n// ── Guardians ──────────────────────────────────────────────────────────────────\n\nexport const linkGuardianContract = oc\n .route({ method: 'POST', path: '/students/guardians' })\n .input(LinkGuardianInputSchema)\n .output(z.object({ guardianId: UuidSchema }))\n\n// ── Classes (selector data) ────────────────────────────────────────────────────\n\nexport const listClassesContract = oc\n .route({ method: 'GET', path: '/students/classes' })\n .input(z.object({\n termId: UuidSchema.optional(),\n gradeLevel: z.string().optional(),\n }))\n .output(z.array(ClassSummarySchema))\n\n// ── Students contract router ───────────────────────────────────────────────────\n\nexport const studentsContract = {\n create: createStudentContract,\n bulkUpload: bulkUploadStudentsContract,\n list: listStudentsContract,\n getById: getStudentByIdContract,\n linkGuardian: linkGuardianContract,\n listClasses: listClassesContract,\n}","/**\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 *\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// ── 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":["z","z","z","z","import_contract","z","import_contract","z","EmptyOutput"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/schemas/base.ts","../src/schemas/auth.ts","../src/schemas/hr.ts","../src/schemas/students.ts","../src/schemas/attendance.ts","../src/contracts/auth.ts","../src/contracts/hr.ts","../src/contracts/students.ts","../src/contracts/attendance.ts","../src/roles/helpers.ts","../src/permissions/index.ts"],"sourcesContent":["export * from './schemas'\nexport * from './contracts'\nexport * from './roles'\nexport * from './permissions'","/**\n * Brite Future Schools — bfs-contracts\n * Base Zod schemas: reusable primitives shared across all domain schemas.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/schemas/base\n * @since Phase 0.1\n */\n\nimport * as z from 'zod'\n\n// ── ID ─────────────────────────────────────────────────────────────────────────\n\nexport const CuidSchema = z\n .string()\n .regex(/^[a-z][a-z0-9]{24}$/, 'Invalid cuid2 identifier')\n .meta({ description: 'cuid2 — prefixed, collision-resistant identifier' })\n\n// ── UUID ───────────────────────────────────────────────────────────────────────\n\nexport const UuidSchema = z\n .uuidv4()\n .meta({ description: 'RFC-4122 UUID v4' })\n\n// ── Timestamps ─────────────────────────────────────────────────────────────────\n\nconst IsoDatetime = z.iso.datetime()\n\nexport const TimestampsSchema = z.object({\n createdAt: IsoDatetime.meta({ description: 'ISO-8601 creation time (UTC)' }),\n updatedAt: IsoDatetime.meta({ description: 'ISO-8601 last update time (UTC)' }),\n})\n\n// ── Soft-delete ────────────────────────────────────────────────────────────────\n\nexport const SoftDeleteSchema = z.object({\n deletedAt: IsoDatetime.nullable().meta({\n description: 'Set when the record is soft-deleted; null if active',\n }),\n})\n\n// ── Pagination ─────────────────────────────────────────────────────────────────\n\nexport const PaginationInputSchema = z.object({\n cursor: CuidSchema.optional().meta({\n description: 'Opaque cursor from the previous page response',\n }),\n limit: z\n .int()\n .min(1)\n .max(100)\n .default(20)\n .meta({ description: 'Number of items to return (1–100, default 20)' }),\n})\n\nexport function paginatedOutputSchema<T extends z.ZodTypeAny>(itemSchema: T) {\n return z.object({\n items: z.array(itemSchema),\n nextCursor: CuidSchema.nullable().meta({\n description: 'Pass as `cursor` on the next request; null when no more pages',\n }),\n total: z\n .int()\n .nonnegative()\n .meta({ description: 'Total matching records (before pagination)' }),\n })\n}\n\n// ── Branch reference ───────────────────────────────────────────────────────────\n\nexport const BranchRefSchema = z.object({\n branchId: CuidSchema.meta({ description: 'The branch this record belongs to' }),\n})\n\n// ── Inferred types ─────────────────────────────────────────────────────────────\n\nexport type Timestamps = z.infer<typeof TimestampsSchema>\nexport type SoftDelete = z.infer<typeof SoftDeleteSchema>\nexport type PaginationInput = z.infer<typeof PaginationInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * Auth-related Zod schemas.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/schemas/auth\n * @since Phase 0.1\n */\n\nimport * as z from 'zod'\nimport { CuidSchema } from './base.js'\n\n// ── Session user (defined first — referenced by LoginOutputSchema below) ───────\n\nexport const SessionUserRoleSchema = z.object({\n id: CuidSchema,\n name: z.string().meta({ description: 'Role name, e.g. PRINCIPAL' }),\n branchId: CuidSchema,\n isPrimary: z.boolean(),\n})\n\nexport const SessionUserSubRoleSchema = z.object({\n id: CuidSchema,\n name: z.string().meta({ description: 'Sub-role name, e.g. HEAD_PREFECT' }),\n branchId: CuidSchema,\n})\n\nexport const SessionUserOutputSchema = z.object({\n id: CuidSchema,\n email: z.email(),\n firstName: z.string(),\n lastName: z.string(),\n activeBranchId: CuidSchema,\n roles: z.array(SessionUserRoleSchema),\n subRoles: z.array(SessionUserSubRoleSchema),\n isActive: z.boolean(),\n mustChangePassword: z.boolean(),\n})\n\n// ── Login ──────────────────────────────────────────────────────────────────────\n\nexport const LoginInputSchema = z.object({\n email: z.email().meta({ description: 'User email address' }),\n password: z.string().min(1).meta({ description: 'Plain-text password (sent over TLS)' }),\n branchId: CuidSchema.optional().meta({\n description: 'Branch to activate on login; defaults to user primary branch',\n }),\n})\n\nexport const LoginOutputSchema = z.object({\n accessToken: z.string().meta({ description: 'Short-lived JWT (15 min)' }),\n refreshToken: z.string().meta({ description: 'Long-lived opaque refresh token (7 days)' }),\n expiresIn: z.int().positive().meta({ description: 'Access token TTL in seconds' }),\n user: SessionUserOutputSchema,\n})\n\n// ── Token refresh ──────────────────────────────────────────────────────────────\n\nexport const RefreshTokenInputSchema = z.object({\n refreshToken: z.string().min(1),\n})\n\nexport const RefreshTokenOutputSchema = z.object({\n accessToken: z.string(),\n expiresIn: z.int().positive(),\n})\n\n// ── Logout ─────────────────────────────────────────────────────────────────────\n\nexport const LogoutInputSchema = z.object({\n refreshToken: z.string().min(1).meta({\n description: 'The refresh token to revoke; also invalidated server-side',\n }),\n})\n\n// ── Password change ─────────────────────────────────────────────────────────────\n\nexport const ChangePasswordInputSchema = z\n .object({\n currentPassword: z.string().min(1),\n newPassword: z\n .string()\n .min(8, { error: 'Password must be at least 8 characters' }),\n confirmPassword: z.string().min(1),\n })\n .refine((v) => v.newPassword === v.confirmPassword, {\n error: 'Passwords do not match',\n path: ['confirmPassword'],\n })\n\n// ── Password reset ─────────────────────────────────────────────────────────────\n\nexport const RequestPasswordResetInputSchema = z.object({\n email: z.email(),\n})\n\nexport const ResetPasswordInputSchema = z\n .object({\n token: z.string().min(1).meta({ description: 'One-time reset token from email link' }),\n newPassword: z.string().min(8, { error: 'Password must be at least 8 characters' }),\n confirmPassword: z.string().min(1),\n })\n .refine((v) => v.newPassword === v.confirmPassword, {\n error: 'Passwords do not match',\n path: ['confirmPassword'],\n })\n\n// ── Branch switch ───────────────────────────────────────────────────────────────\n\nexport const SwitchBranchInputSchema = z.object({\n branchId: CuidSchema.meta({ description: 'Branch to switch the active session to' }),\n})\n\n// ── Inferred types ──────────────────────────────────────────────────────────────\n\nexport type LoginInput = z.infer<typeof LoginInputSchema>\nexport type LoginOutput = z.infer<typeof LoginOutputSchema>\nexport type SessionUserOutput = z.infer<typeof SessionUserOutputSchema>\nexport type RefreshTokenInput = z.infer<typeof RefreshTokenInputSchema>\nexport type RefreshTokenOutput = z.infer<typeof RefreshTokenOutputSchema>\nexport type ChangePasswordInput = z.infer<typeof ChangePasswordInputSchema>\nexport type SwitchBranchInput = z.infer<typeof SwitchBranchInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * HR domain Zod schemas — staff creation, listing, and profiles.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation — staff.create, staff.list,\n * staff.getById wire types\n *\n * @module src/schemas/hr\n * @since Phase 1\n */\n\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from './base.js'\n\n// ── Enums ──────────────────────────────────────────────────────────────────────\n\nexport const EmploymentTypeSchema = z.enum([\n 'permanent',\n 'contract',\n 'temporary',\n 'intern',\n])\n\nexport const RoleNameSchema = z.enum([\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 'STUDENT',\n 'PARENT',\n 'ORG_SPONSOR',\n 'INDIVIDUAL_SPONSOR',\n])\n\n// ── Create staff ───────────────────────────────────────────────────────────────\n\nexport const CreateStaffInputSchema = z.object({\n // Personal details\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n email: z.email(),\n phone: z.string().min(9).max(30),\n nationalId: z.string().min(1).max(20),\n\n // Role assignment\n roleName: RoleNameSchema.meta({\n description: 'System role to assign — determines dashboard access and permissions',\n }),\n isPrimaryRole: z.boolean().default(true),\n\n // Employment details\n departmentId: UuidSchema.optional(),\n designation: z.string().min(1).max(100).meta({\n description: 'Job title, e.g. \"Mathematics Teacher\", \"Head of Finance\"',\n }),\n employmentType: EmploymentTypeSchema,\n contractStart: z.iso.date().meta({ description: 'ISO date, e.g. 2026-01-15' }),\n contractEnd: z.iso.date().optional(),\n\n // Payroll\n basicSalary: z.number().positive(),\n houseAllowance: z.number().nonnegative().default(0),\n transportAllowance: z.number().nonnegative().default(0),\n helbDeduction: z.number().nonnegative().default(0),\n saccoDeduction: z.number().nonnegative().default(0),\n\n // Banking\n bankName: z.string().max(100).optional(),\n bankAccount: z.string().max(30).optional(),\n bankBranch: z.string().max(100).optional(),\n\n // Statutory\n tscNumber: z.string().max(30).optional(),\n kraPin: z.string().max(20).optional(),\n nhifNo: z.string().max(20).optional(),\n nssfNo: z.string().max(20).optional(),\n})\n\nexport type CreateStaffInput = z.infer<typeof CreateStaffInputSchema>\n\n// ── Staff profile (output) ─────────────────────────────────────────────────────\n\nexport const StaffProfileSchema = z.object({\n // Staff record\n id: UuidSchema,\n userId: UuidSchema,\n branchId: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n phone: z.string(),\n nationalId: z.string(),\n tscNumber: z.string().nullable(),\n kraPin: z.string().nullable(),\n nhifNo: z.string().nullable(),\n nssfNo: z.string().nullable(),\n designation: z.string(),\n employmentType: EmploymentTypeSchema,\n contractStart: z.string(),\n contractEnd: z.string().nullable(),\n basicSalary: z.string(),\n houseAllowance: z.string(),\n transportAllowance: z.string(),\n helbDeduction: z.string().nullable(),\n saccoDeduction: z.string().nullable(),\n bankName: z.string().nullable(),\n bankAccount: z.string().nullable(),\n bankBranch: z.string().nullable(),\n status: z.string(),\n createdAt: z.string(),\n\n // From users join\n email: z.string(),\n mustChangePassword: z.boolean(),\n\n // Department (nullable — not all staff are in a department)\n departmentId: UuidSchema.nullable(),\n departmentName: z.string().nullable(),\n\n // Primary role\n roleName: RoleNameSchema.nullable(),\n roleId: UuidSchema.nullable(),\n})\n\nexport type StaffProfile = z.infer<typeof StaffProfileSchema>\n\n// ── Staff list item (lighter than full profile) ────────────────────────────────\n\nexport const StaffListItemSchema = z.object({\n id: UuidSchema,\n userId: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n email: z.string(),\n phone: z.string(),\n designation: z.string(),\n employmentType: EmploymentTypeSchema,\n status: z.string(),\n departmentName: z.string().nullable(),\n roleName: RoleNameSchema.nullable(),\n createdAt: z.string(),\n})\n\nexport type StaffListItem = z.infer<typeof StaffListItemSchema>\n\n// ── List staff input ───────────────────────────────────────────────────────────\n\nexport const ListStaffInputSchema = PaginationInputSchema.extend({\n search: z.string().optional().meta({\n description: 'Search by name or email',\n }),\n departmentId: UuidSchema.optional(),\n roleName: RoleNameSchema.optional(),\n status: z.enum(['active', 'inactive']).optional(),\n})\n\nexport type ListStaffInput = z.infer<typeof ListStaffInputSchema>\n\n// ── Create staff output ────────────────────────────────────────────────────────\n\nexport const CreateStaffOutputSchema = z.object({\n staffId: UuidSchema,\n userId: UuidSchema,\n email: z.string(),\n /** Temp password was emailed — not returned in response for security */\n emailSent: z.boolean(),\n})\n\nexport type CreateStaffOutput = z.infer<typeof CreateStaffOutputSchema>\n\n// ── Department ─────────────────────────────────────────────────────────────────\n\nexport const DepartmentSchema = z.object({\n id: UuidSchema,\n branchId: UuidSchema,\n name: z.string(),\n hodId: UuidSchema.nullable(),\n})\n\nexport type Department = z.infer<typeof DepartmentSchema>\n\nexport const CreateDepartmentInputSchema = z.object({\n name: z.string().min(1).max(100),\n hodId: UuidSchema.optional(),\n})\n\nexport type CreateDepartmentInput = z.infer<typeof CreateDepartmentInputSchema>","/**\n * Brite Future Schools — bfs-contracts\n * Students domain Zod schemas.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation — student create, list,\n * bulk upload, guardian linkage\n *\n * @module src/schemas/students\n * @since Phase 1\n */\n\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from './base.js'\n\n// ── Enums ──────────────────────────────────────────────────────────────────────\n\nexport const GenderSchema = z.enum(['male', 'female'])\n\nexport const StudentStatusSchema = z.enum([\n 'active',\n 'transferred',\n 'graduated',\n 'suspended',\n 'withdrawn',\n])\n\nexport const GradeLevelSchema = z.enum([\n 'PP1', 'PP2',\n 'G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9',\n])\n\n// ── Create single student ──────────────────────────────────────────────────────\n\nexport const CreateStudentInputSchema = z.object({\n // Identity\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n dateOfBirth: z.iso.date().meta({ description: 'ISO date, e.g. 2015-03-22' }),\n gender: GenderSchema,\n admissionNo: z.string().min(1).max(50).meta({\n description: 'School-assigned admission number — must be unique per branch',\n }),\n nemisNo: z.string().max(50).optional(),\n admissionDate: z.iso.date(),\n bloodGroup: z.string().max(10).optional(),\n medicalNotes: z.string().optional(),\n\n // Class placement (optional at creation — can be enrolled later)\n classId: UuidSchema.optional().meta({\n description: 'Class to enrol student in for the current term',\n }),\n termId: UuidSchema.optional().meta({\n description: 'Term for class enrolment — required if classId is provided',\n }),\n\n // Guardian (optional at creation — can be linked later)\n guardian: z.object({\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n relationship: z.string().min(1).max(50).meta({\n description: 'e.g. mother, father, uncle, guardian',\n }),\n phone: z.string().min(9).max(30),\n email: z.email().optional(),\n nationalId: z.string().max(20).optional(),\n occupation: z.string().max(100).optional(),\n }).optional(),\n})\n\nexport type CreateStudentInput = z.infer<typeof CreateStudentInputSchema>\n\n// ── Student profile (output) ───────────────────────────────────────────────────\n\nexport const StudentProfileSchema = z.object({\n id: UuidSchema,\n branchId: UuidSchema,\n admissionNo: z.string(),\n nemisNo: z.string().nullable(),\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n dateOfBirth: z.string(),\n gender: GenderSchema,\n photoUrl: z.string().nullable(),\n bloodGroup: z.string().nullable(),\n medicalNotes: z.string().nullable(),\n admissionDate: z.string(),\n status: StudentStatusSchema,\n createdAt: z.string(),\n\n // Current class (from latest enrollment)\n currentClass: z.object({\n classId: UuidSchema,\n className: z.string(),\n gradeLevel: GradeLevelSchema,\n termId: UuidSchema,\n termName: z.string(),\n }).nullable(),\n\n // Guardians\n guardians: z.array(z.object({\n id: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n relationship: z.string(),\n phone: z.string(),\n email: z.string().nullable(),\n isPrimary: z.boolean(),\n })),\n})\n\nexport type StudentProfile = z.infer<typeof StudentProfileSchema>\n\n// ── Student list item ──────────────────────────────────────────────────────────\n\nexport const StudentListItemSchema = z.object({\n id: UuidSchema,\n admissionNo: z.string(),\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n gender: GenderSchema,\n status: StudentStatusSchema,\n className: z.string().nullable(),\n gradeLevel: GradeLevelSchema.nullable(),\n primaryGuardianName: z.string().nullable(),\n primaryGuardianPhone: z.string().nullable(),\n createdAt: z.string(),\n})\n\nexport type StudentListItem = z.infer<typeof StudentListItemSchema>\n\n// ── List students input ────────────────────────────────────────────────────────\n\nexport const ListStudentsInputSchema = PaginationInputSchema.extend({\n search: z.string().optional().meta({\n description: 'Search by name or admission number',\n }),\n classId: UuidSchema.optional(),\n gradeLevel: GradeLevelSchema.optional(),\n status: StudentStatusSchema.optional(),\n termId: UuidSchema.optional(),\n})\n\nexport type ListStudentsInput = z.infer<typeof ListStudentsInputSchema>\n\n// ── Bulk upload ────────────────────────────────────────────────────────────────\n\n/**\n * One row from a CSV bulk upload.\n * Column mapping is flexible — the upload endpoint accepts this shape\n * after the CSV parser maps headers to these field names.\n */\nexport const BulkUploadStudentRowSchema = z.object({\n firstName: z.string().min(1),\n middleName: z.string().optional(),\n lastName: z.string().min(1),\n dateOfBirth: z.string().min(1).meta({ description: 'Any parseable date string' }),\n gender: z.string().min(1).meta({ description: 'male | female (case-insensitive)' }),\n admissionNo: z.string().min(1),\n nemisNo: z.string().optional(),\n admissionDate: z.string().optional(),\n bloodGroup: z.string().optional(),\n\n // Guardian columns (all optional in CSV)\n guardianFirstName: z.string().optional(),\n guardianLastName: z.string().optional(),\n guardianRelationship: z.string().optional(),\n guardianPhone: z.string().optional(),\n guardianEmail: z.string().optional(),\n})\n\nexport type BulkUploadStudentRow = z.infer<typeof BulkUploadStudentRowSchema>\n\nexport const BulkUploadStudentsInputSchema = z.object({\n classId: UuidSchema.meta({\n description: 'Class to enrol all uploaded students into',\n }),\n termId: UuidSchema,\n rows: z.array(BulkUploadStudentRowSchema).min(1).max(500),\n})\n\nexport type BulkUploadStudentsInput = z.infer<typeof BulkUploadStudentsInputSchema>\n\nexport const BulkUploadStudentsOutputSchema = z.object({\n created: z.int().nonnegative(),\n skipped: z.int().nonnegative(),\n errors: z.array(z.object({\n row: z.int().positive(),\n admissionNo: z.string().optional(),\n reason: z.string(),\n })),\n})\n\nexport type BulkUploadStudentsOutput = z.infer<typeof BulkUploadStudentsOutputSchema>\n\n// ── Create student output ──────────────────────────────────────────────────────\n\nexport const CreateStudentOutputSchema = z.object({\n studentId: UuidSchema,\n admissionNo: z.string(),\n})\n\nexport type CreateStudentOutput = z.infer<typeof CreateStudentOutputSchema>\n\n// ── Link guardian ──────────────────────────────────────────────────────────────\n\nexport const LinkGuardianInputSchema = z.object({\n studentId: UuidSchema,\n firstName: z.string().min(1).max(100),\n middleName: z.string().max(100).optional(),\n lastName: z.string().min(1).max(100),\n relationship: z.string().min(1).max(50),\n phone: z.string().min(9).max(30),\n email: z.email().optional(),\n nationalId: z.string().max(20).optional(),\n occupation: z.string().max(100).optional(),\n isPrimary: z.boolean().default(false),\n})\n\nexport type LinkGuardianInput = z.infer<typeof LinkGuardianInputSchema>\n\n// ── Classes (for selectors) ────────────────────────────────────────────────────\n\nexport const ClassSummarySchema = z.object({\n id: UuidSchema,\n name: z.string(),\n gradeLevel: GradeLevelSchema,\n gradeName: z.string(),\n capacity: z.number().nullable(),\n enrolledCount: z.number(),\n classTeacherId: UuidSchema.nullable(),\n})\n\nexport type ClassSummary = z.infer<typeof ClassSummarySchema>","/**\n * Brite Future Schools — bfs-contracts\n * Attendance domain Zod schemas.\n *\n * Phase History:\n * Phase 2.1 (2026-06-08): Initial — class attendance mark, getByClass,\n * getByStudent, listTerms\n *\n * @module src/schemas/attendance\n * @since Phase 2.1\n */\n\nimport * as z from 'zod'\nimport { UuidSchema } from './base.js'\n\n// ── Enums ──────────────────────────────────────────────────────────────────────\n\nexport const AttendanceStatusSchema = z.enum([\n 'present',\n 'absent',\n 'late',\n 'excused',\n])\n\nexport type AttendanceStatusEnum = z.infer<typeof AttendanceStatusSchema>\n\n// ── Term ───────────────────────────────────────────────────────────────────────\n\nexport const TermSchema = z.object({\n id: UuidSchema,\n branchId: UuidSchema,\n academicYearId: UuidSchema,\n name: z.string(),\n startDate: z.string(),\n endDate: z.string(),\n isCurrent: z.boolean(),\n})\n\nexport type Term = z.infer<typeof TermSchema>\n\n// ── Mark attendance ────────────────────────────────────────────────────────────\n\nexport const AttendanceRecordInputSchema = z.object({\n studentId: UuidSchema,\n status: AttendanceStatusSchema,\n notes: z.string().max(500).optional(),\n})\n\nexport const MarkAttendanceInputSchema = z.object({\n classId: UuidSchema,\n termId: UuidSchema,\n date: z.iso.date(),\n records: z.array(AttendanceRecordInputSchema).min(1),\n})\n\nexport type MarkAttendanceInput = z.infer<typeof MarkAttendanceInputSchema>\n\nexport const MarkAttendanceOutputSchema = z.object({\n count: z.number(),\n date: z.string(),\n classId: UuidSchema,\n})\n\nexport type MarkAttendanceOutput = z.infer<typeof MarkAttendanceOutputSchema>\n\n// ── Get by class ───────────────────────────────────────────────────────────────\n\nexport const GetByClassInputSchema = z.object({\n classId: UuidSchema,\n date: z.iso.date(),\n})\n\nexport type GetByClassInput = z.infer<typeof GetByClassInputSchema>\n\nexport const ClassAttendanceRowSchema = z.object({\n id: UuidSchema,\n studentId: UuidSchema,\n firstName: z.string(),\n middleName: z.string().nullable(),\n lastName: z.string(),\n admissionNo: z.string(),\n status: AttendanceStatusSchema,\n notes: z.string().nullable(),\n markedBy: UuidSchema,\n updatedAt: z.string(),\n})\n\nexport type ClassAttendanceRow = z.infer<typeof ClassAttendanceRowSchema>\n\n// ── Get by student ─────────────────────────────────────────────────────────────\n\nexport const GetByStudentInputSchema = z.object({\n studentId: UuidSchema,\n termId: UuidSchema,\n})\n\nexport type GetByStudentInput = z.infer<typeof GetByStudentInputSchema>\n\nexport const StudentAttendanceRowSchema = z.object({\n id: UuidSchema,\n date: z.string(),\n status: AttendanceStatusSchema,\n notes: z.string().nullable(),\n classId: UuidSchema,\n className: z.string(),\n})\n\nexport type StudentAttendanceRow = z.infer<typeof StudentAttendanceRowSchema>","/**\n * Brite Future Schools — bfs-contracts\n * Auth oRPC contract.\n *\n * Defines the API surface for authentication. The bfs-api module\n * imports this and passes it to `implement()` — no logic lives here.\n *\n * HTTP method + path pairs follow REST conventions and feed into the\n * OpenAPI spec that oRPC generates automatically.\n *\n * Phase History:\n * Phase 0.1 (2026-06-05): Initial creation\n *\n * @module src/contracts/auth\n * @since Phase 0.1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport {\n ChangePasswordInputSchema,\n LoginInputSchema,\n LoginOutputSchema,\n LogoutInputSchema,\n RefreshTokenInputSchema,\n RefreshTokenOutputSchema,\n RequestPasswordResetInputSchema,\n ResetPasswordInputSchema,\n SessionUserOutputSchema,\n SwitchBranchInputSchema,\n} from '../schemas/auth.js'\n\n/** Reusable empty-success output — used by mutations that return nothing */\nconst EmptyOutputSchema = z.object({}).meta({ description: 'Empty success response' })\n\n// ── Individual procedure contracts ────────────────────────────────────────────\n\n/** Exchange email + password for access/refresh token pair */\nexport const loginContract = oc\n .route({ method: 'POST', path: '/auth/login' })\n .input(LoginInputSchema)\n .output(LoginOutputSchema)\n\n/** Exchange a refresh token for a new access token */\nexport const refreshTokenContract = oc\n .route({ method: 'POST', path: '/auth/refresh' })\n .input(RefreshTokenInputSchema)\n .output(RefreshTokenOutputSchema)\n\n/** Revoke the current refresh token and end the session */\nexport const logoutContract = oc\n .route({ method: 'POST', path: '/auth/logout' })\n .input(LogoutInputSchema)\n .output(EmptyOutputSchema)\n\n/** Return the session user object for the current access token */\nexport const getMeContract = oc\n .route({ method: 'GET', path: '/auth/me' })\n .output(SessionUserOutputSchema)\n\n/** Change password (authenticated, requires current password) */\nexport const changePasswordContract = oc\n .route({ method: 'POST', path: '/auth/change-password' })\n .input(ChangePasswordInputSchema)\n .output(EmptyOutputSchema)\n\n/** Request a password-reset email */\nexport const requestPasswordResetContract = oc\n .route({ method: 'POST', path: '/auth/request-password-reset' })\n .input(RequestPasswordResetInputSchema)\n .output(EmptyOutputSchema)\n\n/** Complete a password reset using the emailed one-time token */\nexport const resetPasswordContract = oc\n .route({ method: 'POST', path: '/auth/reset-password' })\n .input(ResetPasswordInputSchema)\n .output(EmptyOutputSchema)\n\n/** Switch the active branch within an existing session */\nexport const switchBranchContract = oc\n .route({ method: 'POST', path: '/auth/switch-branch' })\n .input(SwitchBranchInputSchema)\n .output(SessionUserOutputSchema)\n\n// ── Auth contract router ──────────────────────────────────────────────────────\n\nexport const authContract = {\n login: loginContract,\n refreshToken: refreshTokenContract,\n logout: logoutContract,\n me: getMeContract,\n changePassword: changePasswordContract,\n requestPasswordReset: requestPasswordResetContract,\n resetPassword: resetPasswordContract,\n switchBranch: switchBranchContract,\n}\n","/**\n * Brite Future Schools — bfs-contracts\n * HR oRPC contract — staff and department procedure definitions.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation\n *\n * @module src/contracts/hr\n * @since Phase 1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport { UuidSchema, PaginationInputSchema } from '../schemas/base.js'\nimport {\n CreateStaffInputSchema,\n CreateStaffOutputSchema,\n StaffProfileSchema,\n StaffListItemSchema,\n ListStaffInputSchema,\n DepartmentSchema,\n CreateDepartmentInputSchema,\n} from '../schemas/hr.js'\n\nconst EmptyOutput = z.object({})\n\n// ── Staff ──────────────────────────────────────────────────────────────────────\n\nexport const createStaffContract = oc\n .route({ method: 'POST', path: '/hr/staff' })\n .input(CreateStaffInputSchema)\n .output(CreateStaffOutputSchema)\n\nexport const listStaffContract = oc\n .route({ method: 'GET', path: '/hr/staff' })\n .input(ListStaffInputSchema)\n .output(z.object({\n items: z.array(StaffListItemSchema),\n total: z.number(),\n nextCursor: UuidSchema.nullable(),\n }))\n\nexport const getStaffByIdContract = oc\n .route({ method: 'GET', path: '/hr/staff/{id}' })\n .input(z.object({ id: UuidSchema }))\n .output(StaffProfileSchema)\n\nexport const updateStaffStatusContract = oc\n .route({ method: 'PATCH', path: '/hr/staff/{id}/status' })\n .input(z.object({\n id: UuidSchema,\n status: z.enum(['active', 'inactive', 'suspended']),\n }))\n .output(EmptyOutput)\n\n// ── Departments ────────────────────────────────────────────────────────────────\n\nexport const listDepartmentsContract = oc\n .route({ method: 'GET', path: '/hr/departments' })\n .input(z.object({ branchId: UuidSchema.optional() }))\n .output(z.array(DepartmentSchema))\n\nexport const createDepartmentContract = oc\n .route({ method: 'POST', path: '/hr/departments' })\n .input(CreateDepartmentInputSchema)\n .output(DepartmentSchema)\n\n// ── HR contract router ─────────────────────────────────────────────────────────\n\nexport const hrContract = {\n createStaff: createStaffContract,\n listStaff: listStaffContract,\n getStaffById: getStaffByIdContract,\n updateStaffStatus: updateStaffStatusContract,\n listDepartments: listDepartmentsContract,\n createDepartment: createDepartmentContract,\n}","/**\n * Brite Future Schools — bfs-contracts\n * Students oRPC contract — student and guardian procedure definitions.\n *\n * Phase History:\n * Phase 1 (2026-06-07): Initial creation\n *\n * @module src/contracts/students\n * @since Phase 1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport { UuidSchema } from '../schemas/base.js'\nimport {\n CreateStudentInputSchema,\n CreateStudentOutputSchema,\n StudentProfileSchema,\n StudentListItemSchema,\n ListStudentsInputSchema,\n BulkUploadStudentsInputSchema,\n BulkUploadStudentsOutputSchema,\n LinkGuardianInputSchema,\n ClassSummarySchema,\n} from '../schemas/students.js'\n\nconst EmptyOutput = z.object({})\n\n// ── Students ───────────────────────────────────────────────────────────────────\n\nexport const createStudentContract = oc\n .route({ method: 'POST', path: '/students' })\n .input(CreateStudentInputSchema)\n .output(CreateStudentOutputSchema)\n\nexport const bulkUploadStudentsContract = oc\n .route({ method: 'POST', path: '/students/bulk' })\n .input(BulkUploadStudentsInputSchema)\n .output(BulkUploadStudentsOutputSchema)\n\nexport const listStudentsContract = oc\n .route({ method: 'GET', path: '/students' })\n .input(ListStudentsInputSchema)\n .output(z.object({\n items: z.array(StudentListItemSchema),\n total: z.number(),\n nextCursor: UuidSchema.nullable(),\n }))\n\nexport const getStudentByIdContract = oc\n .route({ method: 'GET', path: '/students/{id}' })\n .input(z.object({ id: UuidSchema }))\n .output(StudentProfileSchema)\n\n// ── Guardians ──────────────────────────────────────────────────────────────────\n\nexport const linkGuardianContract = oc\n .route({ method: 'POST', path: '/students/guardians' })\n .input(LinkGuardianInputSchema)\n .output(z.object({ guardianId: UuidSchema }))\n\n// ── Classes (selector data) ────────────────────────────────────────────────────\n\nexport const listClassesContract = oc\n .route({ method: 'GET', path: '/students/classes' })\n .input(z.object({\n termId: UuidSchema.optional(),\n gradeLevel: z.string().optional(),\n }))\n .output(z.array(ClassSummarySchema))\n\n// ── Students contract router ───────────────────────────────────────────────────\n\nexport const studentsContract = {\n create: createStudentContract,\n bulkUpload: bulkUploadStudentsContract,\n list: listStudentsContract,\n getById: getStudentByIdContract,\n linkGuardian: linkGuardianContract,\n listClasses: listClassesContract,\n}","/**\n * Brite Future Schools — bfs-contracts\n * Attendance oRPC contract — class attendance procedure definitions.\n *\n * Phase History:\n * Phase 2.1 (2026-06-08): Initial — mark, getByClass, getByStudent, listTerms\n *\n * @module src/contracts/attendance\n * @since Phase 2.1\n */\n\nimport { oc } from '@orpc/contract'\nimport * as z from 'zod'\nimport { UuidSchema } from '../schemas/base.js'\nimport {\n MarkAttendanceInputSchema,\n MarkAttendanceOutputSchema,\n GetByClassInputSchema,\n GetByStudentInputSchema,\n ClassAttendanceRowSchema,\n StudentAttendanceRowSchema,\n TermSchema,\n} from '../schemas/attendance.js'\n\n// ── Class attendance ───────────────────────────────────────────────────────────\n\nexport const markAttendanceContract = oc\n .route({ method: 'POST', path: '/attendance/class/mark' })\n .input(MarkAttendanceInputSchema)\n .output(MarkAttendanceOutputSchema)\n\nexport const getByClassContract = oc\n .route({ method: 'GET', path: '/attendance/class' })\n .input(GetByClassInputSchema)\n .output(z.array(ClassAttendanceRowSchema))\n\nexport const getByStudentContract = oc\n .route({ method: 'GET', path: '/attendance/student' })\n .input(GetByStudentInputSchema)\n .output(z.array(StudentAttendanceRowSchema))\n\n// ── Terms ──────────────────────────────────────────────────────────────────────\n\nexport const listTermsContract = oc\n .route({ method: 'GET', path: '/terms' })\n .input(z.object({}))\n .output(z.array(TermSchema))\n\n// ── Attendance contract router ─────────────────────────────────────────────────\n\nexport const attendanceContract = {\n mark: markAttendanceContract,\n getByClass: getByClassContract,\n getByStudent: getByStudentContract,\n listTerms: listTermsContract,\n}","/**\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 *\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// ── 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACWA,QAAmB;AAIZ,IAAM,aACR,SAAO,EACP,MAAM,uBAAuB,0BAA0B,EACvD,KAAK,EAAE,aAAa,wDAAmD,CAAC;AAItE,IAAM,aACR,SAAO,EACP,KAAK,EAAE,aAAa,mBAAmB,CAAC;AAI7C,IAAM,cAAgB,MAAI,SAAS;AAE5B,IAAM,mBAAqB,SAAO;AAAA,EACrC,WAAW,YAAY,KAAK,EAAE,aAAa,+BAA+B,CAAC;AAAA,EAC3E,WAAW,YAAY,KAAK,EAAE,aAAa,kCAAkC,CAAC;AAClF,CAAC;AAIM,IAAM,mBAAqB,SAAO;AAAA,EACrC,WAAW,YAAY,SAAS,EAAE,KAAK;AAAA,IACnC,aAAa;AAAA,EACjB,CAAC;AACL,CAAC;AAIM,IAAM,wBAA0B,SAAO;AAAA,EAC1C,QAAQ,WAAW,SAAS,EAAE,KAAK;AAAA,IAC/B,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,OACK,MAAI,EACJ,IAAI,CAAC,EACL,IAAI,GAAG,EACP,QAAQ,EAAE,EACV,KAAK,EAAE,aAAa,qDAAgD,CAAC;AAC9E,CAAC;AAEM,SAAS,sBAA8C,YAAe;AACzE,SAAS,SAAO;AAAA,IACZ,OAAS,QAAM,UAAU;AAAA,IACzB,YAAY,WAAW,SAAS,EAAE,KAAK;AAAA,MACnC,aAAa;AAAA,IACjB,CAAC;AAAA,IACD,OACK,MAAI,EACJ,YAAY,EACZ,KAAK,EAAE,aAAa,6CAA6C,CAAC;AAAA,EAC3E,CAAC;AACL;AAIO,IAAM,kBAAoB,SAAO;AAAA,EACpC,UAAU,WAAW,KAAK,EAAE,aAAa,oCAAoC,CAAC;AAClF,CAAC;;;AC/DD,IAAAA,KAAmB;AAKZ,IAAM,wBAA0B,UAAO;AAAA,EAC1C,IAAI;AAAA,EACJ,MAAQ,UAAO,EAAE,KAAK,EAAE,aAAa,4BAA4B,CAAC;AAAA,EAClE,UAAU;AAAA,EACV,WAAa,WAAQ;AACzB,CAAC;AAEM,IAAM,2BAA6B,UAAO;AAAA,EAC7C,IAAI;AAAA,EACJ,MAAQ,UAAO,EAAE,KAAK,EAAE,aAAa,mCAAmC,CAAC;AAAA,EACzE,UAAU;AACd,CAAC;AAEM,IAAM,0BAA4B,UAAO;AAAA,EAC5C,IAAI;AAAA,EACJ,OAAS,SAAM;AAAA,EACf,WAAa,UAAO;AAAA,EACpB,UAAY,UAAO;AAAA,EACnB,gBAAgB;AAAA,EAChB,OAAS,SAAM,qBAAqB;AAAA,EACpC,UAAY,SAAM,wBAAwB;AAAA,EAC1C,UAAY,WAAQ;AAAA,EACpB,oBAAsB,WAAQ;AAClC,CAAC;AAIM,IAAM,mBAAqB,UAAO;AAAA,EACrC,OAAS,SAAM,EAAE,KAAK,EAAE,aAAa,qBAAqB,CAAC;AAAA,EAC3D,UAAY,UAAO,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,sCAAsC,CAAC;AAAA,EACvF,UAAU,WAAW,SAAS,EAAE,KAAK;AAAA,IACjC,aAAa;AAAA,EACjB,CAAC;AACL,CAAC;AAEM,IAAM,oBAAsB,UAAO;AAAA,EACtC,aAAe,UAAO,EAAE,KAAK,EAAE,aAAa,2BAA2B,CAAC;AAAA,EACxE,cAAgB,UAAO,EAAE,KAAK,EAAE,aAAa,2CAA2C,CAAC;AAAA,EACzF,WAAa,OAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,8BAA8B,CAAC;AAAA,EACjF,MAAM;AACV,CAAC;AAIM,IAAM,0BAA4B,UAAO;AAAA,EAC5C,cAAgB,UAAO,EAAE,IAAI,CAAC;AAClC,CAAC;AAEM,IAAM,2BAA6B,UAAO;AAAA,EAC7C,aAAe,UAAO;AAAA,EACtB,WAAa,OAAI,EAAE,SAAS;AAChC,CAAC;AAIM,IAAM,oBAAsB,UAAO;AAAA,EACtC,cAAgB,UAAO,EAAE,IAAI,CAAC,EAAE,KAAK;AAAA,IACjC,aAAa;AAAA,EACjB,CAAC;AACL,CAAC;AAIM,IAAM,4BACR,UAAO;AAAA,EACJ,iBAAmB,UAAO,EAAE,IAAI,CAAC;AAAA,EACjC,aACK,UAAO,EACP,IAAI,GAAG,EAAE,OAAO,yCAAyC,CAAC;AAAA,EAC/D,iBAAmB,UAAO,EAAE,IAAI,CAAC;AACrC,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,iBAAiB;AAAA,EAChD,OAAO;AAAA,EACP,MAAM,CAAC,iBAAiB;AAC5B,CAAC;AAIE,IAAM,kCAAoC,UAAO;AAAA,EACpD,OAAS,SAAM;AACnB,CAAC;AAEM,IAAM,2BACR,UAAO;AAAA,EACJ,OAAS,UAAO,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,uCAAuC,CAAC;AAAA,EACrF,aAAe,UAAO,EAAE,IAAI,GAAG,EAAE,OAAO,yCAAyC,CAAC;AAAA,EAClF,iBAAmB,UAAO,EAAE,IAAI,CAAC;AACrC,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,iBAAiB;AAAA,EAChD,OAAO;AAAA,EACP,MAAM,CAAC,iBAAiB;AAC5B,CAAC;AAIE,IAAM,0BAA4B,UAAO;AAAA,EAC5C,UAAU,WAAW,KAAK,EAAE,aAAa,yCAAyC,CAAC;AACvF,CAAC;;;ACrGD,IAAAC,KAAmB;AAKZ,IAAM,uBAAyB,QAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,iBAAmB,QAAK;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAIM,IAAM,yBAA2B,UAAO;AAAA;AAAA,EAE3C,WAAa,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACpC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,UAAY,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,OAAS,SAAM;AAAA,EACf,OAAS,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAC/B,YAAc,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA;AAAA,EAGpC,UAAU,eAAe,KAAK;AAAA,IAC1B,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,eAAiB,WAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EAGvC,cAAc,WAAW,SAAS;AAAA,EAClC,aAAe,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,KAAK;AAAA,IACzC,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,gBAAgB;AAAA,EAChB,eAAiB,OAAI,KAAK,EAAE,KAAK,EAAE,aAAa,4BAA4B,CAAC;AAAA,EAC7E,aAAe,OAAI,KAAK,EAAE,SAAS;AAAA;AAAA,EAGnC,aAAe,UAAO,EAAE,SAAS;AAAA,EACjC,gBAAkB,UAAO,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA,EAClD,oBAAsB,UAAO,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA,EACtD,eAAiB,UAAO,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA,EACjD,gBAAkB,UAAO,EAAE,YAAY,EAAE,QAAQ,CAAC;AAAA;AAAA,EAGlD,UAAY,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACvC,aAAe,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACzC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA,EAGzC,WAAa,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACvC,QAAU,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACpC,QAAU,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACpC,QAAU,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AACxC,CAAC;AAMM,IAAM,qBAAuB,UAAO;AAAA;AAAA,EAEvC,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAa,UAAO;AAAA,EACpB,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO;AAAA,EACnB,OAAS,UAAO;AAAA,EAChB,YAAc,UAAO;AAAA,EACrB,WAAa,UAAO,EAAE,SAAS;AAAA,EAC/B,QAAU,UAAO,EAAE,SAAS;AAAA,EAC5B,QAAU,UAAO,EAAE,SAAS;AAAA,EAC5B,QAAU,UAAO,EAAE,SAAS;AAAA,EAC5B,aAAe,UAAO;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAiB,UAAO;AAAA,EACxB,aAAe,UAAO,EAAE,SAAS;AAAA,EACjC,aAAe,UAAO;AAAA,EACtB,gBAAkB,UAAO;AAAA,EACzB,oBAAsB,UAAO;AAAA,EAC7B,eAAiB,UAAO,EAAE,SAAS;AAAA,EACnC,gBAAkB,UAAO,EAAE,SAAS;AAAA,EACpC,UAAY,UAAO,EAAE,SAAS;AAAA,EAC9B,aAAe,UAAO,EAAE,SAAS;AAAA,EACjC,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,QAAU,UAAO;AAAA,EACjB,WAAa,UAAO;AAAA;AAAA,EAGpB,OAAS,UAAO;AAAA,EAChB,oBAAsB,WAAQ;AAAA;AAAA,EAG9B,cAAc,WAAW,SAAS;AAAA,EAClC,gBAAkB,UAAO,EAAE,SAAS;AAAA;AAAA,EAGpC,UAAU,eAAe,SAAS;AAAA,EAClC,QAAQ,WAAW,SAAS;AAChC,CAAC;AAMM,IAAM,sBAAwB,UAAO;AAAA,EACxC,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,WAAa,UAAO;AAAA,EACpB,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO;AAAA,EACnB,OAAS,UAAO;AAAA,EAChB,OAAS,UAAO;AAAA,EAChB,aAAe,UAAO;AAAA,EACtB,gBAAgB;AAAA,EAChB,QAAU,UAAO;AAAA,EACjB,gBAAkB,UAAO,EAAE,SAAS;AAAA,EACpC,UAAU,eAAe,SAAS;AAAA,EAClC,WAAa,UAAO;AACxB,CAAC;AAMM,IAAM,uBAAuB,sBAAsB,OAAO;AAAA,EAC7D,QAAU,UAAO,EAAE,SAAS,EAAE,KAAK;AAAA,IAC/B,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,cAAc,WAAW,SAAS;AAAA,EAClC,UAAU,eAAe,SAAS;AAAA,EAClC,QAAU,QAAK,CAAC,UAAU,UAAU,CAAC,EAAE,SAAS;AACpD,CAAC;AAMM,IAAM,0BAA4B,UAAO;AAAA,EAC5C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAS,UAAO;AAAA;AAAA,EAEhB,WAAa,WAAQ;AACzB,CAAC;AAMM,IAAM,mBAAqB,UAAO;AAAA,EACrC,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,MAAQ,UAAO;AAAA,EACf,OAAO,WAAW,SAAS;AAC/B,CAAC;AAIM,IAAM,8BAAgC,UAAO;AAAA,EAChD,MAAQ,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,OAAO,WAAW,SAAS;AAC/B,CAAC;;;AClMD,IAAAC,KAAmB;AAKZ,IAAM,eAAiB,QAAK,CAAC,QAAQ,QAAQ,CAAC;AAE9C,IAAM,sBAAwB,QAAK;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,mBAAqB,QAAK;AAAA,EACnC;AAAA,EAAO;AAAA,EACP;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AACpD,CAAC;AAIM,IAAM,2BAA6B,UAAO;AAAA;AAAA,EAE7C,WAAa,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACpC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,UAAY,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,aAAe,OAAI,KAAK,EAAE,KAAK,EAAE,aAAa,4BAA4B,CAAC;AAAA,EAC3E,QAAQ;AAAA,EACR,aAAe,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK;AAAA,IACxC,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,SAAW,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACrC,eAAiB,OAAI,KAAK;AAAA,EAC1B,YAAc,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACxC,cAAgB,UAAO,EAAE,SAAS;AAAA;AAAA,EAGlC,SAAS,WAAW,SAAS,EAAE,KAAK;AAAA,IAChC,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,QAAQ,WAAW,SAAS,EAAE,KAAK;AAAA,IAC/B,aAAa;AAAA,EACjB,CAAC;AAAA;AAAA,EAGD,UAAY,UAAO;AAAA,IACf,WAAa,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,IACpC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,IACzC,UAAY,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,IACnC,cAAgB,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK;AAAA,MACzC,aAAa;AAAA,IACjB,CAAC;AAAA,IACD,OAAS,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IAC/B,OAAS,SAAM,EAAE,SAAS;AAAA,IAC1B,YAAc,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,IACxC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC7C,CAAC,EAAE,SAAS;AAChB,CAAC;AAMM,IAAM,uBAAyB,UAAO;AAAA,EACzC,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,aAAe,UAAO;AAAA,EACtB,SAAW,UAAO,EAAE,SAAS;AAAA,EAC7B,WAAa,UAAO;AAAA,EACpB,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO;AAAA,EACnB,aAAe,UAAO;AAAA,EACtB,QAAQ;AAAA,EACR,UAAY,UAAO,EAAE,SAAS;AAAA,EAC9B,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,cAAgB,UAAO,EAAE,SAAS;AAAA,EAClC,eAAiB,UAAO;AAAA,EACxB,QAAQ;AAAA,EACR,WAAa,UAAO;AAAA;AAAA,EAGpB,cAAgB,UAAO;AAAA,IACnB,SAAS;AAAA,IACT,WAAa,UAAO;AAAA,IACpB,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAY,UAAO;AAAA,EACvB,CAAC,EAAE,SAAS;AAAA;AAAA,EAGZ,WAAa,SAAQ,UAAO;AAAA,IACxB,IAAI;AAAA,IACJ,WAAa,UAAO;AAAA,IACpB,YAAc,UAAO,EAAE,SAAS;AAAA,IAChC,UAAY,UAAO;AAAA,IACnB,cAAgB,UAAO;AAAA,IACvB,OAAS,UAAO;AAAA,IAChB,OAAS,UAAO,EAAE,SAAS;AAAA,IAC3B,WAAa,WAAQ;AAAA,EACzB,CAAC,CAAC;AACN,CAAC;AAMM,IAAM,wBAA0B,UAAO;AAAA,EAC1C,IAAI;AAAA,EACJ,aAAe,UAAO;AAAA,EACtB,WAAa,UAAO;AAAA,EACpB,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO;AAAA,EACnB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAa,UAAO,EAAE,SAAS;AAAA,EAC/B,YAAY,iBAAiB,SAAS;AAAA,EACtC,qBAAuB,UAAO,EAAE,SAAS;AAAA,EACzC,sBAAwB,UAAO,EAAE,SAAS;AAAA,EAC1C,WAAa,UAAO;AACxB,CAAC;AAMM,IAAM,0BAA0B,sBAAsB,OAAO;AAAA,EAChE,QAAU,UAAO,EAAE,SAAS,EAAE,KAAK;AAAA,IAC/B,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,SAAS,WAAW,SAAS;AAAA,EAC7B,YAAY,iBAAiB,SAAS;AAAA,EACtC,QAAQ,oBAAoB,SAAS;AAAA,EACrC,QAAQ,WAAW,SAAS;AAChC,CAAC;AAWM,IAAM,6BAA+B,UAAO;AAAA,EAC/C,WAAa,UAAO,EAAE,IAAI,CAAC;AAAA,EAC3B,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,aAAe,UAAO,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,4BAA4B,CAAC;AAAA,EAChF,QAAU,UAAO,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,mCAAmC,CAAC;AAAA,EAClF,aAAe,UAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,SAAW,UAAO,EAAE,SAAS;AAAA,EAC7B,eAAiB,UAAO,EAAE,SAAS;AAAA,EACnC,YAAc,UAAO,EAAE,SAAS;AAAA;AAAA,EAGhC,mBAAqB,UAAO,EAAE,SAAS;AAAA,EACvC,kBAAoB,UAAO,EAAE,SAAS;AAAA,EACtC,sBAAwB,UAAO,EAAE,SAAS;AAAA,EAC1C,eAAiB,UAAO,EAAE,SAAS;AAAA,EACnC,eAAiB,UAAO,EAAE,SAAS;AACvC,CAAC;AAIM,IAAM,gCAAkC,UAAO;AAAA,EAClD,SAAS,WAAW,KAAK;AAAA,IACrB,aAAa;AAAA,EACjB,CAAC;AAAA,EACD,QAAQ;AAAA,EACR,MAAQ,SAAM,0BAA0B,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAC5D,CAAC;AAIM,IAAM,iCAAmC,UAAO;AAAA,EACnD,SAAW,OAAI,EAAE,YAAY;AAAA,EAC7B,SAAW,OAAI,EAAE,YAAY;AAAA,EAC7B,QAAU,SAAQ,UAAO;AAAA,IACrB,KAAO,OAAI,EAAE,SAAS;AAAA,IACtB,aAAe,UAAO,EAAE,SAAS;AAAA,IACjC,QAAU,UAAO;AAAA,EACrB,CAAC,CAAC;AACN,CAAC;AAMM,IAAM,4BAA8B,UAAO;AAAA,EAC9C,WAAW;AAAA,EACX,aAAe,UAAO;AAC1B,CAAC;AAMM,IAAM,0BAA4B,UAAO;AAAA,EAC5C,WAAW;AAAA,EACX,WAAa,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACpC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,UAAY,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EACnC,cAAgB,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EACtC,OAAS,UAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAC/B,OAAS,SAAM,EAAE,SAAS;AAAA,EAC1B,YAAc,UAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACxC,YAAc,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,WAAa,WAAQ,EAAE,QAAQ,KAAK;AACxC,CAAC;AAMM,IAAM,qBAAuB,UAAO;AAAA,EACvC,IAAI;AAAA,EACJ,MAAQ,UAAO;AAAA,EACf,YAAY;AAAA,EACZ,WAAa,UAAO;AAAA,EACpB,UAAY,UAAO,EAAE,SAAS;AAAA,EAC9B,eAAiB,UAAO;AAAA,EACxB,gBAAgB,WAAW,SAAS;AACxC,CAAC;;;AChOD,IAAAC,KAAmB;AAKZ,IAAM,yBAA2B,QAAK;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAMM,IAAM,aAAe,UAAO;AAAA,EAC/B,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,MAAQ,UAAO;AAAA,EACf,WAAa,UAAO;AAAA,EACpB,SAAW,UAAO;AAAA,EAClB,WAAa,WAAQ;AACzB,CAAC;AAMM,IAAM,8BAAgC,UAAO;AAAA,EAChD,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAS,UAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACxC,CAAC;AAEM,IAAM,4BAA8B,UAAO;AAAA,EAC9C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAQ,OAAI,KAAK;AAAA,EACjB,SAAW,SAAM,2BAA2B,EAAE,IAAI,CAAC;AACvD,CAAC;AAIM,IAAM,6BAA+B,UAAO;AAAA,EAC/C,OAAS,UAAO;AAAA,EAChB,MAAQ,UAAO;AAAA,EACf,SAAS;AACb,CAAC;AAMM,IAAM,wBAA0B,UAAO;AAAA,EAC1C,SAAS;AAAA,EACT,MAAQ,OAAI,KAAK;AACrB,CAAC;AAIM,IAAM,2BAA6B,UAAO;AAAA,EAC7C,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,WAAa,UAAO;AAAA,EACpB,YAAc,UAAO,EAAE,SAAS;AAAA,EAChC,UAAY,UAAO;AAAA,EACnB,aAAe,UAAO;AAAA,EACtB,QAAQ;AAAA,EACR,OAAS,UAAO,EAAE,SAAS;AAAA,EAC3B,UAAU;AAAA,EACV,WAAa,UAAO;AACxB,CAAC;AAMM,IAAM,0BAA4B,UAAO;AAAA,EAC5C,WAAW;AAAA,EACX,QAAQ;AACZ,CAAC;AAIM,IAAM,6BAA+B,UAAO;AAAA,EAC/C,IAAI;AAAA,EACJ,MAAQ,UAAO;AAAA,EACf,QAAQ;AAAA,EACR,OAAS,UAAO,EAAE,SAAS;AAAA,EAC3B,SAAS;AAAA,EACT,WAAa,UAAO;AACxB,CAAC;;;ACxFD,sBAAmB;AACnB,IAAAC,KAAmB;AAenB,IAAM,oBAAsB,UAAO,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,yBAAyB,CAAC;AAK9E,IAAM,gBAAgB,mBAC1B,MAAM,EAAE,QAAQ,QAAQ,MAAM,cAAc,CAAC,EAC7C,MAAM,gBAAgB,EACtB,OAAO,iBAAiB;AAGpB,IAAM,uBAAuB,mBACjC,MAAM,EAAE,QAAQ,QAAQ,MAAM,gBAAgB,CAAC,EAC/C,MAAM,uBAAuB,EAC7B,OAAO,wBAAwB;AAG3B,IAAM,iBAAiB,mBAC3B,MAAM,EAAE,QAAQ,QAAQ,MAAM,eAAe,CAAC,EAC9C,MAAM,iBAAiB,EACvB,OAAO,iBAAiB;AAGpB,IAAM,gBAAgB,mBAC1B,MAAM,EAAE,QAAQ,OAAO,MAAM,WAAW,CAAC,EACzC,OAAO,uBAAuB;AAG1B,IAAM,yBAAyB,mBACnC,MAAM,EAAE,QAAQ,QAAQ,MAAM,wBAAwB,CAAC,EACvD,MAAM,yBAAyB,EAC/B,OAAO,iBAAiB;AAGpB,IAAM,+BAA+B,mBACzC,MAAM,EAAE,QAAQ,QAAQ,MAAM,+BAA+B,CAAC,EAC9D,MAAM,+BAA+B,EACrC,OAAO,iBAAiB;AAGpB,IAAM,wBAAwB,mBAClC,MAAM,EAAE,QAAQ,QAAQ,MAAM,uBAAuB,CAAC,EACtD,MAAM,wBAAwB,EAC9B,OAAO,iBAAiB;AAGpB,IAAM,uBAAuB,mBACjC,MAAM,EAAE,QAAQ,QAAQ,MAAM,sBAAsB,CAAC,EACrD,MAAM,uBAAuB,EAC7B,OAAO,uBAAuB;AAI1B,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,cAAc;AAChB;;;ACpFA,IAAAC,mBAAmB;AACnB,IAAAC,KAAmB;AAYnB,IAAM,cAAgB,UAAO,CAAC,CAAC;AAIxB,IAAM,sBAAsB,oBAC9B,MAAM,EAAE,QAAQ,QAAQ,MAAM,YAAY,CAAC,EAC3C,MAAM,sBAAsB,EAC5B,OAAO,uBAAuB;AAE5B,IAAM,oBAAoB,oBAC5B,MAAM,EAAE,QAAQ,OAAO,MAAM,YAAY,CAAC,EAC1C,MAAM,oBAAoB,EAC1B,OAAS,UAAO;AAAA,EACb,OAAS,SAAM,mBAAmB;AAAA,EAClC,OAAS,UAAO;AAAA,EAChB,YAAY,WAAW,SAAS;AACpC,CAAC,CAAC;AAEC,IAAM,uBAAuB,oBAC/B,MAAM,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC,EAC/C,MAAQ,UAAO,EAAE,IAAI,WAAW,CAAC,CAAC,EAClC,OAAO,kBAAkB;AAEvB,IAAM,4BAA4B,oBACpC,MAAM,EAAE,QAAQ,SAAS,MAAM,wBAAwB,CAAC,EACxD,MAAQ,UAAO;AAAA,EACZ,IAAI;AAAA,EACJ,QAAU,QAAK,CAAC,UAAU,YAAY,WAAW,CAAC;AACtD,CAAC,CAAC,EACD,OAAO,WAAW;AAIhB,IAAM,0BAA0B,oBAClC,MAAM,EAAE,QAAQ,OAAO,MAAM,kBAAkB,CAAC,EAChD,MAAQ,UAAO,EAAE,UAAU,WAAW,SAAS,EAAE,CAAC,CAAC,EACnD,OAAS,SAAM,gBAAgB,CAAC;AAE9B,IAAM,2BAA2B,oBACnC,MAAM,EAAE,QAAQ,QAAQ,MAAM,kBAAkB,CAAC,EACjD,MAAM,2BAA2B,EACjC,OAAO,gBAAgB;AAIrB,IAAM,aAAa;AAAA,EACtB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,kBAAkB;AACtB;;;ACjEA,IAAAC,mBAAmB;AACnB,IAAAC,KAAmB;AAcnB,IAAMC,eAAgB,UAAO,CAAC,CAAC;AAIxB,IAAM,wBAAwB,oBAChC,MAAM,EAAE,QAAQ,QAAQ,MAAM,YAAY,CAAC,EAC3C,MAAM,wBAAwB,EAC9B,OAAO,yBAAyB;AAE9B,IAAM,6BAA6B,oBACrC,MAAM,EAAE,QAAQ,QAAQ,MAAM,iBAAiB,CAAC,EAChD,MAAM,6BAA6B,EACnC,OAAO,8BAA8B;AAEnC,IAAM,uBAAuB,oBAC/B,MAAM,EAAE,QAAQ,OAAO,MAAM,YAAY,CAAC,EAC1C,MAAM,uBAAuB,EAC7B,OAAS,UAAO;AAAA,EACb,OAAS,SAAM,qBAAqB;AAAA,EACpC,OAAS,UAAO;AAAA,EAChB,YAAY,WAAW,SAAS;AACpC,CAAC,CAAC;AAEC,IAAM,yBAAyB,oBACjC,MAAM,EAAE,QAAQ,OAAO,MAAM,iBAAiB,CAAC,EAC/C,MAAQ,UAAO,EAAE,IAAI,WAAW,CAAC,CAAC,EAClC,OAAO,oBAAoB;AAIzB,IAAM,uBAAuB,oBAC/B,MAAM,EAAE,QAAQ,QAAQ,MAAM,sBAAsB,CAAC,EACrD,MAAM,uBAAuB,EAC7B,OAAS,UAAO,EAAE,YAAY,WAAW,CAAC,CAAC;AAIzC,IAAM,sBAAsB,oBAC9B,MAAM,EAAE,QAAQ,OAAO,MAAM,oBAAoB,CAAC,EAClD,MAAQ,UAAO;AAAA,EACZ,QAAQ,WAAW,SAAS;AAAA,EAC5B,YAAc,UAAO,EAAE,SAAS;AACpC,CAAC,CAAC,EACD,OAAS,SAAM,kBAAkB,CAAC;AAIhC,IAAM,mBAAmB;AAAA,EAC5B,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,cAAc;AAAA,EACd,aAAa;AACjB;;;ACrEA,IAAAC,mBAAmB;AACnB,IAAAC,KAAmB;AAcZ,IAAM,yBAAyB,oBACjC,MAAM,EAAE,QAAQ,QAAQ,MAAM,yBAAyB,CAAC,EACxD,MAAM,yBAAyB,EAC/B,OAAO,0BAA0B;AAE/B,IAAM,qBAAqB,oBAC7B,MAAM,EAAE,QAAQ,OAAO,MAAM,oBAAoB,CAAC,EAClD,MAAM,qBAAqB,EAC3B,OAAS,SAAM,wBAAwB,CAAC;AAEtC,IAAM,uBAAuB,oBAC/B,MAAM,EAAE,QAAQ,OAAO,MAAM,sBAAsB,CAAC,EACpD,MAAM,uBAAuB,EAC7B,OAAS,SAAM,0BAA0B,CAAC;AAIxC,IAAM,oBAAoB,oBAC5B,MAAM,EAAE,QAAQ,OAAO,MAAM,SAAS,CAAC,EACvC,MAAQ,UAAO,CAAC,CAAC,CAAC,EAClB,OAAS,SAAM,UAAU,CAAC;AAIxB,IAAM,qBAAqB;AAAA,EAC9B,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,WAAW;AACf;;;AC5BA,SAAS,QAAQ,MAAmB,MAAyB;AAC3D,SAAO,KAAK,MAAM;AAAA,IAChB,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,aAAa,KAAK;AAAA,EAChD;AACF;AAIO,SAAS,aAAa,MAA4B;AACvD,SAAO,QAAQ,MAAM,YAAY;AACnC;AAEO,SAAS,WAAW,MAA4B;AACrD,SAAO,QAAQ,MAAM,UAAU;AACjC;AAEO,SAAS,cAAc,MAA4B;AACxD,SAAO,QAAQ,MAAM,cAAc;AACrC;AAEO,SAAS,YAAY,MAA4B;AACtD,SAAO,QAAQ,MAAM,WAAW;AAClC;AAEO,SAAS,kBAAkB,MAA4B;AAC5D,SAAO,QAAQ,MAAM,kBAAkB;AACzC;AAEO,SAAS,mBAAmB,MAA4B;AAC7D,SACE,aAAa,IAAI,KACjB,WAAW,IAAI,KACf,YAAY,IAAI,KAChB,kBAAkB,IAAI;AAE1B;AAIO,SAAS,MAAM,MAA4B;AAChD,SAAO,QAAQ,MAAM,KAAK;AAC5B;AAEO,SAAS,eAAe,MAA4B;AACzD,SAAO,QAAQ,MAAM,eAAe;AACtC;AAEO,SAAS,iBAAiB,MAA4B;AAC3D,SAAO,QAAQ,MAAM,iBAAiB;AACxC;AAIO,SAAS,cAAc,MAA4B;AACxD,SAAO,QAAQ,MAAM,cAAc;AACrC;AAEO,SAAS,YAAY,MAA4B;AACtD,SAAO,QAAQ,MAAM,WAAW;AAClC;AAEO,SAAS,gBAAgB,MAA4B;AAC1D,SAAO,QAAQ,MAAM,gBAAgB;AACvC;AAEO,SAAS,cAAc,MAA4B;AACxD,SAAO,QAAQ,MAAM,cAAc;AACrC;AAEO,SAAS,aAAa,MAA4B;AACvD,SAAO,QAAQ,MAAM,YAAY;AACnC;AAEO,SAAS,YAAY,MAA4B;AACtD,SAAO,QAAQ,MAAM,WAAW;AAClC;AAEO,SAAS,WAAW,MAA4B;AACrD,SAAO,QAAQ,MAAM,UAAU;AACjC;AAEO,SAAS,iBAAiB,MAA4B;AAC3D,SAAO,QAAQ,MAAM,iBAAiB;AACxC;AAIO,SAAS,SAAS,MAA4B;AACnD,SAAO,QAAQ,MAAM,QAAQ;AAC/B;AAEO,SAAS,UAAU,MAA4B;AACpD,SAAO,QAAQ,MAAM,UAAU;AACjC;AAEO,SAAS,SAAS,MAA4B;AACnD,SAAO,QAAQ,MAAM,QAAQ;AAC/B;AAEO,SAAS,eAAe,MAA4B;AACzD,SAAO,QAAQ,MAAM,eAAe;AACtC;AAEO,SAAS,iBAAiB,MAA4B;AAC3D,SAAO,QAAQ,MAAM,iBAAiB;AACxC;AAEO,SAAS,UAAU,MAA4B;AACpD,SAAO,QAAQ,MAAM,UAAU;AACjC;AAIO,SAAS,UAAU,MAA4B;AACpD,SAAO,QAAQ,MAAM,SAAS;AAChC;AAEO,SAAS,UAAU,MAA4B;AACpD,SAAO,QAAQ,MAAM,SAAS;AAChC;AAEO,SAAS,SAAS,MAA4B;AACnD,SAAO,QAAQ,MAAM,QAAQ;AAC/B;AAIO,SAAS,aAAa,MAA4B;AACvD,SAAO,QAAQ,MAAM,aAAa;AACpC;AAEO,SAAS,oBAAoB,MAA4B;AAC9D,SAAO,QAAQ,MAAM,oBAAoB;AAC3C;AAIO,SAAS,QAAQ,MAA4B;AAClD,QAAM,aAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,KAAK,MAAM;AAAA,IAChB,CAAC,MACC,WAAW,SAAS,EAAE,IAAI,KAAK,EAAE,aAAa,KAAK;AAAA,EACvD;AACF;;;AC/JO,SAAS,uBAAuB,MAA4B;AAC/D,SACI,eAAe,IAAI,KACnB,MAAM,IAAI,KACV,YAAY,IAAI,KAChB,kBAAkB,IAAI,KACtB,cAAc,IAAI;AAE1B;AAGO,SAAS,uBAAuB,MAA4B;AAC/D,SACI,uBAAuB,IAAI,KAC3B,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAGO,SAAS,uBAAuB,MAA4B;AAC/D,SACI,UAAU,IAAI,KACd,YAAY,IAAI,KAChB,kBAAkB,IAAI,KACtB,cAAc,IAAI;AAE1B;AAGO,SAAS,uBAAuB,MAA4B;AAC/D,SACI,uBAAuB,IAAI,KAC3B,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAKO,SAAS,iBAAiB,MAA4B;AACzD,SACI,UAAU,IAAI,KACd,YAAY,IAAI,KAChB,kBAAkB,IAAI,KACtB,cAAc,IAAI,KAClB,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAGO,SAAS,eAAe,MAA4B;AACvD,SACI,UAAU,IAAI,KACd,YAAY,IAAI,KAChB,cAAc,IAAI,KAClB,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAKO,SAAS,mBAAmB,MAA4B;AAC3D,SACI,eAAe,IAAI,KACnB,MAAM,IAAI,KACV,YAAY,IAAI,KAChB,kBAAkB,IAAI,KACtB,UAAU,IAAI,KACd,cAAc,IAAI,KAClB,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAGO,SAAS,kBAAkB,MAA4B;AAC1D,SACI,YAAY,IAAI,KAChB,kBAAkB,IAAI,KACtB,UAAU,IAAI,KACd,cAAc,IAAI,KAClB,WAAW,IAAI,KACf,aAAa,IAAI;AAEzB;AAKO,SAAS,wBAAwB,MAA4B;AAChE,SACI,CAAC,UAAU,IAAI,KACf,CAAC,SAAS,IAAI,KACd,CAAC,UAAU,IAAI,KACf,CAAC,aAAa,IAAI,KAClB,CAAC,oBAAoB,IAAI;AAEjC;","names":["z","z","z","z","z","import_contract","z","import_contract","z","EmptyOutput","import_contract","z"]}
|