315 lines
9.9 KiB
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
|
|
}
|