Add lessons domain Phase 1: instructor and lesson type entities
Foundation tables for the lessons module with full CRUD, pagination, search, and sorting. Includes migration, Drizzle schema, Zod validation, services, routes, and 23 integration tests.
This commit is contained in:
38
packages/shared/src/schemas/lessons.schema.ts
Normal file
38
packages/shared/src/schemas/lessons.schema.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
/** Coerce empty strings to undefined — solves HTML form inputs sending '' for blank optional fields */
|
||||
function opt<T extends z.ZodTypeAny>(schema: T) {
|
||||
return z.preprocess((v) => (v === '' ? undefined : v), schema.optional())
|
||||
}
|
||||
|
||||
// --- Enums ---
|
||||
|
||||
export const LessonFormat = z.enum(['private', 'group'])
|
||||
export type LessonFormat = z.infer<typeof LessonFormat>
|
||||
|
||||
// --- Instructor schemas ---
|
||||
|
||||
export const InstructorCreateSchema = z.object({
|
||||
userId: opt(z.string().uuid()),
|
||||
displayName: z.string().min(1).max(255),
|
||||
bio: opt(z.string()),
|
||||
instruments: z.array(z.string()).optional(),
|
||||
})
|
||||
export type InstructorCreateInput = z.infer<typeof InstructorCreateSchema>
|
||||
|
||||
export const InstructorUpdateSchema = InstructorCreateSchema.partial()
|
||||
export type InstructorUpdateInput = z.infer<typeof InstructorUpdateSchema>
|
||||
|
||||
// --- Lesson Type schemas ---
|
||||
|
||||
export const LessonTypeCreateSchema = z.object({
|
||||
name: z.string().min(1).max(255),
|
||||
instrument: opt(z.string().max(100)),
|
||||
durationMinutes: z.coerce.number().int().min(5).max(480),
|
||||
lessonFormat: LessonFormat.default('private'),
|
||||
baseRateMonthly: z.coerce.number().min(0).optional(),
|
||||
})
|
||||
export type LessonTypeCreateInput = z.infer<typeof LessonTypeCreateSchema>
|
||||
|
||||
export const LessonTypeUpdateSchema = LessonTypeCreateSchema.partial()
|
||||
export type LessonTypeUpdateInput = z.infer<typeof LessonTypeUpdateSchema>
|
||||
Reference in New Issue
Block a user