image storage added
This commit is contained in:
parent
f5ca21ca68
commit
212ce0a5c4
6 changed files with 190 additions and 65 deletions
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"merch-parser-api/internal/api/user"
|
"merch-parser-api/internal/api/user"
|
||||||
"merch-parser-api/internal/app"
|
"merch-parser-api/internal/app"
|
||||||
"merch-parser-api/internal/grpcService"
|
"merch-parser-api/internal/grpcService"
|
||||||
|
"merch-parser-api/internal/imagesProvider"
|
||||||
"merch-parser-api/internal/interfaces"
|
"merch-parser-api/internal/interfaces"
|
||||||
"merch-parser-api/internal/mediaStorage"
|
"merch-parser-api/internal/mediaStorage"
|
||||||
"merch-parser-api/internal/provider/auth"
|
"merch-parser-api/internal/provider/auth"
|
||||||
|
|
@ -62,6 +63,8 @@ func main() {
|
||||||
"provider": mediaProvider,
|
"provider": mediaProvider,
|
||||||
}).Debug("Media storage | Minio client created")
|
}).Debug("Media storage | Minio client created")
|
||||||
|
|
||||||
|
imageProvider := imagesProvider.NewClient(c.ImageConf.Host + ":" + c.ImageConf.Port)
|
||||||
|
|
||||||
//deps providers
|
//deps providers
|
||||||
routerHandler := router.NewRouter(router.Deps{
|
routerHandler := router.NewRouter(router.Deps{
|
||||||
ApiPrefix: c.AppConf.ApiPrefix,
|
ApiPrefix: c.AppConf.ApiPrefix,
|
||||||
|
|
@ -94,6 +97,7 @@ func main() {
|
||||||
DB: database,
|
DB: database,
|
||||||
Utils: utilsProvider,
|
Utils: utilsProvider,
|
||||||
Media: mediaProvider,
|
Media: mediaProvider,
|
||||||
|
ImageStorage: imageProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
//collect modules
|
//collect modules
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ type Config struct {
|
||||||
JWTConf JWTConfig
|
JWTConf JWTConfig
|
||||||
GrpcConf GrpcConfig
|
GrpcConf GrpcConfig
|
||||||
MediaConf MediaConfig
|
MediaConf MediaConfig
|
||||||
|
ImageConf ImageStorageConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
|
|
@ -48,6 +49,11 @@ type MediaConfig struct {
|
||||||
Secure string
|
Secure string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageStorageConfig struct {
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
AppConf: AppConfig{
|
AppConf: AppConfig{
|
||||||
|
|
@ -87,5 +93,10 @@ func NewConfig() *Config {
|
||||||
Password: getEnv("MEDIA_STORAGE_PASSWORD", ""),
|
Password: getEnv("MEDIA_STORAGE_PASSWORD", ""),
|
||||||
Secure: getEnv("MEDIA_STORAGE_SECURE", ""),
|
Secure: getEnv("MEDIA_STORAGE_SECURE", ""),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ImageConf: ImageStorageConfig{
|
||||||
|
Host: getEnv("IMAGE_STORAGE_HOST", ""),
|
||||||
|
Port: getEnv("IMAGE_STORAGE_PORT", ""),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -266,16 +266,15 @@ func (co *controller) getDistinctPrices(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Загрузить картинки по merch_uuid и query параметрам
|
// @Summary Загрузить картинку по merch_uuid
|
||||||
// @Description Загрузить картинки по merch_uuid и query параметрам
|
// @Description Загрузить картинку по merch_uuid. В ответ будут выданы ссылки на созданные картинки.
|
||||||
// @Tags Merch images
|
// @Tags Merch images
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Accept multipart/form-data
|
// @Accept multipart/form-data
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param uuid path string true "Merch UUID"
|
// @Param uuid path string true "Merch UUID"
|
||||||
// @Param file formData file true "Image file"
|
// @Param file formData file true "Image file"
|
||||||
// @Param imageType formData string true "Image type: thumbnail, full or all" Enums(thumbnail, full, all)
|
// @Success 200 {object} imageStorage.UploadMerchImageResponse
|
||||||
// @Success 200
|
|
||||||
// @Failure 400 {object} responses.ErrorResponse400
|
// @Failure 400 {object} responses.ErrorResponse400
|
||||||
// @Failure 500 {object} responses.ErrorResponse500
|
// @Failure 500 {object} responses.ErrorResponse500
|
||||||
// @Router /merch/images/{uuid} [post]
|
// @Router /merch/images/{uuid} [post]
|
||||||
|
|
@ -294,13 +293,14 @@ func (co *controller) uploadMerchImage(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageType := c.PostForm("imageType")
|
//Uncomment for MinIO use
|
||||||
types := map[string]struct{}{"thumbnail": {}, "full": {}, "all": {}}
|
//imageType := c.PostForm("imageType")
|
||||||
if _, allowed := types[imageType]; !allowed {
|
//types := map[string]struct{}{"thumbnail": {}, "full": {}, "all": {}}
|
||||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "imageType must be one of: thumbnail, full, all"})
|
//if _, allowed := types[imageType]; !allowed {
|
||||||
log.WithError(err).Error("Merch | imageType must be one of: thumbnail, full, all")
|
// c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "imageType must be one of: thumbnail, full, all"})
|
||||||
return
|
// log.WithError(err).Error("Merch | imageType must be one of: thumbnail, full, all")
|
||||||
}
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
file, err := c.FormFile("file")
|
file, err := c.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -312,14 +312,17 @@ func (co *controller) uploadMerchImage(c *gin.Context) {
|
||||||
ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err = co.service.uploadMerchImage(ctx, userUuid, merchUuid, imageType, file)
|
//Uncomment for MinIO use
|
||||||
|
//err = co.service.uploadMerchImage(ctx, userUuid, merchUuid, imageType, file)
|
||||||
|
response, err := co.service.mtUploadMerchImage(ctx, userUuid, merchUuid, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
||||||
log.WithError(err).Error("Merch | Failed to upload merch image")
|
log.WithError(err).Error("Merch | Failed to upload merch image")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Status(http.StatusOK)
|
//c.Status(http.StatusOK)
|
||||||
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Получить картинки по merch_uuid и query параметрам
|
// @Summary Получить картинки по merch_uuid и query параметрам
|
||||||
|
|
@ -333,40 +336,50 @@ func (co *controller) uploadMerchImage(c *gin.Context) {
|
||||||
// @Failure 500 {object} responses.ErrorResponse500
|
// @Failure 500 {object} responses.ErrorResponse500
|
||||||
// @Router /merch/images/{uuid} [get]
|
// @Router /merch/images/{uuid} [get]
|
||||||
func (co *controller) getMerchImage(c *gin.Context) {
|
func (co *controller) getMerchImage(c *gin.Context) {
|
||||||
typeQuery := strings.ToLower(c.Query("type"))
|
//Uncomment for MinIO use
|
||||||
if typeQuery == "" {
|
|
||||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "Image type query param is empty"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userUuid, err := co.utils.GetUserUuidFromContext(c)
|
//typeQuery := strings.ToLower(c.Query("type"))
|
||||||
if err != nil {
|
//if typeQuery == "" {
|
||||||
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
// c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "Image type query param is empty"})
|
||||||
log.WithError(err).Error("Merch | Failed to get user uuid from context")
|
// return
|
||||||
return
|
//}
|
||||||
}
|
//
|
||||||
|
//userUuid, err := co.utils.GetUserUuidFromContext(c)
|
||||||
merchUuid := c.Param("uuid")
|
//if err != nil {
|
||||||
if merchUuid == "" {
|
// c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
||||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "MerchUuid is empty"})
|
// log.WithError(err).Error("Merch | Failed to get user uuid from context")
|
||||||
log.WithError(err).Error("Merch | Failed to get single merch")
|
// return
|
||||||
return
|
//}
|
||||||
}
|
//
|
||||||
|
//merchUuid := c.Param("uuid")
|
||||||
ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
//if merchUuid == "" {
|
||||||
defer cancel()
|
// c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "MerchUuid is empty"})
|
||||||
|
// log.WithError(err).Error("Merch | Failed to get single merch")
|
||||||
link, err := co.service.getPublicImageLink(ctx, userUuid, merchUuid, typeQuery)
|
// return
|
||||||
if err != nil {
|
//}
|
||||||
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
//
|
||||||
log.WithError(err).Error("Merch | Failed to get merch image")
|
//ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
||||||
return
|
//defer cancel()
|
||||||
}
|
//
|
||||||
c.JSON(http.StatusOK, link)
|
//link, err := co.service.getPublicImageLink(ctx, userUuid, merchUuid, typeQuery)
|
||||||
|
//if err != nil {
|
||||||
|
// c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
||||||
|
// log.WithError(err).Error("Merch | Failed to get merch image")
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if link.Link == "" {
|
||||||
|
// log.Debug("Merch | No image")
|
||||||
|
// c.Status(http.StatusNoContent)
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//c.JSON(http.StatusOK, link)
|
||||||
|
c.JSON(http.StatusNotImplemented, gin.H{"msg": "Method deprecated. Request images from image storage."})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Удалить (безвозвратно) картинки по merch_uuid и query параметрам
|
// @Summary Удалить (безвозвратно) картинки по merch_uuid
|
||||||
// @Description Удалить (безвозвратно) картинки по merch_uuid и query параметрам
|
// @Description Удалить (безвозвратно) картинки по merch_uuid
|
||||||
// @Tags Merch images
|
// @Tags Merch images
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Param uuid path string true "merch_uuid"
|
// @Param uuid path string true "merch_uuid"
|
||||||
|
|
@ -385,14 +398,17 @@ func (co *controller) deleteMerchImage(c *gin.Context) {
|
||||||
merchUuid := c.Param("uuid")
|
merchUuid := c.Param("uuid")
|
||||||
if merchUuid == "" {
|
if merchUuid == "" {
|
||||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "MerchUuid is empty"})
|
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: "MerchUuid is empty"})
|
||||||
log.WithError(err).Error("Merch | Failed to get single merch")
|
log.WithError(err).Error("Merch | Failed to get merch uuid")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
ctx, cancel := context.WithTimeout(c.Request.Context(), co.expires)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if err := co.service.deleteMerchImage(ctx, userUuid, merchUuid); err != nil {
|
//Uncomment for MinIO use
|
||||||
|
//if err := co.service.deleteMerchImage(ctx, userUuid, merchUuid); err != nil {
|
||||||
|
|
||||||
|
if err := co.service.mtDeleteMerchImage(ctx, userUuid, merchUuid); err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()})
|
||||||
log.WithError(err).Error("Merch | Failed to delete merch image")
|
log.WithError(err).Error("Merch | Failed to delete merch image")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"merch-parser-api/internal/interfaces"
|
"merch-parser-api/internal/interfaces"
|
||||||
|
is "merch-parser-api/proto/imageStorage"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,6 +18,7 @@ type Deps struct {
|
||||||
DB *gorm.DB
|
DB *gorm.DB
|
||||||
Utils interfaces.Utils
|
Utils interfaces.Utils
|
||||||
Media interfaces.MediaStorage
|
Media interfaces.MediaStorage
|
||||||
|
ImageStorage is.ImageStorageClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(deps Deps) *Handler {
|
func NewHandler(deps Deps) *Handler {
|
||||||
|
|
@ -24,7 +26,13 @@ func NewHandler(deps Deps) *Handler {
|
||||||
expires := time.Minute * 5
|
expires := time.Minute * 5
|
||||||
|
|
||||||
r := NewRepo(deps.DB)
|
r := NewRepo(deps.DB)
|
||||||
s := newService(r, deps.Media, packageBucketName, expires)
|
s := newService(serviceDeps{
|
||||||
|
repo: r,
|
||||||
|
media: deps.Media,
|
||||||
|
bucketName: packageBucketName,
|
||||||
|
expires: expires,
|
||||||
|
imageStorage: deps.ImageStorage,
|
||||||
|
})
|
||||||
c := newController(s, deps.Utils, expires)
|
c := newController(s, deps.Utils, expires)
|
||||||
|
|
||||||
media := deps.Media
|
media := deps.Media
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ func (r *Repo) merchRecordExists(userUuid, merchUuid string) (bool, error) {
|
||||||
FROM merch
|
FROM merch
|
||||||
WHERE user_uuid = ?
|
WHERE user_uuid = ?
|
||||||
AND merch_uuid = ?
|
AND merch_uuid = ?
|
||||||
|
AND deleted_at IS NULL
|
||||||
);`, userUuid, merchUuid).Scan(&exists).Error
|
);`, userUuid, merchUuid).Scan(&exists).Error
|
||||||
|
|
||||||
return exists, err
|
return exists, err
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"io"
|
"io"
|
||||||
"merch-parser-api/internal/interfaces"
|
"merch-parser-api/internal/interfaces"
|
||||||
|
is "merch-parser-api/proto/imageStorage"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -24,14 +25,24 @@ type service struct {
|
||||||
media interfaces.MediaStorage
|
media interfaces.MediaStorage
|
||||||
bucketName string
|
bucketName string
|
||||||
expires time.Duration
|
expires time.Duration
|
||||||
|
imageStorage is.ImageStorageClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func newService(repo repository, media interfaces.MediaStorage, bucketName string, expires time.Duration) *service {
|
type serviceDeps struct {
|
||||||
|
repo repository
|
||||||
|
media interfaces.MediaStorage
|
||||||
|
bucketName string
|
||||||
|
expires time.Duration
|
||||||
|
imageStorage is.ImageStorageClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func newService(deps serviceDeps) *service {
|
||||||
return &service{
|
return &service{
|
||||||
repo: repo,
|
repo: deps.repo,
|
||||||
media: media,
|
media: deps.media,
|
||||||
bucketName: bucketName,
|
bucketName: deps.bucketName,
|
||||||
expires: expires,
|
expires: deps.expires,
|
||||||
|
imageStorage: deps.imageStorage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,6 +221,9 @@ func (s *service) getDistinctPrices(userUuid, merchUuid, days string) (PricesRes
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uploadMerchImage
|
||||||
|
// Deprecated.
|
||||||
|
// Use only with MinIO storage. Use mtUploadMerchImage for merch-tracker images storage.
|
||||||
func (s *service) uploadMerchImage(ctx context.Context, userUuid, merchUuid, imageType string, file *multipart.FileHeader) error {
|
func (s *service) uploadMerchImage(ctx context.Context, userUuid, merchUuid, imageType string, file *multipart.FileHeader) error {
|
||||||
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -303,6 +317,9 @@ func (s *service) uploadMerchImage(ctx context.Context, userUuid, merchUuid, ima
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPublicImageLink
|
||||||
|
// Deprecated.
|
||||||
|
// Use only with MinIO storage.
|
||||||
func (s *service) getPublicImageLink(ctx context.Context, userUuid, merchUuid, imageType string) (ImageLink, error) {
|
func (s *service) getPublicImageLink(ctx context.Context, userUuid, merchUuid, imageType string) (ImageLink, error) {
|
||||||
object, err := s.makeObject(userUuid, merchUuid, imageType)
|
object, err := s.makeObject(userUuid, merchUuid, imageType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -320,6 +337,9 @@ func (s *service) getPublicImageLink(ctx context.Context, userUuid, merchUuid, i
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPresignedImageLink
|
||||||
|
// Deprecated.
|
||||||
|
// Use only with MinIO storage.
|
||||||
func (s *service) getPresignedImageLink(ctx context.Context, userUuid, merchUuid, imageType string) (ImageLink, error) {
|
func (s *service) getPresignedImageLink(ctx context.Context, userUuid, merchUuid, imageType string) (ImageLink, error) {
|
||||||
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -351,6 +371,9 @@ func (s *service) getPresignedImageLink(ctx context.Context, userUuid, merchUuid
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deleteMerchImage
|
||||||
|
// Deprecated.
|
||||||
|
// Use only with MinIO storage.
|
||||||
func (s *service) deleteMerchImage(ctx context.Context, userUuid, merchUuid string) error {
|
func (s *service) deleteMerchImage(ctx context.Context, userUuid, merchUuid string) error {
|
||||||
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -398,3 +421,65 @@ func (s *service) _uploadToStorage(params uploadImageParams) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mtUploadMerchImage
|
||||||
|
// Upload new/rewrite existing image to merch-tracker images storage
|
||||||
|
func (s *service) mtUploadMerchImage(ctx context.Context, userUuid, merchUuid string, file *multipart.FileHeader) (*is.UploadMerchImageResponse, error) {
|
||||||
|
const uploadMerchImage = "Merch service | Upload merch image"
|
||||||
|
|
||||||
|
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error(uploadMerchImage)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
err = fmt.Errorf("no merch found for user %s with uuid %s", userUuid, merchUuid)
|
||||||
|
log.WithError(err).Error(uploadMerchImage)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error(uploadMerchImage)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
data, err := io.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error(uploadMerchImage)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := s.imageStorage.UploadImage(ctx, &is.UploadMerchImageRequest{
|
||||||
|
ImageData: data,
|
||||||
|
UserUuid: userUuid,
|
||||||
|
MerchUuid: merchUuid,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error(uploadMerchImage)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mtDeleteMerchImage
|
||||||
|
// Delete all merch images for given user and merch uuid-s from merch-tracker images storage
|
||||||
|
func (s *service) mtDeleteMerchImage(ctx context.Context, userUuid, merchUuid string) error {
|
||||||
|
exists, err := s.repo.merchRecordExists(userUuid, merchUuid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("no merch found for user %s with uuid %s", userUuid, merchUuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.imageStorage.DeleteImage(ctx, &is.DeleteImageRequest{
|
||||||
|
UserUuid: userUuid,
|
||||||
|
MerchUuid: merchUuid,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue