package models import ( "time" "github.com/google/uuid" ) // TimetableSolution is one run of the solver — exactly one row per solve. // Lessons attached via tt_lesson.solution_id. type TimetableSolution struct { ID uuid.UUID `json:"id" db:"id"` CreatedByUserID uuid.UUID `json:"created_by_user_id" db:"created_by_user_id"` Name string `json:"name,omitempty" db:"name"` Status string `json:"status" db:"status"` HardScore *int `json:"hard_score,omitempty" db:"hard_score"` SoftScore *int `json:"soft_score,omitempty" db:"soft_score"` ErrorMessage string `json:"error_message,omitempty" db:"error_message"` StartedAt *time.Time `json:"started_at,omitempty" db:"started_at"` FinishedAt *time.Time `json:"finished_at,omitempty" db:"finished_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` ParentSolutionID *uuid.UUID `json:"parent_solution_id,omitempty" db:"parent_solution_id"` SecondsLimit *int `json:"seconds_limit,omitempty" db:"seconds_limit"` } // TimetableLesson is one scheduled class-period in a solution. type TimetableLesson struct { ID uuid.UUID `json:"id" db:"id"` SolutionID uuid.UUID `json:"solution_id" db:"solution_id"` ClassID uuid.UUID `json:"class_id" db:"class_id"` SubjectID uuid.UUID `json:"subject_id" db:"subject_id"` TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"` RoomID *uuid.UUID `json:"room_id,omitempty" db:"room_id"` DayOfWeek int `json:"day_of_week" db:"day_of_week"` PeriodIndex int `json:"period_index" db:"period_index"` Pinned bool `json:"pinned" db:"pinned"` CreatedAt time.Time `json:"created_at" db:"created_at"` // Joined fields for display ClassName string `json:"class_name,omitempty"` SubjectName string `json:"subject_name,omitempty"` TeacherName string `json:"teacher_name,omitempty"` RoomName string `json:"room_name,omitempty"` } // CreateTimetableSolutionRequest kicks off a solve. The solver-service is // invoked async — this endpoint only registers the solution row and queues // the job. // // ParentSolutionID, if set, instructs the solver to seed the new problem // with the parent solution's pinned lessons (Phase 7 plan versioning). // SecondsLimit overrides the default 60s solver budget. type CreateTimetableSolutionRequest struct { Name string `json:"name"` ParentSolutionID *string `json:"parent_solution_id,omitempty" binding:"omitempty,uuid"` SecondsLimit *int `json:"seconds_limit,omitempty" binding:"omitempty,min=5,max=600"` } // UpdateLessonPinRequest toggles tt_lesson.pinned. Used by the Plan view's // pin/unpin button. type UpdateLessonPinRequest struct { Pinned bool `json:"pinned"` }