sno-quiz/backend/internal/service/question_service.go
2025-09-17 22:22:14 +03:00

91 lines
2.8 KiB
Go

package service
import (
"context"
"errors"
"sno/internal/models"
"sno/internal/repository"
)
// QuestionService defines the interface for question-related business logic.
type QuestionService interface {
CreateQuestion(ctx context.Context, question *models.Question) (*models.Question, error)
GetQuestionByID(ctx context.Context, id int) (*models.Question, error)
UpdateQuestion(ctx context.Context, id int, question *models.Question) (*models.Question, error)
DeleteQuestion(ctx context.Context, id int) error
}
// questionService implements the QuestionService interface.
type questionService struct {
questionRepo repository.QuestionRepository
}
// NewQuestionService creates a new instance of a question service.
func NewQuestionService(questionRepo repository.QuestionRepository) QuestionService {
return &questionService{questionRepo: questionRepo}
}
// CreateQuestion handles the business logic for creating a new question.
func (s *questionService) CreateQuestion(ctx context.Context, question *models.Question) (*models.Question, error) {
// Basic validation
if question.Text == "" {
return nil, errors.New("question text cannot be empty")
}
if len(question.Options) < 2 {
return nil, errors.New("question must have at least two options")
}
correctAnswers := 0
for _, opt := range question.Options {
if opt.IsCorrect {
correctAnswers++
}
}
if correctAnswers == 0 {
return nil, errors.New("question must have at least one correct answer")
}
if question.Type == models.Single && correctAnswers > 1 {
return nil, errors.New("single choice question cannot have multiple correct answers")
}
return s.questionRepo.Create(ctx, question)
}
// GetQuestionByID retrieves a question by its ID.
func (s *questionService) GetQuestionByID(ctx context.Context, id int) (*models.Question, error) {
return s.questionRepo.GetByID(ctx, id)
}
// UpdateQuestion handles the business logic for updating an existing question.
func (s *questionService) UpdateQuestion(ctx context.Context, id int, question *models.Question) (*models.Question, error) {
// Basic validation
if question.Text == "" {
return nil, errors.New("question text cannot be empty")
}
if len(question.Options) < 2 {
return nil, errors.New("question must have at least two options")
}
correctAnswers := 0
for _, opt := range question.Options {
if opt.IsCorrect {
correctAnswers++
}
}
if correctAnswers == 0 {
return nil, errors.New("question must have at least one correct answer")
}
if question.Type == models.Single && correctAnswers > 1 {
return nil, errors.New("single choice question cannot have multiple correct answers")
}
return s.questionRepo.Update(ctx, id, question)
}
// DeleteQuestion handles the business logic for deleting a question.
func (s *questionService) DeleteQuestion(ctx context.Context, id int) error {
return s.questionRepo.Delete(ctx, id)
}