package assignmentgen import ( "context" "boostai-backend/internal/database" "boostai-backend/internal/questiongen" "boostai-backend/internal/sqlc" ) type SourceBucket string const ( SourceBucketCoreTopic SourceBucket = "core_topic" SourceBucketPersonalized SourceBucket = "personalized" defaultQuestionSource = "assignment_student_generated" ) type PlanItem struct { Topic sqlc.QuestionTopic Difficulty sqlc.QuestionDifficulty Count int SourceBucket SourceBucket Seed int64 } type GenerateStudentQuestionSetParams struct { AssignmentID int64 StudentID int64 TeacherID int64 Subject string QuestionStatus sqlc.QuestionStatus QuestionSource string Plan []PlanItem } type StoredStudentQuestion struct { Mapping sqlc.AssignmentStudentQuestion Question sqlc.Question Tags []string UsedSeed int64 SourceBucket string } type Service struct { db *database.DB generator *questiongen.Service } func NewService(db *database.DB, generator *questiongen.Service) *Service { return &Service{db: db, generator: generator} } func (s *Service) GenerateAndStoreStudentQuestions(ctx context.Context, params GenerateStudentQuestionSetParams) ([]StoredStudentQuestion, error) { if err := s.validateGenerateRequest(params); err != nil { return nil, err } tx, err := s.db.Pool.Begin(ctx) if err != nil { return nil, err } defer func() { _ = tx.Rollback(ctx) }() queries := sqlc.New(tx) if err := validateAssignmentOwnership(ctx, queries, params.AssignmentID, params.TeacherID); err != nil { return nil, err } if err := validateStudentAssignment(ctx, queries, params.AssignmentID, params.StudentID); err != nil { return nil, err } if err := clearStudentQuestionMappings(ctx, queries, params.AssignmentID, params.StudentID); err != nil { return nil, err } questionStatus, questionSource := normalizeQuestionDefaults(params) stored, err := s.generateAndStorePlan(ctx, queries, params, questionStatus, questionSource) if err != nil { return nil, err } if err := tx.Commit(ctx); err != nil { return nil, err } return stored, nil }