104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"tailly_clips/internal/domain"
|
|
"tailly_clips/internal/repository"
|
|
"time"
|
|
)
|
|
|
|
type CommentService interface {
|
|
CreateComment(ctx context.Context, clipID, userID int, content string) (*domain.ClipComment, error)
|
|
GetClipComments(ctx context.Context, clipID, limit, offset int) ([]*domain.ClipComment, int, error)
|
|
DeleteComment(ctx context.Context, commentID, userID int) error
|
|
}
|
|
|
|
type commentService struct {
|
|
commentRepo repository.CommentRepository
|
|
clipRepo repository.ClipRepository
|
|
}
|
|
|
|
func NewCommentService(commentRepo repository.CommentRepository, clipRepo repository.ClipRepository) CommentService {
|
|
return &commentService{
|
|
commentRepo: commentRepo,
|
|
clipRepo: clipRepo,
|
|
}
|
|
}
|
|
|
|
func (s *commentService) CreateComment(ctx context.Context, clipID, userID int, content string) (*domain.ClipComment, error) {
|
|
// Проверяем существование клипа
|
|
if _, err := s.clipRepo.GetByID(ctx, clipID); err != nil {
|
|
return nil, fmt.Errorf("clip not found: %w", err)
|
|
}
|
|
|
|
// Валидация контента
|
|
if content == "" {
|
|
return nil, fmt.Errorf("comment content cannot be empty")
|
|
}
|
|
if len(content) > 1000 {
|
|
return nil, fmt.Errorf("comment content too long")
|
|
}
|
|
|
|
// Создаем комментарий
|
|
comment := &domain.ClipComment{
|
|
ClipID: clipID,
|
|
AuthorID: userID,
|
|
Content: content,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if err := s.commentRepo.Create(ctx, comment); err != nil {
|
|
return nil, fmt.Errorf("failed to create comment: %w", err)
|
|
}
|
|
|
|
// Увеличиваем счетчик комментариев
|
|
if err := s.clipRepo.IncrementCommentsCount(ctx, clipID); err != nil {
|
|
// Откатываем создание комментария при ошибке
|
|
s.commentRepo.Delete(ctx, comment.ID)
|
|
return nil, fmt.Errorf("failed to increment comments count: %w", err)
|
|
}
|
|
|
|
return comment, nil
|
|
}
|
|
|
|
func (s *commentService) GetClipComments(ctx context.Context, clipID, limit, offset int) ([]*domain.ClipComment, int, error) {
|
|
// Проверяем существование клипа
|
|
if _, err := s.clipRepo.GetByID(ctx, clipID); err != nil {
|
|
return nil, 0, fmt.Errorf("clip not found: %w", err)
|
|
}
|
|
|
|
comments, totalCount, err := s.commentRepo.GetByClipID(ctx, clipID, limit, offset)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to get clip comments: %w", err)
|
|
}
|
|
|
|
return comments, totalCount, nil
|
|
}
|
|
|
|
func (s *commentService) DeleteComment(ctx context.Context, commentID, userID int) error {
|
|
// Получаем комментарий для проверки прав
|
|
comment, err := s.commentRepo.GetByID(ctx, commentID)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get comment: %w", err)
|
|
}
|
|
|
|
// Проверяем права доступа
|
|
if comment.AuthorID != userID {
|
|
return fmt.Errorf("user %d is not the author of comment %d", userID, commentID)
|
|
}
|
|
|
|
// Удаляем комментарий
|
|
if err := s.commentRepo.Delete(ctx, commentID); err != nil {
|
|
return fmt.Errorf("failed to delete comment: %w", err)
|
|
}
|
|
|
|
// Уменьшаем счетчик комментариев
|
|
if err := s.clipRepo.DecrementCommentsCount(ctx, comment.ClipID); err != nil {
|
|
return fmt.Errorf("failed to decrement comments count: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|