package database // TimetableMigrations returns the SQL statements that create all timetable-related // tables. They are applied idempotently via CREATE TABLE IF NOT EXISTS. func TimetableMigrations() []string { return []string{ // Classes (school-wide, distinct from per-teacher `classes` table) `CREATE TABLE IF NOT EXISTS tt_class ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, name VARCHAR(50) NOT NULL, grade_level INT NOT NULL, student_count INT DEFAULT 0, notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(created_by_user_id, name) )`, // Time periods (Mon=1..Sun=7, period_index = 1..N) `CREATE TABLE IF NOT EXISTS tt_period ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, day_of_week INT NOT NULL CHECK (day_of_week BETWEEN 1 AND 7), period_index INT NOT NULL CHECK (period_index >= 1), start_time TIME NOT NULL, end_time TIME NOT NULL, is_break BOOLEAN DEFAULT false, label VARCHAR(50), created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(created_by_user_id, day_of_week, period_index) )`, // Rooms `CREATE TABLE IF NOT EXISTS tt_room ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, name VARCHAR(50) NOT NULL, room_type VARCHAR(30), capacity INT DEFAULT 30, floor_level INT DEFAULT 0, has_elevator BOOLEAN DEFAULT true, notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(created_by_user_id, name) )`, // Subjects (school-wide, distinct from per-teacher `subjects`) `CREATE TABLE IF NOT EXISTS tt_subject ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, name VARCHAR(100) NOT NULL, short_code VARCHAR(10) NOT NULL, color VARCHAR(7), is_main_subject BOOLEAN DEFAULT false, required_room_type VARCHAR(30), created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(created_by_user_id, short_code) )`, // Teachers (planning resource, NOT a BreakPilot user) `CREATE TABLE IF NOT EXISTS tt_teacher ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, short_code VARCHAR(10) NOT NULL, employment_percentage INT DEFAULT 100, max_hours_week INT DEFAULT 28, notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(created_by_user_id, short_code) )`, // Curriculum: weekly hour count per class+subject `CREATE TABLE IF NOT EXISTS tt_curriculum ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), class_id UUID NOT NULL REFERENCES tt_class(id) ON DELETE CASCADE, subject_id UUID NOT NULL REFERENCES tt_subject(id) ON DELETE CASCADE, weekly_hours INT NOT NULL CHECK (weekly_hours >= 1), created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(class_id, subject_id) )`, // Assignment: which teacher teaches which subject in which class `CREATE TABLE IF NOT EXISTS tt_assignment ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), teacher_id UUID NOT NULL REFERENCES tt_teacher(id) ON DELETE CASCADE, class_id UUID NOT NULL REFERENCES tt_class(id) ON DELETE CASCADE, subject_id UUID NOT NULL REFERENCES tt_subject(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(teacher_id, class_id, subject_id) )`, // Indexes `CREATE INDEX IF NOT EXISTS idx_tt_class_user ON tt_class(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_period_user ON tt_period(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_room_user ON tt_room(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_subject_user ON tt_subject(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_teacher_user ON tt_teacher(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_curriculum_class ON tt_curriculum(class_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_assignment_teacher ON tt_assignment(teacher_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_assignment_class ON tt_assignment(class_id)`, } }