From 1bef2a45e52a5316853937ee6d0b4e35c256595c Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Mon, 17 Nov 2025 22:44:55 +0700 Subject: [PATCH] fix: update product, banners, gallery_files, product spec, promotions --- app/database/entity/products.entity.go | 2 +- .../banners/controller/banners.controller.go | 2 +- app/module/banners/mapper/banners.mapper.go | 6 ++++-- app/module/banners/service/banners.service.go | 2 +- .../controller/gallery_files.controller.go | 2 +- .../gallery_files/mapper/gallery_files.mapper.go | 5 ++++- .../service/gallery_files.service.go | 2 +- .../product_specifications.controller.go | 2 +- .../mapper/product_specifications.mapper.go | 5 ++++- .../service/product_specifications.service.go | 2 +- .../products/controller/products.controller.go | 11 ++++------- app/module/products/mapper/products.mapper.go | 5 ++++- app/module/products/request/products.request.go | 15 +++++++-------- app/module/products/response/products.response.go | 2 +- app/module/products/service/products.service.go | 2 +- .../controller/promotions.controller.go | 2 +- app/module/promotions/mapper/promotions.mapper.go | 5 ++++- .../promotions/service/promotions.service.go | 2 +- docs/swagger/docs.go | 14 +++++++------- docs/swagger/swagger.json | 14 +++++++------- docs/swagger/swagger.yaml | 14 +++++++------- 21 files changed, 63 insertions(+), 53 deletions(-) diff --git a/app/database/entity/products.entity.go b/app/database/entity/products.entity.go index 74d11d2..f582f6f 100644 --- a/app/database/entity/products.entity.go +++ b/app/database/entity/products.entity.go @@ -8,7 +8,7 @@ type Products struct { ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` Title string `json:"title" gorm:"type:varchar"` Variant *string `json:"variant" gorm:"type:varchar"` - Price *float64 `json:"price" gorm:"type:decimal(10,2)"` + Price *string `json:"price" gorm:"type:varchar"` ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"` Colors *string `json:"colors" gorm:"type:text"` // JSON array stored as text IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` diff --git a/app/module/banners/controller/banners.controller.go b/app/module/banners/controller/banners.controller.go index a97c985..8365732 100644 --- a/app/module/banners/controller/banners.controller.go +++ b/app/module/banners/controller/banners.controller.go @@ -240,7 +240,7 @@ func (_i *bannersController) Delete(c *fiber.Ctx) error { // @Tags Banners // @Security Bearer // @Param X-Client-Key header string true "Insert the X-Client-Key" -// @Param filename path string true "Banner File Path" +// @Param filename path string true "Banner File Name (e.g., user_277788.png)" // @Success 200 {file} file // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError diff --git a/app/module/banners/mapper/banners.mapper.go b/app/module/banners/mapper/banners.mapper.go index bc4d1f6..846b527 100644 --- a/app/module/banners/mapper/banners.mapper.go +++ b/app/module/banners/mapper/banners.mapper.go @@ -3,6 +3,7 @@ package mapper import ( "jaecoo-be/app/database/entity" res "jaecoo-be/app/module/banners/response" + "path/filepath" ) func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResponse { @@ -23,10 +24,11 @@ func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResp } if banner.ThumbnailPath != nil && *banner.ThumbnailPath != "" { - thumbnailUrl := host + "/banners/thumbnail/viewer/" + *banner.ThumbnailPath + // Extract filename from path + filename := filepath.Base(*banner.ThumbnailPath) + thumbnailUrl := host + "/banners/viewer/" + filename response.ThumbnailUrl = &thumbnailUrl } return response } - diff --git a/app/module/banners/service/banners.service.go b/app/module/banners/service/banners.service.go index 381f095..e121eae 100644 --- a/app/module/banners/service/banners.service.go +++ b/app/module/banners/service/banners.service.go @@ -195,7 +195,7 @@ func (_i *bannersService) Delete(id uint) (err error) { func (_i *bannersService) Viewer(c *fiber.Ctx) (err error) { filename := c.Params("filename") - // Find banner by thumbnail path + // Find banner by filename (repository will search using LIKE pattern) result, err := _i.Repo.FindByThumbnailPath(filename) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ diff --git a/app/module/gallery_files/controller/gallery_files.controller.go b/app/module/gallery_files/controller/gallery_files.controller.go index 566f65b..1d5fdd0 100644 --- a/app/module/gallery_files/controller/gallery_files.controller.go +++ b/app/module/gallery_files/controller/gallery_files.controller.go @@ -230,7 +230,7 @@ func (_i *galleryFilesController) Delete(c *fiber.Ctx) error { // @Tags GalleryFiles // @Security Bearer // @Param X-Client-Key header string true "Insert the X-Client-Key" -// @Param filename path string true "Gallery File Path" +// @Param filename path string true "Gallery File Name (e.g., user_277788.png)" // @Success 200 {file} file // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError diff --git a/app/module/gallery_files/mapper/gallery_files.mapper.go b/app/module/gallery_files/mapper/gallery_files.mapper.go index a29c8e5..3403439 100644 --- a/app/module/gallery_files/mapper/gallery_files.mapper.go +++ b/app/module/gallery_files/mapper/gallery_files.mapper.go @@ -3,6 +3,7 @@ package mapper import ( "jaecoo-be/app/database/entity" res "jaecoo-be/app/module/gallery_files/response" + "path/filepath" ) func GalleryFilesResponseMapper(file *entity.GalleryFiles, host string) *res.GalleryFilesResponse { @@ -21,7 +22,9 @@ func GalleryFilesResponseMapper(file *entity.GalleryFiles, host string) *res.Gal } if file.ImagePath != nil && *file.ImagePath != "" { - imageUrl := host + "/gallery-files/image/viewer/" + *file.ImagePath + // Extract filename from path + filename := filepath.Base(*file.ImagePath) + imageUrl := host + "/gallery-files/viewer/" + filename response.ImageUrl = &imageUrl } diff --git a/app/module/gallery_files/service/gallery_files.service.go b/app/module/gallery_files/service/gallery_files.service.go index b3dd8b1..2d3304c 100644 --- a/app/module/gallery_files/service/gallery_files.service.go +++ b/app/module/gallery_files/service/gallery_files.service.go @@ -195,7 +195,7 @@ func (_i *galleryFilesService) Delete(id uint) (err error) { func (_i *galleryFilesService) Viewer(c *fiber.Ctx) (err error) { filename := c.Params("filename") - // Find gallery file by image path + // Find gallery file by filename (repository will search using LIKE pattern) result, err := _i.Repo.FindByImagePath(filename) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ diff --git a/app/module/product_specifications/controller/product_specifications.controller.go b/app/module/product_specifications/controller/product_specifications.controller.go index d57b022..31dbb56 100644 --- a/app/module/product_specifications/controller/product_specifications.controller.go +++ b/app/module/product_specifications/controller/product_specifications.controller.go @@ -235,7 +235,7 @@ func (_i *productSpecificationsController) Delete(c *fiber.Ctx) error { // @Tags ProductSpecifications // @Security Bearer // @Param X-Client-Key header string true "Insert the X-Client-Key" -// @Param filename path string true "Product Specification File Path" +// @Param filename path string true "Product Specification File Name (e.g., user_277788.png)" // @Success 200 {file} file // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError diff --git a/app/module/product_specifications/mapper/product_specifications.mapper.go b/app/module/product_specifications/mapper/product_specifications.mapper.go index 9472fab..7aa1dbd 100644 --- a/app/module/product_specifications/mapper/product_specifications.mapper.go +++ b/app/module/product_specifications/mapper/product_specifications.mapper.go @@ -3,6 +3,7 @@ package mapper import ( "jaecoo-be/app/database/entity" res "jaecoo-be/app/module/product_specifications/response" + "path/filepath" ) func ProductSpecificationsResponseMapper(spec *entity.ProductSpecifications, host string) *res.ProductSpecificationsResponse { @@ -21,7 +22,9 @@ func ProductSpecificationsResponseMapper(spec *entity.ProductSpecifications, hos } if spec.ThumbnailPath != nil && *spec.ThumbnailPath != "" { - thumbnailUrl := host + "/product-specifications/thumbnail/viewer/" + *spec.ThumbnailPath + // Extract filename from path + filename := filepath.Base(*spec.ThumbnailPath) + thumbnailUrl := host + "/product-specifications/viewer/" + filename response.ThumbnailUrl = &thumbnailUrl } diff --git a/app/module/product_specifications/service/product_specifications.service.go b/app/module/product_specifications/service/product_specifications.service.go index 8ab4a68..8ad7235 100644 --- a/app/module/product_specifications/service/product_specifications.service.go +++ b/app/module/product_specifications/service/product_specifications.service.go @@ -195,7 +195,7 @@ func (_i *productSpecificationsService) Delete(id uint) (err error) { func (_i *productSpecificationsService) Viewer(c *fiber.Ctx) (err error) { filename := c.Params("filename") - // Find product specification by thumbnail path + // Find product specification by filename (repository will search using LIKE pattern) result, err := _i.Repo.FindByThumbnailPath(filename) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ diff --git a/app/module/products/controller/products.controller.go b/app/module/products/controller/products.controller.go index f4dd61d..9ffea85 100644 --- a/app/module/products/controller/products.controller.go +++ b/app/module/products/controller/products.controller.go @@ -110,7 +110,7 @@ func (_i *productsController) Show(c *fiber.Ctx) error { // @Param file formData file false "Upload file" // @Param title formData string true "Product title" // @Param variant formData string false "Product variant" -// @Param price formData number false "Product price" +// @Param price formData string false "Product price" // @Param colors formData string false "Product colors (JSON array)" // @Success 200 {object} response.Response // @Failure 400 {object} response.BadRequestError @@ -136,10 +136,8 @@ func (_i *productsController) Save(c *fiber.Ctx) error { req.Variant = &variant } - if priceStr := c.FormValue("price"); priceStr != "" { - if price, err := strconv.ParseFloat(priceStr, 64); err == nil { - req.Price = &price - } + if price := c.FormValue("price"); price != "" { + req.Price = &price } // Handle colors (JSON array string) @@ -246,7 +244,7 @@ func (_i *productsController) Delete(c *fiber.Ctx) error { // @Tags Products // @Security Bearer // @Param X-Client-Key header string true "Insert the X-Client-Key" -// @Param filename path string true "Product File Path" +// @Param filename path string true "Product File Name (e.g., user_277788.png)" // @Success 200 {file} file // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError @@ -255,4 +253,3 @@ func (_i *productsController) Delete(c *fiber.Ctx) error { func (_i *productsController) Viewer(c *fiber.Ctx) error { return _i.productsService.Viewer(c) } - diff --git a/app/module/products/mapper/products.mapper.go b/app/module/products/mapper/products.mapper.go index e17d736..12c0ae0 100644 --- a/app/module/products/mapper/products.mapper.go +++ b/app/module/products/mapper/products.mapper.go @@ -4,6 +4,7 @@ import ( "encoding/json" "jaecoo-be/app/database/entity" res "jaecoo-be/app/module/products/response" + "path/filepath" ) func ProductsResponseMapper(product *entity.Products, host string) *res.ProductsResponse { @@ -29,7 +30,9 @@ func ProductsResponseMapper(product *entity.Products, host string) *res.Products } if product.ThumbnailPath != nil && *product.ThumbnailPath != "" { - thumbnailUrl := host + "/products/thumbnail/viewer/" + *product.ThumbnailPath + // Extract filename from path + filename := filepath.Base(*product.ThumbnailPath) + thumbnailUrl := host + "/products/viewer/" + filename response.ThumbnailUrl = &thumbnailUrl } diff --git a/app/module/products/request/products.request.go b/app/module/products/request/products.request.go index 4f31591..65777a8 100644 --- a/app/module/products/request/products.request.go +++ b/app/module/products/request/products.request.go @@ -33,7 +33,7 @@ func (req ProductsQueryRequestContext) ToParamRequest() ProductsQueryRequest { type ProductsCreateRequest struct { Title string `json:"title" validate:"required"` Variant *string `json:"variant"` - Price *float64 `json:"price"` + Price *string `json:"price"` ThumbnailPath *string `json:"thumbnail_path"` Colors []string `json:"colors"` } @@ -55,12 +55,12 @@ func (req ProductsCreateRequest) ToEntity() *entity.Products { } type ProductsUpdateRequest struct { - Title *string `json:"title"` - Variant *string `json:"variant"` - Price *float64 `json:"price"` - ThumbnailPath *string `json:"thumbnail_path"` - Colors []string `json:"colors"` - IsActive *bool `json:"is_active"` + Title *string `json:"title"` + Variant *string `json:"variant"` + Price *string `json:"price"` + ThumbnailPath *string `json:"thumbnail_path"` + Colors []string `json:"colors"` + IsActive *bool `json:"is_active"` } func (req ProductsUpdateRequest) ToEntity() *entity.Products { @@ -86,4 +86,3 @@ func getStringValue(s *string) string { } return *s } - diff --git a/app/module/products/response/products.response.go b/app/module/products/response/products.response.go index 675a1e7..fe9145b 100644 --- a/app/module/products/response/products.response.go +++ b/app/module/products/response/products.response.go @@ -8,7 +8,7 @@ type ProductsResponse struct { ID uint `json:"id"` Title string `json:"title"` Variant *string `json:"variant"` - Price *float64 `json:"price"` + Price *string `json:"price"` ThumbnailPath *string `json:"thumbnail_path"` ThumbnailUrl *string `json:"thumbnail_url"` Colors []string `json:"colors"` diff --git a/app/module/products/service/products.service.go b/app/module/products/service/products.service.go index 6704a55..5752fdc 100644 --- a/app/module/products/service/products.service.go +++ b/app/module/products/service/products.service.go @@ -195,7 +195,7 @@ func (_i *productsService) Delete(id uint) (err error) { func (_i *productsService) Viewer(c *fiber.Ctx) (err error) { filename := c.Params("filename") - // Find product by thumbnail path + // Find product by filename (repository will search using LIKE pattern) result, err := _i.Repo.FindByThumbnailPath(filename) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ diff --git a/app/module/promotions/controller/promotions.controller.go b/app/module/promotions/controller/promotions.controller.go index d96f517..5b1ec89 100644 --- a/app/module/promotions/controller/promotions.controller.go +++ b/app/module/promotions/controller/promotions.controller.go @@ -228,7 +228,7 @@ func (_i *promotionsController) Delete(c *fiber.Ctx) error { // @Tags Promotions // @Security Bearer // @Param X-Client-Key header string true "Insert the X-Client-Key" -// @Param filename path string true "Promotion File Path" +// @Param filename path string true "Promotion File Name (e.g., user_277788.png)" // @Success 200 {file} file // @Failure 400 {object} response.BadRequestError // @Failure 401 {object} response.UnauthorizedError diff --git a/app/module/promotions/mapper/promotions.mapper.go b/app/module/promotions/mapper/promotions.mapper.go index e1500c7..f2b1f94 100644 --- a/app/module/promotions/mapper/promotions.mapper.go +++ b/app/module/promotions/mapper/promotions.mapper.go @@ -3,6 +3,7 @@ package mapper import ( "jaecoo-be/app/database/entity" res "jaecoo-be/app/module/promotions/response" + "path/filepath" ) func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.PromotionsResponse { @@ -21,7 +22,9 @@ func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.Pr } if promotion.ThumbnailPath != nil && *promotion.ThumbnailPath != "" { - thumbnailUrl := host + "/promotions/thumbnail/viewer/" + *promotion.ThumbnailPath + // Extract filename from path + filename := filepath.Base(*promotion.ThumbnailPath) + thumbnailUrl := host + "/promotions/viewer/" + filename response.ThumbnailUrl = &thumbnailUrl } diff --git a/app/module/promotions/service/promotions.service.go b/app/module/promotions/service/promotions.service.go index 15aed23..c0228cb 100644 --- a/app/module/promotions/service/promotions.service.go +++ b/app/module/promotions/service/promotions.service.go @@ -195,7 +195,7 @@ func (_i *promotionsService) Delete(id uint) (err error) { func (_i *promotionsService) Viewer(c *fiber.Ctx) (err error) { filename := c.Params("filename") - // Find promotion by thumbnail path + // Find promotion by filename (repository will search using LIKE pattern) result, err := _i.Repo.FindByThumbnailPath(filename) if err != nil { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 5d87973..a052bcf 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -3426,7 +3426,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Banner File Path", + "description": "Banner File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -5440,7 +5440,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Gallery File Path", + "description": "Gallery File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -5835,7 +5835,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Product Specification File Path", + "description": "Product Specification File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -6179,7 +6179,7 @@ const docTemplate = `{ "in": "formData" }, { - "type": "number", + "type": "string", "description": "Product price", "name": "price", "in": "formData" @@ -6241,7 +6241,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Product File Path", + "description": "Product File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -6630,7 +6630,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Promotion File Path", + "description": "Promotion File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -10406,7 +10406,7 @@ const docTemplate = `{ "type": "boolean" }, "price": { - "type": "number" + "type": "string" }, "thumbnail_path": { "type": "string" diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index ae23bd9..d36c101 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -3415,7 +3415,7 @@ }, { "type": "string", - "description": "Banner File Path", + "description": "Banner File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -5429,7 +5429,7 @@ }, { "type": "string", - "description": "Gallery File Path", + "description": "Gallery File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -5824,7 +5824,7 @@ }, { "type": "string", - "description": "Product Specification File Path", + "description": "Product Specification File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -6168,7 +6168,7 @@ "in": "formData" }, { - "type": "number", + "type": "string", "description": "Product price", "name": "price", "in": "formData" @@ -6230,7 +6230,7 @@ }, { "type": "string", - "description": "Product File Path", + "description": "Product File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -6619,7 +6619,7 @@ }, { "type": "string", - "description": "Promotion File Path", + "description": "Promotion File Name (e.g., user_277788.png)", "name": "filename", "in": "path", "required": true @@ -10395,7 +10395,7 @@ "type": "boolean" }, "price": { - "type": "number" + "type": "string" }, "thumbnail_path": { "type": "string" diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 20ef1df..1f47f83 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -436,7 +436,7 @@ definitions: is_active: type: boolean price: - type: number + type: string thumbnail_path: type: string title: @@ -3133,7 +3133,7 @@ paths: name: X-Client-Key required: true type: string - - description: Banner File Path + - description: Banner File Name (e.g., user_277788.png) in: path name: filename required: true @@ -4415,7 +4415,7 @@ paths: name: X-Client-Key required: true type: string - - description: Gallery File Path + - description: Gallery File Name (e.g., user_277788.png) in: path name: filename required: true @@ -4668,7 +4668,7 @@ paths: name: X-Client-Key required: true type: string - - description: Product Specification File Path + - description: Product Specification File Name (e.g., user_277788.png) in: path name: filename required: true @@ -4780,7 +4780,7 @@ paths: - description: Product price in: formData name: price - type: number + type: string - description: Product colors (JSON array) in: formData name: colors @@ -4928,7 +4928,7 @@ paths: name: X-Client-Key required: true type: string - - description: Product File Path + - description: Product File Name (e.g., user_277788.png) in: path name: filename required: true @@ -5177,7 +5177,7 @@ paths: name: X-Client-Key required: true type: string - - description: Promotion File Path + - description: Promotion File Name (e.g., user_277788.png) in: path name: filename required: true