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:
Ryan Moon
2026-03-30 09:17:32 -05:00
parent 145eb0efce
commit 5dbe837c08
10 changed files with 603 additions and 1 deletions

View File

@@ -0,0 +1,47 @@
import {
pgTable,
uuid,
varchar,
text,
timestamp,
boolean,
integer,
pgEnum,
} from 'drizzle-orm/pg-core'
import { users } from './users.js'
// --- Enums ---
export const lessonFormatEnum = pgEnum('lesson_format', ['private', 'group'])
// --- Tables ---
export const instructors = pgTable('instructor', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').references(() => users.id),
displayName: varchar('display_name', { length: 255 }).notNull(),
bio: text('bio'),
instruments: text('instruments').array(),
isActive: boolean('is_active').notNull().default(true),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})
export const lessonTypes = pgTable('lesson_type', {
id: uuid('id').primaryKey().defaultRandom(),
name: varchar('name', { length: 255 }).notNull(),
instrument: varchar('instrument', { length: 100 }),
durationMinutes: integer('duration_minutes').notNull(),
lessonFormat: lessonFormatEnum('lesson_format').notNull().default('private'),
baseRateMonthly: varchar('base_rate_monthly', { length: 20 }),
isActive: boolean('is_active').notNull().default(true),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
})
// --- Type exports ---
export type Instructor = typeof instructors.$inferSelect
export type InstructorInsert = typeof instructors.$inferInsert
export type LessonType = typeof lessonTypes.$inferSelect
export type LessonTypeInsert = typeof lessonTypes.$inferInsert