tailly_clips/internal/service/comment_service.go
admin 57eba68496
Some checks failed
continuous-integration/drone/push Build is failing
v.0.0.1 Создан сервис клипов
2025-09-02 11:58:10 +03:00

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
}