|
|
|
|
@@ -1,3 +1,134 @@
|
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"sort"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"route256/comments/internal/domain/entity"
|
|
|
|
|
"route256/comments/internal/domain/model"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type CommentRepository interface {
|
|
|
|
|
GetCommentByID(ctx context.Context, id int64) (*entity.Comment, error)
|
|
|
|
|
InsertComment(ctx context.Context, comment *entity.Comment) (*entity.Comment, error)
|
|
|
|
|
ListCommentsBySku(ctx context.Context, sku int64) ([]*entity.Comment, error)
|
|
|
|
|
ListCommentsByUser(ctx context.Context, userID int64) ([]*entity.Comment, error)
|
|
|
|
|
UpdateComment(ctx context.Context, comment *entity.Comment) (*entity.Comment, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommentsService struct {
|
|
|
|
|
comments CommentRepository
|
|
|
|
|
|
|
|
|
|
timeout time.Duration
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewCommentsService(commRepo CommentRepository, timeout time.Duration) *CommentsService {
|
|
|
|
|
return &CommentsService{
|
|
|
|
|
comments: commRepo,
|
|
|
|
|
timeout: timeout,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) checkTimeout(newTime, oldTime time.Time) error {
|
|
|
|
|
if newTime.Sub(oldTime) >= s.timeout {
|
|
|
|
|
return model.ErrCommentEditTimeout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) CommentCreate(ctx context.Context, comment *entity.Comment) (int64, error) {
|
|
|
|
|
comm, err := s.comments.InsertComment(ctx, &entity.Comment{
|
|
|
|
|
UserID: comment.UserID,
|
|
|
|
|
SKU: comment.SKU,
|
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
|
Text: comment.Text,
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, fmt.Errorf("repository.InsertComment: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return comm.ID, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) CommentGetByID(ctx context.Context, id int64) (*entity.Comment, error) {
|
|
|
|
|
if id <= 0 {
|
|
|
|
|
return nil, fmt.Errorf("comment id must be greater than 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comm, err := s.comments.GetCommentByID(ctx, id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("repository.InsertComment: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return comm, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) CommentEdit(ctx context.Context, newComment *entity.Comment) error {
|
|
|
|
|
if newComment.ID <= 0 {
|
|
|
|
|
return fmt.Errorf("comment id must be greater than 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oldComment, err := s.comments.GetCommentByID(ctx, newComment.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("repository.GetCommentByID: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if oldComment.UserID != newComment.UserID {
|
|
|
|
|
return model.ErrCommentEditUserMismatch
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comment := &entity.Comment{
|
|
|
|
|
ID: newComment.ID,
|
|
|
|
|
UserID: newComment.UserID,
|
|
|
|
|
SKU: newComment.SKU,
|
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
|
Text: newComment.Text,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := s.checkTimeout(comment.CreatedAt, oldComment.CreatedAt); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := s.comments.UpdateComment(ctx, comment); err != nil {
|
|
|
|
|
return fmt.Errorf("repository.UpdateComment: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) CommentListBySKU(ctx context.Context, sku int64) ([]*entity.Comment, error) {
|
|
|
|
|
if sku <= 0 {
|
|
|
|
|
return nil, fmt.Errorf("sku must be greater than 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comms, err := s.comments.ListCommentsBySku(ctx, sku)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("repository.ListCommentsBySku: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return comms, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *CommentsService) CommentListByUser(ctx context.Context, userID int64) ([]*entity.Comment, error) {
|
|
|
|
|
if userID <= 0 {
|
|
|
|
|
return nil, fmt.Errorf("userID must be greater than 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
comms, err := s.comments.ListCommentsByUser(ctx, userID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("repository.ListCommentsByUser: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sort.Slice(comms, func(i, j int) bool {
|
|
|
|
|
if comms[i].CreatedAt.Equal(comms[j].CreatedAt) {
|
|
|
|
|
return comms[i].UserID < comms[j].UserID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return comms[i].CreatedAt.After(comms[j].CreatedAt)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return comms, nil
|
|
|
|
|
}
|
|
|
|
|
|