Add lessons Phase 5: grading scales with nested levels

Custom grading scales with ordered levels (value, label, numeric score,
color). Supports one-default-per-store constraint, deep create with
nested levels, lookup endpoint for dropdowns, and search/pagination.
12 new tests (76 total lessons tests).
This commit is contained in:
Ryan Moon
2026-03-30 09:36:48 -05:00
parent 73360cd478
commit 31f661ff4f
8 changed files with 396 additions and 2 deletions

View File

@@ -116,6 +116,8 @@ export {
LessonSessionStatusUpdateSchema,
LessonSessionNotesSchema,
LessonSessionUpdateSchema,
GradingScaleCreateSchema,
GradingScaleUpdateSchema,
} from './lessons.schema.js'
export type {
InstructorCreateInput,
@@ -130,4 +132,6 @@ export type {
LessonSessionStatusUpdateInput,
LessonSessionNotesInput,
LessonSessionUpdateInput,
GradingScaleCreateInput,
GradingScaleUpdateInput,
} from './lessons.schema.js'

View File

@@ -106,3 +106,28 @@ export const LessonSessionUpdateSchema = z.object({
actualEndTime: opt(z.string().regex(/^\d{2}:\d{2}$/, 'Must be HH:MM format')),
})
export type LessonSessionUpdateInput = z.infer<typeof LessonSessionUpdateSchema>
// --- Grading Scale schemas ---
export const GradingScaleLevelInput = z.object({
value: z.string().min(1).max(50),
label: z.string().min(1).max(255),
numericValue: z.coerce.number().int().min(0).max(100),
colorHex: opt(z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Must be #RRGGBB format')),
sortOrder: z.coerce.number().int(),
})
export const GradingScaleCreateSchema = z.object({
name: z.string().min(1).max(255),
description: opt(z.string()),
isDefault: z.boolean().default(false),
levels: z.array(GradingScaleLevelInput).min(1),
})
export type GradingScaleCreateInput = z.infer<typeof GradingScaleCreateSchema>
export const GradingScaleUpdateSchema = z.object({
name: z.string().min(1).max(255).optional(),
description: opt(z.string()),
isDefault: z.boolean().optional(),
})
export type GradingScaleUpdateInput = z.infer<typeof GradingScaleUpdateSchema>