All files / web/src/db/schema classrooms.ts

88.13% Statements 52/59
100% Branches 2/2
50% Functions 1/2
88.13% Lines 52/59

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 602x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 43x 43x 43x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x                
import { createId } from '@paralleldrive/cuid2'
import { index, integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
import { users } from './users'
 
/**
 * Classrooms table - teacher's persistent space for students
 *
 * Each teacher has exactly one classroom (enforced by unique constraint on teacherId).
 * Students enroll in classrooms and can be "present" for live sessions.
 */
export const classrooms = sqliteTable(
  'classrooms',
  {
    /** Primary key */
    id: text('id')
      .primaryKey()
      .$defaultFn(() => createId()),
 
    /** Teacher who owns this classroom (one classroom per teacher) */
    teacherId: text('teacher_id')
      .notNull()
      .unique()
      .references(() => users.id, { onDelete: 'cascade' }),
 
    /** Classroom display name */
    name: text('name').notNull(),
 
    /** Join code for enrollment (e.g., "MATH-4B") */
    code: text('code').notNull().unique(),
 
    /** When this classroom was created */
    createdAt: integer('created_at', { mode: 'timestamp' })
      .notNull()
      .$defaultFn(() => new Date()),
 
    /** Default expiry time for entry prompts (in minutes). Null = use system default (30 min) */
    entryPromptExpiryMinutes: integer('entry_prompt_expiry_minutes'),
  },
  (table) => ({
    /** Index for looking up classroom by code */
    codeIdx: index('classrooms_code_idx').on(table.code),
  })
)
 
export type Classroom = typeof classrooms.$inferSelect
export type NewClassroom = typeof classrooms.$inferInsert
 
/**
 * Generate a unique classroom code
 * Format: 4-6 uppercase alphanumeric characters (no confusing chars like 0/O, 1/I)
 */
export function generateClassroomCode(): string {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
  let code = ''
  for (let i = 0; i < 6; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return code
}