package database // TimetableSolutionMigrations creates tt_solution + tt_lesson for the solver // pipeline. One run of the solver produces exactly one tt_solution row plus // many tt_lesson rows (one per scheduled class-subject hour). // // Status flow: // // pending → running → completed | failed | infeasible // // hard_score / soft_score come straight from Timefold's HardSoftScore. Lower // (more negative) hard_score means more hard-constraint violations; the UI // only ever offers solutions with hard_score == 0 as "valid". func TimetableSolutionMigrations() []string { return []string{ `CREATE TABLE IF NOT EXISTS tt_solution ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_by_user_id UUID NOT NULL, name VARCHAR(120), status VARCHAR(20) NOT NULL DEFAULT 'pending', hard_score INT, soft_score INT, error_message TEXT, started_at TIMESTAMPTZ, finished_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() )`, `CREATE TABLE IF NOT EXISTS tt_lesson ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), solution_id UUID NOT NULL REFERENCES tt_solution(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, teacher_id UUID NOT NULL REFERENCES tt_teacher(id) ON DELETE CASCADE, room_id UUID REFERENCES tt_room(id) ON DELETE SET NULL, day_of_week INT NOT NULL CHECK (day_of_week BETWEEN 1 AND 7), period_index INT NOT NULL CHECK (period_index BETWEEN 1 AND 12), pinned BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(solution_id, class_id, day_of_week, period_index), UNIQUE(solution_id, teacher_id, day_of_week, period_index), UNIQUE(solution_id, room_id, day_of_week, period_index) )`, `CREATE INDEX IF NOT EXISTS idx_tt_solution_user ON tt_solution(created_by_user_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_lesson_solution ON tt_lesson(solution_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_lesson_class ON tt_lesson(class_id)`, `CREATE INDEX IF NOT EXISTS idx_tt_lesson_teacher ON tt_lesson(teacher_id)`, // Phase 7: plan versioning + per-solve solver-timeout override. `ALTER TABLE tt_solution ADD COLUMN IF NOT EXISTS parent_solution_id UUID REFERENCES tt_solution(id) ON DELETE SET NULL`, `ALTER TABLE tt_solution ADD COLUMN IF NOT EXISTS seconds_limit INT`, } }