Implement Feedback Management System with CRUD Operations and API Enhancements
- Introduced a new feedback management system, including the creation of feedback entities, services, and repositories. - Implemented CRUD operations for feedback, allowing users to submit likes and dislikes on tenders. - Developed administrative endpoints for listing and retrieving feedback with comprehensive filtering options. - Enhanced public API to allow users to view feedback related to tenders. - Updated Swagger documentation to reflect new feedback endpoints and their functionalities. - Removed obsolete configuration file `config.yaml` as part of the transition to a modular configuration system. - Ensured adherence to Clean Architecture principles throughout the implementation.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
package feedback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/response"
|
||||
)
|
||||
|
||||
// FeedbackService interface defines feedback business logic methods
|
||||
type FeedbackService interface {
|
||||
ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error)
|
||||
GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error)
|
||||
ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error)
|
||||
DeleteFeedback(ctx context.Context, id string) error
|
||||
}
|
||||
|
||||
// feedbackService implements FeedbackService interface
|
||||
type feedbackService struct {
|
||||
feedbackRepo Repository
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
// NewFeedbackService creates a new feedback service
|
||||
func NewFeedbackService(feedbackRepo Repository, logger logger.Logger) FeedbackService {
|
||||
return &feedbackService{
|
||||
feedbackRepo: feedbackRepo,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *feedbackService) ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error) {
|
||||
existing, err := s.feedbackRepo.GetByCompanyID(ctx, *companyID, req.TenderID)
|
||||
|
||||
if err != nil {
|
||||
feedback := &Feedback{
|
||||
TenderID: req.TenderID,
|
||||
FeedbackType: req.FeedbackType,
|
||||
CompanyID: companyID,
|
||||
CustomerID: customerID,
|
||||
}
|
||||
|
||||
err = s.feedbackRepo.Create(ctx, feedback)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to create new feedback", map[string]interface{}{
|
||||
"tender_id": req.TenderID,
|
||||
"company_id": *companyID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return feedback.ToResponse(), nil
|
||||
}
|
||||
|
||||
if existing.FeedbackType == FeedbackTypeLike {
|
||||
existing.FeedbackType = FeedbackTypeDislike
|
||||
} else {
|
||||
existing.FeedbackType = FeedbackTypeLike
|
||||
}
|
||||
|
||||
err = s.feedbackRepo.Update(ctx, existing)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update existing feedback", map[string]interface{}{
|
||||
"feedback_id": existing.GetID(),
|
||||
"tender_id": req.TenderID,
|
||||
"company_id": *companyID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return existing.ToResponse(), nil
|
||||
}
|
||||
|
||||
func (s *feedbackService) GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error) {
|
||||
feedback, err := s.feedbackRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get feedback", map[string]interface{}{
|
||||
"id": id,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return feedback.ToResponse(), nil
|
||||
}
|
||||
|
||||
func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error) {
|
||||
feedbacks, total, err := s.feedbackRepo.List(ctx, criteria, limit, offset)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to list feedback", map[string]interface{}{
|
||||
"criteria": criteria,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
meta := &response.Meta{
|
||||
Total: int(total),
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Page: (offset / limit) + 1,
|
||||
Pages: int((total + int64(limit) - 1) / int64(limit)),
|
||||
}
|
||||
|
||||
result := make([]*FeedbackResponse, len(feedbacks))
|
||||
for i, feedback := range feedbacks {
|
||||
result[i] = feedback.ToResponse()
|
||||
}
|
||||
return &FeedbackListResponse{
|
||||
Feedback: result,
|
||||
Meta: meta,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *feedbackService) DeleteFeedback(ctx context.Context, id string) error {
|
||||
return s.feedbackRepo.Delete(ctx, id)
|
||||
}
|
||||
Reference in New Issue
Block a user