package assessment import ( dbgen "Yimaru-Backend/gen/db" "Yimaru-Backend/internal/domain" "context" "errors" "encoding/json" "github.com/jackc/pgx/v5/pgtype" ) func (s *Service) CreateQuestion( ctx context.Context, input domain.CreateAssessmentQuestionInput, ) error { repo := s.initialAssessmentStore // 1. Create Question question, err := repo.CreateAssessmentQuestion( ctx, dbgen.CreateAssessmentQuestionParams{ Title: input.Title, Description: func() pgtype.Text { ns := toNullString(input.Description) return pgtype.Text{String: ns.String, Valid: ns.Valid} }(), QuestionType: string(input.QuestionType), DifficultyLevel: pgtype.Text{String: input.DifficultyLevel}, Points: input.Points, IsActive: input.IsActive, }, ) if err != nil { return err } // 2. Branch by Question Type switch input.QuestionType { case domain.MultipleChoice: if len(input.Options) == 0 { return errors.New("multiple choice question requires options") } for _, opt := range input.Options { _, err := repo.CreateQuestionOption( ctx, dbgen.CreateQuestionOptionParams{ QuestionID: question.ID, OptionText: opt.Text, OptionOrder: opt.Order, IsCorrect: opt.IsCorrect, }, ) if err != nil { return err } } case domain.TrueFalse: // TRUE if _, err := repo.CreateQuestionOption( ctx, dbgen.CreateQuestionOptionParams{ QuestionID: question.ID, OptionText: "True", OptionOrder: 1, IsCorrect: true, }, ); err != nil { return err } // FALSE if _, err := repo.CreateQuestionOption( ctx, dbgen.CreateQuestionOptionParams{ QuestionID: question.ID, OptionText: "False", OptionOrder: 2, IsCorrect: false, }, ); err != nil { return err } case domain.ShortAnswer: if input.CorrectAnswer == nil || *input.CorrectAnswer == "" { return errors.New("short answer question requires correct_answer") } _, err := repo.CreateShortAnswer( ctx, dbgen.CreateShortAnswerParams{ QuestionID: question.ID, CorrectAnswer: *input.CorrectAnswer, }, ) if err != nil { return err } default: return errors.New("unsupported question type") } return nil } func (s *Service) ListQuestions(ctx context.Context) ([]domain.QuestionWithDetails, error) { // repo := s.initialAssessmentStore questions, err := s.initialAssessmentStore.GetActiveAssessmentQuestions(ctx) if err != nil { return nil, err } out := make([]domain.QuestionWithDetails, 0, len(questions)) for _, q := range questions { var dq domain.AssessmentQuestion b, err := json.Marshal(q) if err != nil { return nil, err } if err := json.Unmarshal(b, &dq); err != nil { return nil, err } item := domain.QuestionWithDetails{Question: dq} switch domain.QuestionType(q.QuestionType) { case domain.MultipleChoice, domain.TrueFalse: opts, err := s.initialAssessmentStore.GetQuestionOptions(ctx, q.ID) if err != nil { return nil, err } for _, opt := range opts { tempOpt := domain.QuestionOption{ QuestionID: opt.ID, OptionText: opt.OptionText, } item.Options = append(item.Options, tempOpt) } // case domain.ShortAnswer: // sa, err := s.initialAssessmentStore.GetShortAnswerByQuestionID(ctx, q.ID) // if err != nil { // return nil, err // } // item.ShortAnswer = &sa // } out = append(out, item) } } return out, nil } func (s *Service) GetQuestionByID(ctx context.Context, id int64) (domain.QuestionWithDetails, error) { repo := s.initialAssessmentStore q, err := repo.GetAssessmentQuestionByID(ctx, id) if err != nil { return domain.QuestionWithDetails{}, err } var dq domain.AssessmentQuestion b, err := json.Marshal(q) if err != nil { return domain.QuestionWithDetails{}, err } if err := json.Unmarshal(b, &dq); err != nil { return domain.QuestionWithDetails{}, err } item := domain.QuestionWithDetails{Question: dq} switch domain.QuestionType(q.QuestionType) { case domain.MultipleChoice, domain.TrueFalse: opts, err := repo.GetQuestionOptions(ctx, q.ID) if err != nil { return domain.QuestionWithDetails{}, err } for _, opt := range opts { tempOpt := domain.QuestionOption{ QuestionID: opt.ID, OptionText: opt.OptionText, } item.Options = append(item.Options, tempOpt) } // case domain.ShortAnswer: // sa, err := repo.GetShortAnswerByQuestionID(ctx, q.ID) // if err != nil { // return QuestionWithDetails{}, err // } // item.ShortAnswer = &sa } return item, nil } // func (s *Service) UpdateQuestion(ctx context.Context, id int64, input domain.UpdateAssessmentQuestionInput) error { // repo := s.initialAssessmentStore // // fetch existing // existing, err := repo.GetAssessmentQuestionByID(ctx, id) // if err != nil { // return err // } // // update base question // _, err = repo.UpdateAssessmentQuestion( // ctx, // dbgen.UpdateAssessmentQuestionParams{ // ID: id, // Title: input.Title, // Description: func() pgtype.Text { // ns := toNullString(input.Description) // return pgtype.Text{String: ns.String, Valid: ns.Valid} // }(), // QuestionType: string(input.QuestionType), // DifficultyLevel: pgtype.Text{String: input.DifficultyLevel}, // Points: input.Points, // IsActive: input.IsActive, // }, // ) // if err != nil { // return err // } // // remove previous dependents (safe to remove regardless of new type) // // try delete options and short answer; ignore not-found errors if repo returns them // if err := repo.DeleteQuestionOptionsByQuestionID(ctx, id); err != nil { // return err // } // if err := repo.DeleteShortAnswerByQuestionID(ctx, id); err != nil { // return err // } // // create dependents for new type // switch input.QuestionType { // case domain.MultipleChoice: // if len(input.Options) == 0 { // return errors.New("multiple choice question requires options") // } // for _, opt := range input.Options { // if _, err := repo.CreateQuestionOption( // ctx, // dbgen.CreateQuestionOptionParams{ // QuestionID: id, // OptionText: opt.Text, // OptionOrder: opt.Order, // IsCorrect: opt.IsCorrect, // }, // ); err != nil { // return err // } // } // case domain.TrueFalse: // if _, err := repo.CreateQuestionOption(ctx, dbgen.CreateQuestionOptionParams{ // QuestionID: id, // OptionText: "True", // OptionOrder: 1, // IsCorrect: true, // }); err != nil { // return err // } // if _, err := repo.CreateQuestionOption(ctx, dbgen.CreateQuestionOptionParams{ // QuestionID: id, // OptionText: "False", // OptionOrder: 2, // IsCorrect: false, // }); err != nil { // return err // } // case domain.ShortAnswer: // if input.CorrectAnswer == nil || *input.CorrectAnswer == "" { // return errors.New("short answer question requires correct_answer") // } // if _, err := repo.CreateShortAnswer(ctx, dbgen.CreateShortAnswerParams{ // QuestionID: id, // CorrectAnswer: *input.CorrectAnswer, // }); err != nil { // return err // } // default: // return errors.New("unsupported question type") // } // _ = existing // return nil // } // func (s *Service) DeleteQuestion(ctx context.Context, id int64) error { // repo := s.initialAssessmentStore // q, err := repo.GetAssessmentQuestionByID(ctx, id) // if err != nil { // return err // } // // delete dependents by existing type // switch domain.QuestionType(q.QuestionType) { // case domain.MultipleChoice, domain.TrueFalse: // if err := repo.DeleteQuestionOptionsByQuestionID(ctx, id); err != nil { // return err // } // case domain.ShortAnswer: // if err := repo.DeleteShortAnswerByQuestionID(ctx, id); err != nil { // return err // } // } // if err := repo.DeleteAssessmentQuestion(ctx, id); err != nil { // return err // } // return nil // } // ...existing code...