kontenhumas-be/app/module/bookmarks/service/bookmarks.service.go

315 lines
9.9 KiB
Go

package service
import (
"errors"
"netidhub-saas-be/app/database/entity"
articlesRepository "netidhub-saas-be/app/module/articles/repository"
"netidhub-saas-be/app/module/bookmarks/mapper"
"netidhub-saas-be/app/module/bookmarks/repository"
"netidhub-saas-be/app/module/bookmarks/request"
"netidhub-saas-be/app/module/bookmarks/response"
usersRepository "netidhub-saas-be/app/module/users/repository"
"netidhub-saas-be/utils/paginator"
utilSvc "netidhub-saas-be/utils/service"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
// BookmarksService
type bookmarksService struct {
Repo repository.BookmarksRepository
ArticlesRepo articlesRepository.ArticlesRepository
UsersRepo usersRepository.UsersRepository
Log zerolog.Logger
}
// BookmarksService define interface of IBookmarksService
type BookmarksService interface {
All(authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error)
Show(authToken string, id uint) (bookmark *response.BookmarksResponse, err error)
Save(authToken string, req request.BookmarksCreateRequest) (bookmark *entity.Bookmarks, err error)
Delete(authToken string, id uint) error
GetByUserId(authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error)
ToggleBookmark(authToken string, articleId uint) (isBookmarked bool, err error)
GetBookmarkSummary(authToken string) (summary *response.BookmarksSummaryResponse, err error)
}
// NewBookmarksService init BookmarksService
func NewBookmarksService(
repo repository.BookmarksRepository,
articlesRepo articlesRepository.ArticlesRepository,
usersRepo usersRepository.UsersRepository,
log zerolog.Logger,
) BookmarksService {
return &bookmarksService{
Repo: repo,
ArticlesRepo: articlesRepo,
UsersRepo: usersRepo,
Log: log,
}
}
// implement interface of IBookmarksService
func (_i *bookmarksService) All(authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user == nil {
_i.Log.Error().Msg("User not found from auth token")
return nil, paging, errors.New("user not found")
}
req.UserId = &user.ID
bookmarksEntity, paging, err := _i.Repo.GetAll(clientId, req)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to get all bookmarks")
return nil, paging, err
}
// Convert []*entity.Bookmarks to []entity.Bookmarks
var bookmarksSlice []entity.Bookmarks
for _, b := range bookmarksEntity {
bookmarksSlice = append(bookmarksSlice, *b)
}
bookmarks = mapper.ToBookmarksResponseList(bookmarksSlice)
return bookmarks, paging, nil
}
func (_i *bookmarksService) Show(authToken string, id uint) (bookmark *response.BookmarksResponse, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
bookmarkEntity, err := _i.Repo.FindOne(clientId, id)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to show bookmark")
return nil, err
}
bookmark = mapper.ToBookmarksResponse(bookmarkEntity)
return bookmark, nil
}
func (_i *bookmarksService) Save(authToken string, req request.BookmarksCreateRequest) (bookmark *entity.Bookmarks, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
// Extract user info from auth token
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user == nil {
_i.Log.Error().Msg("User not found from auth token")
return nil, errors.New("user not found")
}
// Check if article exists
_, err = _i.ArticlesRepo.FindOne(clientId, req.ArticleId)
if err != nil {
_i.Log.Error().Err(err).Msg("Article not found")
return nil, errors.New("article not found")
}
// Check if bookmark already exists
existingBookmark, err := _i.Repo.FindByUserAndArticle(clientId, user.ID, req.ArticleId)
if err == nil && existingBookmark != nil {
_i.Log.Error().Msg("Bookmark already exists")
return nil, errors.New("article already bookmarked")
}
// Create new bookmark
bookmarkEntity := req.ToEntity(user.ID)
bookmark, err = _i.Repo.Create(clientId, bookmarkEntity)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to create bookmark")
return nil, err
}
return bookmark, nil
}
func (_i *bookmarksService) Delete(authToken string, id uint) error {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
err := _i.Repo.Delete(clientId, id)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to delete bookmark")
return err
}
return nil
}
func (_i *bookmarksService) GetByUserId(authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
// Extract user info from auth token
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user == nil {
_i.Log.Error().Msg("User not found from auth token")
return nil, paging, errors.New("user not found")
}
bookmarksEntity, paging, err := _i.Repo.GetByUserId(clientId, user.ID, req)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to get bookmarks by user ID")
return nil, paging, err
}
// Convert []*entity.Bookmarks to []entity.Bookmarks
var bookmarksSlice []entity.Bookmarks
for _, b := range bookmarksEntity {
bookmarksSlice = append(bookmarksSlice, *b)
}
bookmarks = mapper.ToBookmarksResponseList(bookmarksSlice)
return bookmarks, paging, nil
}
func (_i *bookmarksService) ToggleBookmark(authToken string, articleId uint) (isBookmarked bool, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
// Extract user info from auth token
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user == nil {
_i.Log.Error().Msg("User not found from auth token")
return false, errors.New("user not found")
}
// Check if article exists
_, err = _i.ArticlesRepo.FindOne(clientId, articleId)
if err != nil {
_i.Log.Error().Err(err).Msg("Article not found")
return false, errors.New("article not found")
}
// Check if bookmark already exists
existingBookmark, err := _i.Repo.FindByUserAndArticle(clientId, user.ID, articleId)
if err == nil && existingBookmark != nil {
// Bookmark exists, delete it
err = _i.Repo.Delete(clientId, existingBookmark.ID)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to delete existing bookmark")
return false, err
}
return false, nil // Bookmark removed
}
// Bookmark doesn't exist, create it
bookmarkEntity := &entity.Bookmarks{
UserId: user.ID,
ArticleId: articleId,
IsActive: boolPtr(true),
}
_, err = _i.Repo.Create(clientId, bookmarkEntity)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to create bookmark")
return false, err
}
return true, nil // Bookmark added
}
func (_i *bookmarksService) GetBookmarkSummary(authToken string) (summary *response.BookmarksSummaryResponse, err error) {
// Extract clientId from authToken
var clientId *uuid.UUID
if authToken != "" {
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user != nil && user.ClientId != nil {
clientId = user.ClientId
_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
}
}
// Extract user info from auth token
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
if user == nil {
_i.Log.Error().Msg("User not found from auth token")
return nil, errors.New("user not found")
}
// Get total count
totalCount, err := _i.Repo.CountByUserId(clientId, user.ID)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to count user bookmarks")
return nil, err
}
// Get recent bookmarks (last 5)
req := request.BookmarksQueryRequest{
Pagination: &paginator.Pagination{
Page: 1,
Limit: 5,
},
}
recentBookmarksEntity, _, err := _i.Repo.GetByUserId(clientId, user.ID, req)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to get recent bookmarks")
return nil, err
}
// Convert []*entity.Bookmarks to []entity.Bookmarks
var bookmarksSlice []entity.Bookmarks
for _, b := range recentBookmarksEntity {
bookmarksSlice = append(bookmarksSlice, *b)
}
recentBookmarks := mapper.ToBookmarksResponseList(bookmarksSlice)
summary = &response.BookmarksSummaryResponse{
TotalBookmarks: int(totalCount),
RecentBookmarks: recentBookmarks,
}
return summary, nil
}
// Helper function to create bool pointer
func boolPtr(b bool) *bool {
return &b
}