package services import ( "encoding/json" "errors" "time" "github.com/pahmiudahgede/senggoldong/config" "github.com/pahmiudahgede/senggoldong/domain" "github.com/pahmiudahgede/senggoldong/dto" "github.com/pahmiudahgede/senggoldong/internal/repositories" "github.com/pahmiudahgede/senggoldong/utils" ) type ArticleService struct { repo *repositories.ArticleRepository } func NewArticleService(repo *repositories.ArticleRepository) *ArticleService { return &ArticleService{repo: repo} } func (s *ArticleService) GetAllArticles() ([]dto.ArticleResponse, error) { ctx := config.Context() cacheKey := "articles:all" cachedData, err := config.RedisClient.Get(ctx, cacheKey).Result() if err == nil && cachedData != "" { var cachedArticles []dto.ArticleResponse if err := json.Unmarshal([]byte(cachedData), &cachedArticles); err == nil { return cachedArticles, nil } } articles, err := s.repo.GetAll() if err != nil { return nil, err } var result []dto.ArticleResponse for _, article := range articles { result = append(result, dto.ArticleResponse{ ID: article.ID, Title: article.Title, CoverImage: article.CoverImage, Author: article.Author, Heading: article.Heading, Content: article.Content, PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt), UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt), }) } cacheData, _ := json.Marshal(result) config.RedisClient.Set(ctx, cacheKey, cacheData, time.Minute*5) return result, nil } func (s *ArticleService) GetArticleByID(id string) (*dto.ArticleResponse, error) { ctx := config.Context() cacheKey := "articles:" + id cachedData, err := config.RedisClient.Get(ctx, cacheKey).Result() if err == nil && cachedData != "" { var cachedArticle dto.ArticleResponse if err := json.Unmarshal([]byte(cachedData), &cachedArticle); err == nil { return &cachedArticle, nil } } article, err := s.repo.GetByID(id) if err != nil { return nil, err } result := &dto.ArticleResponse{ ID: article.ID, Title: article.Title, CoverImage: article.CoverImage, Author: article.Author, Heading: article.Heading, Content: article.Content, PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt), UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt), } cacheData, _ := json.Marshal(result) config.RedisClient.Set(ctx, cacheKey, cacheData, time.Minute*5) return result, nil } func (s *ArticleService) CreateArticle(request *dto.ArticleCreateRequest) (*dto.ArticleResponse, error) { if err := request.Validate(); err != nil { return nil, err } newArticle := &domain.Article{ Title: request.Title, CoverImage: request.CoverImage, Author: request.Author, Heading: request.Heading, Content: request.Content, } err := s.repo.Create(newArticle) if err != nil { return nil, errors.New("failed to create article") } ctx := config.Context() config.RedisClient.Del(ctx, "articles:all") response := &dto.ArticleResponse{ ID: newArticle.ID, Title: newArticle.Title, CoverImage: newArticle.CoverImage, Author: newArticle.Author, Heading: newArticle.Heading, Content: newArticle.Content, PublishedAt: utils.FormatDateToIndonesianFormat(newArticle.PublishedAt), UpdatedAt: utils.FormatDateToIndonesianFormat(newArticle.UpdatedAt), } return response, nil } func (s *ArticleService) UpdateArticle(id string, request *dto.ArticleUpdateRequest) (*dto.ArticleResponse, error) { // if err := dto.GetValidator().Struct(request); err != nil { // return nil, errors.New("invalid input data") // } if err := request.Validate(); err != nil { return nil, err } article, err := s.repo.GetByID(id) if err != nil { return nil, errors.New("article not found") } article.Title = request.Title article.CoverImage = request.CoverImage article.Author = request.Author article.Heading = request.Heading article.Content = request.Content article.UpdatedAt = time.Now() err = s.repo.Update(article) if err != nil { return nil, errors.New("failed to update article") } ctx := config.Context() config.RedisClient.Del(ctx, "articles:all") config.RedisClient.Del(ctx, "articles:"+id) response := &dto.ArticleResponse{ ID: article.ID, Title: article.Title, CoverImage: article.CoverImage, Author: article.Author, Heading: article.Heading, Content: article.Content, PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt), UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt), } return response, nil } func (s *ArticleService) DeleteArticle(id string) error { article, err := s.repo.GetByID(id) if err != nil { return errors.New("article not found") } err = s.repo.Delete(article) if err != nil { return errors.New("failed to delete article") } ctx := config.Context() config.RedisClient.Del(ctx, "articles:all") config.RedisClient.Del(ctx, "articles:"+id) return nil }