tailly_back_v2/internal/service/comment_service.go
2025-08-06 22:30:19 +03:00

138 lines
3.9 KiB
Go

package service
import (
"context"
"errors"
"tailly_back_v2/internal/domain"
"tailly_back_v2/internal/repository"
"time"
)
// Интерфейс сервиса комментариев
type CommentService interface {
Create(ctx context.Context, postID, authorID int, content string) (*domain.Comment, error)
GetByID(ctx context.Context, id int) (*domain.Comment, error)
GetByPostID(ctx context.Context, postID int) ([]*domain.Comment, error)
GetCountComments(ctx context.Context, postID int) (int, error)
Update(ctx context.Context, id int, content string) (*domain.Comment, error)
Delete(ctx context.Context, id int) error
}
// Реализация сервиса комментариев
type commentService struct {
commentRepo repository.CommentRepository
postRepo repository.PostRepository // Добавляем для проверки существования поста
}
// Конструктор сервиса
func NewCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository) CommentService {
return &commentService{
commentRepo: commentRepo,
postRepo: postRepo,
}
}
// Создание комментария
func (s *commentService) Create(ctx context.Context, postID, authorID int, content string) (*domain.Comment, error) {
// Проверяем существование поста
if _, err := s.postRepo.GetByID(ctx, postID); err != nil {
if errors.Is(err, repository.ErrPostNotFound) {
return nil, errors.New("post not found")
}
return nil, err
}
// Валидация контента
if content == "" {
return nil, errors.New("comment content cannot be empty")
}
if len(content) > 1000 {
return nil, errors.New("comment is too long")
}
comment := &domain.Comment{
Content: content,
PostID: postID,
AuthorID: authorID,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if err := s.commentRepo.Create(ctx, comment); err != nil {
return nil, err
}
return comment, nil
}
// Получение комментария по ID
func (s *commentService) GetByID(ctx context.Context, id int) (*domain.Comment, error) {
comment, err := s.commentRepo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, repository.ErrCommentNotFound) {
return nil, errors.New("comment not found")
}
return nil, err
}
return comment, nil
}
// Получение комментариев для поста
func (s *commentService) GetByPostID(ctx context.Context, postID int) ([]*domain.Comment, error) {
// Проверяем существование поста
if _, err := s.postRepo.GetByID(ctx, postID); err != nil {
if errors.Is(err, repository.ErrPostNotFound) {
return nil, errors.New("post not found")
}
return nil, err
}
comments, err := s.commentRepo.GetByPostID(ctx, postID)
if err != nil {
return nil, err
}
// Возвращаем пустой слайс вместо nil
if comments == nil {
return []*domain.Comment{}, nil
}
return comments, nil
}
// Обновление комментария
func (s *commentService) Update(ctx context.Context, id int, content string) (*domain.Comment, error) {
// Валидация контента
if content == "" {
return nil, errors.New("comment content cannot be empty")
}
// Получаем существующий комментарий
comment, err := s.commentRepo.GetByID(ctx, id)
if err != nil {
return nil, err
}
// Обновляем поля
comment.Content = content
comment.UpdatedAt = time.Now()
if err := s.commentRepo.Update(ctx, comment); err != nil {
return nil, err
}
return comment, nil
}
// Удаление комментария
func (s *commentService) Delete(ctx context.Context, id int) error {
return s.commentRepo.Delete(ctx, id)
}
func (s *commentService) GetCountComments(ctx context.Context, postID int) (int, error) {
count, err := s.commentRepo.GetCountComments(ctx, postID)
if err != nil {
return 0, err
}
return count, nil
}