package faqs import ( "Yimaru-Backend/internal/domain" "Yimaru-Backend/internal/ports" "context" "fmt" "strings" ) type Service struct { faqStore ports.FAQStore } func NewService(faqStore ports.FAQStore) *Service { return &Service{faqStore: faqStore} } func normalizeFAQStatus(status *string) (string, error) { if status == nil || strings.TrimSpace(*status) == "" { return domain.FAQStatusActive, nil } value := strings.ToUpper(strings.TrimSpace(*status)) switch value { case domain.FAQStatusActive, domain.FAQStatusInactive: return value, nil default: return "", fmt.Errorf("status must be one of %s, %s", domain.FAQStatusActive, domain.FAQStatusInactive) } } func (s *Service) CreateFAQ(ctx context.Context, input domain.CreateFAQInput) (domain.FAQ, error) { input.Question = strings.TrimSpace(input.Question) input.Answer = strings.TrimSpace(input.Answer) if input.Question == "" { return domain.FAQ{}, fmt.Errorf("question is required") } if input.Answer == "" { return domain.FAQ{}, fmt.Errorf("answer is required") } if input.Category != nil { c := strings.TrimSpace(*input.Category) if c == "" { input.Category = nil } else { input.Category = &c } } status, err := normalizeFAQStatus(input.Status) if err != nil { return domain.FAQ{}, err } input.Status = &status return s.faqStore.CreateFAQ(ctx, input) } func (s *Service) UpdateFAQ(ctx context.Context, id int64, input domain.UpdateFAQInput) (domain.FAQ, error) { if id <= 0 { return domain.FAQ{}, fmt.Errorf("invalid faq id") } if input.Question != nil { trimmed := strings.TrimSpace(*input.Question) if trimmed == "" { return domain.FAQ{}, fmt.Errorf("question cannot be empty") } input.Question = &trimmed } if input.Answer != nil { trimmed := strings.TrimSpace(*input.Answer) if trimmed == "" { return domain.FAQ{}, fmt.Errorf("answer cannot be empty") } input.Answer = &trimmed } if input.Category != nil { c := strings.TrimSpace(*input.Category) input.Category = &c } if input.Status != nil { status, err := normalizeFAQStatus(input.Status) if err != nil { return domain.FAQ{}, err } input.Status = &status } return s.faqStore.UpdateFAQ(ctx, id, input) } func (s *Service) GetFAQByID(ctx context.Context, id int64, includeInactive bool) (domain.FAQ, error) { if id <= 0 { return domain.FAQ{}, fmt.Errorf("invalid faq id") } return s.faqStore.GetFAQByID(ctx, id, includeInactive) } func (s *Service) ListFAQs(ctx context.Context, status *string, category *string, limit int32, offset int32) ([]domain.FAQ, int64, error) { if status != nil { normalized, err := normalizeFAQStatus(status) if err != nil { return nil, 0, err } status = &normalized } if category != nil { trimmed := strings.TrimSpace(*category) if trimmed == "" { category = nil } else { category = &trimmed } } if limit <= 0 { limit = 20 } if limit > 200 { limit = 200 } if offset < 0 { offset = 0 } return s.faqStore.ListFAQs(ctx, status, category, limit, offset) } func (s *Service) DeleteFAQ(ctx context.Context, id int64) error { if id <= 0 { return fmt.Errorf("invalid faq id") } return s.faqStore.DeleteFAQ(ctx, id) }