[hw-8] add: comment service

This commit is contained in:
3ybacTuK
2025-07-26 23:47:18 +03:00
parent 6420eaf3d7
commit 6e0d90a6d5
29 changed files with 1249 additions and 725 deletions

View File

@@ -1,9 +1,11 @@
package entity
import "time"
type Comment struct {
ID int64
UserID int64
SKU int64
CreatedAt string
CreatedAt time.Time
Text string
}

View File

@@ -1,22 +0,0 @@
package model
import (
"fmt"
"time"
)
type Comment struct {
ID int64 `validate:"gt=0"`
UserID int64 `validate:"gt=0"`
SKU int64 `validate:"gt=0"`
CreatedAt time.Time
Text string `validate:"lte=255,gt=0"`
}
func (c *Comment) Validate() error {
if err := validate.Struct(c); err != nil {
return fmt.Errorf("invalid requested values: %w", err)
}
return nil
}

View File

@@ -3,3 +3,5 @@ package model
import "errors"
var ErrCommentNotFound = errors.New("comment not found")
var ErrCommentEditUserMismatch = errors.New("comment edit user mismatch")
var ErrCommentEditTimeout = errors.New("comment edit timeout")

View File

@@ -1,9 +0,0 @@
package model
import "github.com/go-playground/validator/v10"
var validate *validator.Validate
func init() {
validate = validator.New()
}

View File

@@ -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
}