@brite-future-schools-contracts/contracts 2.0.8 → 2.0.12
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-7Q4RWA5S.js → chunk-TTAZOH4Y.js} +9 -9
- package/dist/chunk-TTAZOH4Y.js.map +1 -0
- package/dist/{chunk-3IZCDZ2P.js → chunk-YQELK62C.js} +2 -2
- package/dist/contracts/index.cjs +75 -77
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.js +2 -2
- package/dist/index.cjs +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/schemas/index.cjs +8 -8
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +1 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7Q4RWA5S.js.map +0 -1
- /package/dist/{chunk-3IZCDZ2P.js.map → chunk-YQELK62C.js.map} +0 -0
|
@@ -34,22 +34,22 @@ var BranchRefSchema = z.object({
|
|
|
34
34
|
// src/schemas/auth.ts
|
|
35
35
|
import * as z2 from "zod";
|
|
36
36
|
var SessionUserRoleSchema = z2.object({
|
|
37
|
-
id:
|
|
37
|
+
id: z2.string().uuid(),
|
|
38
38
|
name: z2.string().meta({ description: "Role name, e.g. PRINCIPAL" }),
|
|
39
|
-
branchId:
|
|
39
|
+
branchId: z2.string().uuid(),
|
|
40
40
|
isPrimary: z2.boolean()
|
|
41
41
|
});
|
|
42
42
|
var SessionUserSubRoleSchema = z2.object({
|
|
43
|
-
id:
|
|
43
|
+
id: z2.string().uuid(),
|
|
44
44
|
name: z2.string().meta({ description: "Sub-role name, e.g. HEAD_PREFECT" }),
|
|
45
|
-
branchId:
|
|
45
|
+
branchId: z2.string().uuid()
|
|
46
46
|
});
|
|
47
47
|
var SessionUserOutputSchema = z2.object({
|
|
48
|
-
id:
|
|
48
|
+
id: z2.string().uuid(),
|
|
49
49
|
email: z2.email(),
|
|
50
50
|
firstName: z2.string(),
|
|
51
51
|
lastName: z2.string(),
|
|
52
|
-
activeBranchId:
|
|
52
|
+
activeBranchId: z2.string().uuid(),
|
|
53
53
|
roles: z2.array(SessionUserRoleSchema),
|
|
54
54
|
subRoles: z2.array(SessionUserSubRoleSchema),
|
|
55
55
|
isActive: z2.boolean(),
|
|
@@ -58,7 +58,7 @@ var SessionUserOutputSchema = z2.object({
|
|
|
58
58
|
var LoginInputSchema = z2.object({
|
|
59
59
|
email: z2.email().meta({ description: "User email address" }),
|
|
60
60
|
password: z2.string().min(1).meta({ description: "Plain-text password (sent over TLS)" }),
|
|
61
|
-
branchId:
|
|
61
|
+
branchId: z2.string().uuid().optional().meta({
|
|
62
62
|
description: "Branch to activate on login; defaults to user primary branch"
|
|
63
63
|
})
|
|
64
64
|
});
|
|
@@ -100,7 +100,7 @@ var ResetPasswordInputSchema = z2.object({
|
|
|
100
100
|
path: ["confirmPassword"]
|
|
101
101
|
});
|
|
102
102
|
var SwitchBranchInputSchema = z2.object({
|
|
103
|
-
branchId:
|
|
103
|
+
branchId: z2.string().uuid().meta({ description: "Branch to switch the active session to" })
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
// src/schemas/hr.ts
|
|
@@ -546,4 +546,4 @@ export {
|
|
|
546
546
|
GetByStudentInputSchema,
|
|
547
547
|
StudentAttendanceRowSchema
|
|
548
548
|
};
|
|
549
|
-
//# sourceMappingURL=chunk-
|
|
549
|
+
//# sourceMappingURL=chunk-TTAZOH4Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/base.ts","../src/schemas/auth.ts","../src/schemas/hr.ts","../src/schemas/students.ts","../src/schemas/attendance.ts"],"sourcesContent":["/**\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 * Phase 3 (2026-06-10): Replaced CuidSchema with z.string().uuid() per R-052\n *\n * @module src/schemas/auth\n * @since Phase 0.1\n */\n\nimport * as z from 'zod'\n\n// ── Session user (defined first — referenced by LoginOutputSchema below) ───────\n\nexport const SessionUserRoleSchema = z.object({\n id: z.string().uuid(),\n name: z.string().meta({ description: 'Role name, e.g. PRINCIPAL' }),\n branchId: z.string().uuid(),\n isPrimary: z.boolean(),\n})\n\nexport const SessionUserSubRoleSchema = z.object({\n id: z.string().uuid(),\n name: z.string().meta({ description: 'Sub-role name, e.g. HEAD_PREFECT' }),\n branchId: z.string().uuid(),\n})\n\nexport const SessionUserOutputSchema = z.object({\n id: z.string().uuid(),\n email: z.email(),\n firstName: z.string(),\n lastName: z.string(),\n activeBranchId: z.string().uuid(),\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: z.string().uuid().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: z.string().uuid().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>"],"mappings":"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","names":["z","z","z","z"]}
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
SwitchBranchInputSchema,
|
|
34
34
|
TermSchema,
|
|
35
35
|
UuidSchema
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-TTAZOH4Y.js";
|
|
37
37
|
|
|
38
38
|
// src/contracts/auth.ts
|
|
39
39
|
import { oc } from "@orpc/contract";
|
|
@@ -154,4 +154,4 @@ export {
|
|
|
154
154
|
listTermsContract,
|
|
155
155
|
attendanceContract
|
|
156
156
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-YQELK62C.js.map
|
package/dist/contracts/index.cjs
CHANGED
|
@@ -63,108 +63,82 @@ module.exports = __toCommonJS(contracts_exports);
|
|
|
63
63
|
|
|
64
64
|
// src/contracts/auth.ts
|
|
65
65
|
var import_contract = require("@orpc/contract");
|
|
66
|
-
var z3 = __toESM(require("zod"), 1);
|
|
67
|
-
|
|
68
|
-
// src/schemas/auth.ts
|
|
69
66
|
var z2 = __toESM(require("zod"), 1);
|
|
70
67
|
|
|
71
|
-
// src/schemas/base.ts
|
|
72
|
-
var z = __toESM(require("zod"), 1);
|
|
73
|
-
var CuidSchema = z.string().regex(/^[a-z][a-z0-9]{24}$/, "Invalid cuid2 identifier").meta({ description: "cuid2 \u2014 prefixed, collision-resistant identifier" });
|
|
74
|
-
var UuidSchema = z.uuidv4().meta({ description: "RFC-4122 UUID v4" });
|
|
75
|
-
var IsoDatetime = z.iso.datetime();
|
|
76
|
-
var TimestampsSchema = z.object({
|
|
77
|
-
createdAt: IsoDatetime.meta({ description: "ISO-8601 creation time (UTC)" }),
|
|
78
|
-
updatedAt: IsoDatetime.meta({ description: "ISO-8601 last update time (UTC)" })
|
|
79
|
-
});
|
|
80
|
-
var SoftDeleteSchema = z.object({
|
|
81
|
-
deletedAt: IsoDatetime.nullable().meta({
|
|
82
|
-
description: "Set when the record is soft-deleted; null if active"
|
|
83
|
-
})
|
|
84
|
-
});
|
|
85
|
-
var PaginationInputSchema = z.object({
|
|
86
|
-
cursor: CuidSchema.optional().meta({
|
|
87
|
-
description: "Opaque cursor from the previous page response"
|
|
88
|
-
}),
|
|
89
|
-
limit: z.int().min(1).max(100).default(20).meta({ description: "Number of items to return (1\u2013100, default 20)" })
|
|
90
|
-
});
|
|
91
|
-
var BranchRefSchema = z.object({
|
|
92
|
-
branchId: CuidSchema.meta({ description: "The branch this record belongs to" })
|
|
93
|
-
});
|
|
94
|
-
|
|
95
68
|
// src/schemas/auth.ts
|
|
96
|
-
var
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
69
|
+
var z = __toESM(require("zod"), 1);
|
|
70
|
+
var SessionUserRoleSchema = z.object({
|
|
71
|
+
id: z.string().uuid(),
|
|
72
|
+
name: z.string().meta({ description: "Role name, e.g. PRINCIPAL" }),
|
|
73
|
+
branchId: z.string().uuid(),
|
|
74
|
+
isPrimary: z.boolean()
|
|
75
|
+
});
|
|
76
|
+
var SessionUserSubRoleSchema = z.object({
|
|
77
|
+
id: z.string().uuid(),
|
|
78
|
+
name: z.string().meta({ description: "Sub-role name, e.g. HEAD_PREFECT" }),
|
|
79
|
+
branchId: z.string().uuid()
|
|
80
|
+
});
|
|
81
|
+
var SessionUserOutputSchema = z.object({
|
|
82
|
+
id: z.string().uuid(),
|
|
83
|
+
email: z.email(),
|
|
84
|
+
firstName: z.string(),
|
|
85
|
+
lastName: z.string(),
|
|
86
|
+
activeBranchId: z.string().uuid(),
|
|
87
|
+
roles: z.array(SessionUserRoleSchema),
|
|
88
|
+
subRoles: z.array(SessionUserSubRoleSchema),
|
|
89
|
+
isActive: z.boolean(),
|
|
90
|
+
mustChangePassword: z.boolean()
|
|
91
|
+
});
|
|
92
|
+
var LoginInputSchema = z.object({
|
|
93
|
+
email: z.email().meta({ description: "User email address" }),
|
|
94
|
+
password: z.string().min(1).meta({ description: "Plain-text password (sent over TLS)" }),
|
|
95
|
+
branchId: z.string().uuid().optional().meta({
|
|
122
96
|
description: "Branch to activate on login; defaults to user primary branch"
|
|
123
97
|
})
|
|
124
98
|
});
|
|
125
|
-
var LoginOutputSchema =
|
|
126
|
-
accessToken:
|
|
127
|
-
refreshToken:
|
|
128
|
-
expiresIn:
|
|
99
|
+
var LoginOutputSchema = z.object({
|
|
100
|
+
accessToken: z.string().meta({ description: "Short-lived JWT (15 min)" }),
|
|
101
|
+
refreshToken: z.string().meta({ description: "Long-lived opaque refresh token (7 days)" }),
|
|
102
|
+
expiresIn: z.int().positive().meta({ description: "Access token TTL in seconds" }),
|
|
129
103
|
user: SessionUserOutputSchema
|
|
130
104
|
});
|
|
131
|
-
var RefreshTokenInputSchema =
|
|
132
|
-
refreshToken:
|
|
105
|
+
var RefreshTokenInputSchema = z.object({
|
|
106
|
+
refreshToken: z.string().min(1)
|
|
133
107
|
});
|
|
134
|
-
var RefreshTokenOutputSchema =
|
|
135
|
-
accessToken:
|
|
136
|
-
expiresIn:
|
|
108
|
+
var RefreshTokenOutputSchema = z.object({
|
|
109
|
+
accessToken: z.string(),
|
|
110
|
+
expiresIn: z.int().positive()
|
|
137
111
|
});
|
|
138
|
-
var LogoutInputSchema =
|
|
139
|
-
refreshToken:
|
|
112
|
+
var LogoutInputSchema = z.object({
|
|
113
|
+
refreshToken: z.string().min(1).meta({
|
|
140
114
|
description: "The refresh token to revoke; also invalidated server-side"
|
|
141
115
|
})
|
|
142
116
|
});
|
|
143
|
-
var ChangePasswordInputSchema =
|
|
144
|
-
currentPassword:
|
|
145
|
-
newPassword:
|
|
146
|
-
confirmPassword:
|
|
117
|
+
var ChangePasswordInputSchema = z.object({
|
|
118
|
+
currentPassword: z.string().min(1),
|
|
119
|
+
newPassword: z.string().min(8, { error: "Password must be at least 8 characters" }),
|
|
120
|
+
confirmPassword: z.string().min(1)
|
|
147
121
|
}).refine((v) => v.newPassword === v.confirmPassword, {
|
|
148
122
|
error: "Passwords do not match",
|
|
149
123
|
path: ["confirmPassword"]
|
|
150
124
|
});
|
|
151
|
-
var RequestPasswordResetInputSchema =
|
|
152
|
-
email:
|
|
125
|
+
var RequestPasswordResetInputSchema = z.object({
|
|
126
|
+
email: z.email()
|
|
153
127
|
});
|
|
154
|
-
var ResetPasswordInputSchema =
|
|
155
|
-
token:
|
|
156
|
-
newPassword:
|
|
157
|
-
confirmPassword:
|
|
128
|
+
var ResetPasswordInputSchema = z.object({
|
|
129
|
+
token: z.string().min(1).meta({ description: "One-time reset token from email link" }),
|
|
130
|
+
newPassword: z.string().min(8, { error: "Password must be at least 8 characters" }),
|
|
131
|
+
confirmPassword: z.string().min(1)
|
|
158
132
|
}).refine((v) => v.newPassword === v.confirmPassword, {
|
|
159
133
|
error: "Passwords do not match",
|
|
160
134
|
path: ["confirmPassword"]
|
|
161
135
|
});
|
|
162
|
-
var SwitchBranchInputSchema =
|
|
163
|
-
branchId:
|
|
136
|
+
var SwitchBranchInputSchema = z.object({
|
|
137
|
+
branchId: z.string().uuid().meta({ description: "Branch to switch the active session to" })
|
|
164
138
|
});
|
|
165
139
|
|
|
166
140
|
// src/contracts/auth.ts
|
|
167
|
-
var EmptyOutputSchema =
|
|
141
|
+
var EmptyOutputSchema = z2.object({}).meta({ description: "Empty success response" });
|
|
168
142
|
var loginContract = import_contract.oc.route({ method: "POST", path: "/auth/login" }).input(LoginInputSchema).output(LoginOutputSchema);
|
|
169
143
|
var refreshTokenContract = import_contract.oc.route({ method: "POST", path: "/auth/refresh" }).input(RefreshTokenInputSchema).output(RefreshTokenOutputSchema);
|
|
170
144
|
var logoutContract = import_contract.oc.route({ method: "POST", path: "/auth/logout" }).input(LogoutInputSchema).output(EmptyOutputSchema);
|
|
@@ -188,6 +162,30 @@ var authContract = {
|
|
|
188
162
|
var import_contract2 = require("@orpc/contract");
|
|
189
163
|
var z5 = __toESM(require("zod"), 1);
|
|
190
164
|
|
|
165
|
+
// src/schemas/base.ts
|
|
166
|
+
var z3 = __toESM(require("zod"), 1);
|
|
167
|
+
var CuidSchema = z3.string().regex(/^[a-z][a-z0-9]{24}$/, "Invalid cuid2 identifier").meta({ description: "cuid2 \u2014 prefixed, collision-resistant identifier" });
|
|
168
|
+
var UuidSchema = z3.uuidv4().meta({ description: "RFC-4122 UUID v4" });
|
|
169
|
+
var IsoDatetime = z3.iso.datetime();
|
|
170
|
+
var TimestampsSchema = z3.object({
|
|
171
|
+
createdAt: IsoDatetime.meta({ description: "ISO-8601 creation time (UTC)" }),
|
|
172
|
+
updatedAt: IsoDatetime.meta({ description: "ISO-8601 last update time (UTC)" })
|
|
173
|
+
});
|
|
174
|
+
var SoftDeleteSchema = z3.object({
|
|
175
|
+
deletedAt: IsoDatetime.nullable().meta({
|
|
176
|
+
description: "Set when the record is soft-deleted; null if active"
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
var PaginationInputSchema = z3.object({
|
|
180
|
+
cursor: CuidSchema.optional().meta({
|
|
181
|
+
description: "Opaque cursor from the previous page response"
|
|
182
|
+
}),
|
|
183
|
+
limit: z3.int().min(1).max(100).default(20).meta({ description: "Number of items to return (1\u2013100, default 20)" })
|
|
184
|
+
});
|
|
185
|
+
var BranchRefSchema = z3.object({
|
|
186
|
+
branchId: CuidSchema.meta({ description: "The branch this record belongs to" })
|
|
187
|
+
});
|
|
188
|
+
|
|
191
189
|
// src/schemas/hr.ts
|
|
192
190
|
var z4 = __toESM(require("zod"), 1);
|
|
193
191
|
var EmploymentTypeSchema = z4.enum([
|