Files
easywish/backend/internal/services/wishlist.go

195 lines
6.5 KiB
Go

// Copyright (c) 2025 Nikolai Papin
//
// This file is part of Easywish
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package services
import (
"easywish/internal/database"
"easywish/internal/dto"
errs "easywish/internal/errors"
"easywish/internal/utils"
"easywish/internal/utils/enums"
mapspecial "easywish/internal/utils/mapSpecial"
"errors"
"github.com/go-redis/redis/v8"
"github.com/jackc/pgx/v5"
"go.uber.org/zap"
)
type wishListServiceImpl struct {
log *zap.Logger
dbctx database.DbContext
redis *redis.Client
s3 S3Service
}
type WishListService interface {
CreateWishList(cinfo dto.ClientInfo, object dto.NewWishListDto) (*dto.WishListDto, error)
UpdateWishListByGuid(cinfo dto.ClientInfo, guid string, object dto.NewWishDto) (bool, error)
DeleteWishListByGuid(cinfo dto.ClientInfo, guid string) (bool, error)
GetWishListByGuid(cinfo dto.ClientInfo, guid string) (*dto.WishListDto, error)
GetUserWishListsPaginated(cinfo dto.ClientInfo, amount int, page int, sorting enums.Sorting, sortOrder enums.SortOrder) (*[]dto.WishListDto, error)
CreateWish(cinfo dto.ClientInfo, object dto.NewWishDto) (*dto.WishDto, error)
UpdateWish(cinfo dto.ClientInfo, guid string, object dto.NewWishDto) (bool, error)
MoveWishToWishList(cinfo dto.ClientInfo, wishGuid string, wishListGuid string) (bool, error)
GetWishByGuid(cinfo dto.ClientInfo, guid string) (*dto.WishDto, error)
GetWishesByWishListGuidPaginated(cinfo dto.ClientInfo, guid string, amount int, page int, sorting enums.Sorting, sortOrder enums.SortOrder) (*[]dto.WishDto, error)
}
func NewWishListService(_log *zap.Logger, _dbctx database.DbContext, _redis *redis.Client, _s3 S3Service) WishListService {
return wishListServiceImpl{
log: _log,
dbctx: _dbctx,
redis: _redis,
s3: _s3,
}
}
func (w wishListServiceImpl) CreateWish(cinfo dto.ClientInfo, object dto.NewWishDto) (*dto.WishDto, error) {
helper, db, err := database.NewDbHelperTransaction(w.dbctx); if err != nil {
w.log.Error(
"Failed to open transaction",
zap.Error(err))
return nil, errs.ErrServerError
}
defer helper.Rollback()
// Check if wish list exists
wishList, err := db.TXQueries.GetWishlistByGuid(db.CTX, object.WishListGuid); if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
w.log.Warn(
"Attempted to create a wish for a wish list that does not exist",
zap.String("username", cinfo.Username),
zap.String("wish_list_guid", object.WishListGuid),
zap.Error(err))
return nil, errs.ErrNotFound
}
w.log.Error(
"Failed to get wishlist for the new wish",
zap.String("username", cinfo.Username),
zap.String("wish_list_guid", object.WishListGuid),
zap.Error(err))
return nil, errs.ErrServerError
}
wishListOwnerUser, err := db.TXQueries.GetWishListOwnerByGuid(db.CTX, wishList.Guid.String()); if err != nil {
w.log.Error(
"Failed to get wish list owner",
zap.String("username", cinfo.Username),
zap.String("wish_list_guid", wishList.Guid.String()),
zap.Error(err))
return nil, errs.ErrServerError
}
if wishListOwnerUser.Username != cinfo.Username {
w.log.Warn(
"Attempt to create wish in a wish list the user does not own",
zap.String("owner_username", wishListOwnerUser.Username),
zap.String("username", cinfo.Username),
zap.String("wish_list_guid", object.WishListGuid))
// As usual, we will pretend that it does not exist
return nil, errs.ErrNotFound
}
var avatarUrl *string
if object.PictureUploadId != "" {
key, err := w.s3.SaveUpload(object.PictureUploadId, "images"); if err != nil {
if errors.Is(err, errs.ErrFileNotFound) {
return nil, err
}
w.log.Error(
"Failed to save image",
zap.String("upload_id", object.PictureUploadId),
zap.String("username", cinfo.Username),
zap.Error(err))
return nil, errs.ErrServerError
}
urlObj := w.s3.GetLocalizedFileUrl(*key, "images")
avatarUrl = utils.NewPointer(urlObj.String())
} else {
avatarUrl = utils.NewPointer("")
}
newWish, err := db.TXQueries.CreateWish(db.CTX, database.CreateWishParams{
WishListGuid: object.WishListGuid,
Name: object.Name,
Description: object.Description,
PictureUrl: *avatarUrl,
Stars: int16(object.Stars),
}); if err != nil {
w.log.Error(
"Failed to create a new wish",
zap.String("username", cinfo.Username),
zap.String("wish_list_guid", object.WishListGuid),
zap.Error(err))
return nil, errs.ErrServerError
}
err = helper.Commit(); if err != nil {
w.log.Error(
"Failed to commit transaction",
zap.Error(err))
return nil, errs.ErrServerError
}
wishDto := &dto.WishDto{}
mapspecial.MapWishDto(newWish, wishDto)
return wishDto, nil
}
func (w wishListServiceImpl) CreateWishList(cinfo dto.ClientInfo, object dto.NewWishListDto) (*dto.WishListDto, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) DeleteWishListByGuid(cinfo dto.ClientInfo, guid string) (bool, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) GetUserWishListsPaginated(cinfo dto.ClientInfo, amount int, page int, sorting enums.Sorting, sortOrder enums.SortOrder) (*[]dto.WishListDto, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) GetWishByGuid(cinfo dto.ClientInfo, guid string) (*dto.WishDto, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) GetWishListByGuid(cinfo dto.ClientInfo, guid string) (*dto.WishListDto, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) GetWishesByWishListGuidPaginated(cinfo dto.ClientInfo, guid string, amount int, page int, sorting enums.Sorting, sortOrder enums.SortOrder) (*[]dto.WishDto, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) MoveWishToWishList(cinfo dto.ClientInfo, wishGuid string, wishListGuid string) (bool, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) UpdateWish(cinfo dto.ClientInfo, guid string, object dto.NewWishDto) (bool, error) {
panic("unimplemented")
}
func (w wishListServiceImpl) UpdateWishListByGuid(cinfo dto.ClientInfo, guid string, object dto.NewWishDto) (bool, error) {
panic("unimplemented")
}