merch-api/internal/merch/controller.go
2026-03-10 23:44:24 +03:00

372 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package merch
import (
"errors"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"merch-api/pkg/responses"
"merch-api/pkg/utils"
"net/http"
)
const controllerLogHeader string = "[Controller]"
type controller struct {
service *service
utils utils.Utils
}
func newController(s *service, u utils.Utils) *controller {
return &controller{
service: s,
utils: u,
}
}
func (h *Handler) RegisterRoutes(r *gin.RouterGroup) {
merchGroup := r.Group("/merch")
merchGroup.POST("/create", h.controller.create)
merchGroup.GET("/:id", h.controller.getOne)
merchGroup.GET("/list", h.controller.getMany)
merchGroup.PUT("/:id", h.controller.updateMerch)
merchGroup.PUT("/extra/:id", h.controller.updateExtraData)
merchGroup.DELETE("/:id", h.controller.deleteMerch)
originsGroup := merchGroup.Group("/origins")
originsGroup.POST("", h.controller.createOrigin)
originsGroup.GET("", h.controller.getOrigins)
originsGroup.DELETE("", h.controller.deleteOrigin)
chartsGroup := r.Group("/prices")
chartsGroup.GET("", h.controller.getChartsPrices)
chartsGroup.GET("/:uuid", h.controller.getDistinctPrices)
}
// create godoc
//
// @Summary Create new merch
// @Description Create new merch
// @Tags Merch
// @Accept json
// @Param merch body newMerchDTO true "merch body"
// @Success 201
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/create [POST]
func (co *controller) create(c *gin.Context) {
var newMerch newMerchDTO
if err := c.ShouldBindJSON(&newMerch); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if err := co.service.createMerch(c, getUserId(c), &newMerch); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.Status(http.StatusCreated)
}
func (co *controller) getOne(c *gin.Context) {}
// getMany godoc
//
// @Summary Get all merch
// @Description Get all merch without origins
// @Tags Merch
// @Produce json
// @Success 200 {array} merchDTO
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/list [GET]
func (co *controller) getMany(c *gin.Context) {
response, err := co.service.getMany(c, getUserId(c))
if err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if len(response) == 0 {
c.Status(http.StatusNoContent)
return
}
c.JSON(http.StatusOK, response)
}
// updateMerch godoc
//
// @Summary Update merch
// @Description Update merch general info (except extra data)
// @Tags Merch
// @Accept json
// @Param uuid path string true "merch uuid"
// @Param payload body updateMerchDTO true "payload"
// @Produce json
// @Success 200 {object} merchDTO
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/{uuid} [PUT]
func (co *controller) updateMerch(c *gin.Context) {
merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
var payload updateMerchDTO
if err := c.ShouldBindJSON(&payload); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if merchUuid != payload.MerchUuid {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: "MerchUuid does not match"})
logErr(controllerLogHeader, errors.New("MerchUuid does not match"))
return
}
response, err := co.service.updateMerch(c, getUserId(c), &payload)
if err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.JSON(http.StatusOK, response)
}
// updateMerch godoc
//
// @Summary Update merch extra data
// @Description Update ONLY merch extra data
// @Tags Merch
// @Accept json
// @Param uuid path string true "merch uuid"
// @Param payload body extraDataDTO true "payload"
// @Produce json
// @Success 200 {object} extraDataDTO
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/extra/{uuid} [PUT]
func (co *controller) updateExtraData(c *gin.Context) {
merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
var payload extraDataDTO
if err := c.ShouldBindJSON(&payload); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if merchUuid != payload.MerchUuid {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: "MerchUuid does not match"})
logErr(controllerLogHeader, errors.New("MerchUuid does not match"))
return
}
response, err := co.service.updateExtraData(c, getUserId(c), &payload)
if err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.JSON(http.StatusOK, response)
}
// deleteMerch godoc
//
// @Summary Delete merch
// @Description Marks merch and all its extra data as deleted by uuid.
// @Tags Merch
// @Accept json
// @Param uuid path string true "merch uuid"
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/{uuid} [DELETE]
func (co *controller) deleteMerch(c *gin.Context) {
merchUuid := c.Param("id")
if err := uuid.Validate(merchUuid); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if err := co.service.deleteOneMerchRecord(c, getUserId(c), merchUuid); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.Status(http.StatusNoContent)
}
// createOrigin godoc
//
// @Summary Create new origin
// @Description Create new origin with name
// @Tags Origins
// @Accept json
// @Param origin body newOriginDTO true "origin body"
// @Success 201
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [POST]
func (co *controller) createOrigin(c *gin.Context) {
var origin *newOriginDTO
if err := c.ShouldBindJSON(&origin); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if err := co.service.createOrigin(c, origin); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
logDebug(controllerLogHeader, "create origin success")
c.Status(http.StatusCreated)
}
// getOrigins godoc
//
// @Summary Get all origins
// @Description Get all origins
// @Tags Origins
// @Produce json
// @Success 200 {object} originsDTO
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [GET]
func (co *controller) getOrigins(c *gin.Context) {
response, err := co.service.getOrigins(c)
if err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
logDebug(controllerLogHeader, "get origins success")
c.JSON(http.StatusOK, response)
}
// deleteOrigin godoc
//
// @Summary Delete origin
// @Description Marks origin as deleted by name.
// @Tags Origins
// @Accept json
// @Param origin body deleteOriginDTO true "origin body"
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /merch/origins [DELETE]
func (co *controller) deleteOrigin(c *gin.Context) {
var origin *deleteOriginDTO
if err := c.ShouldBindJSON(&origin); err != nil {
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if err := co.service.deleteOrigin(c, origin); err != nil {
c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
logDebug(controllerLogHeader, "delete origin success")
c.Status(http.StatusNoContent)
}
// getChartsPrices godoc
//
// @Summary Получить цены мерча за период
// @Description Получить цены мерча за период
// @Tags Merch
// @Security BearerAuth
// @Produce json
// @Param days query string false "period in days"
// @Success 200 {array} PricesResponse
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /prices [get]
func (co *controller) getChartsPrices(c *gin.Context) {
response, err := co.service.getPrices(c, getUserId(c), getDays(c))
if err != nil {
c.JSON(http.StatusBadRequest, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
c.JSON(http.StatusOK, response)
}
// getDistinctPrices godoc
//
// @Summary Получить перепады цен мерча за период по его merch_uuid
// @Description Получить перепады цен мерча за период по его merch_uuid
// @Tags Merch
// @Security BearerAuth
// @Produce json
// @Param uuid path string true "merch_uuid"
// @Param days query string false "period in days"
// @Success 200 {object} PricesResponse
// @Success 204
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 500 {object} responses.InternalServerError
// @Router /prices/{uuid} [get]
func (co *controller) getDistinctPrices(c *gin.Context) {
merchUuid := c.Param("uuid")
if merchUuid == "" {
err := errors.New("MerchUuid is empty")
c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
response, err := co.service.getDistinctPrices(c, getUserId(c), merchUuid, getDays(c))
if err != nil {
c.JSON(http.StatusBadRequest, responses.InternalServerError{Error: err.Error()})
logErr(controllerLogHeader, err)
return
}
if response == nil {
c.Status(http.StatusNoContent)
return
}
c.JSON(http.StatusOK, response)
}