diff --git a/docs/docs.go b/docs/docs.go index 9ec07c9..b97688b 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -15,6 +15,51 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/merch": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Добавить новый мерч", + "consumes": [ + "application/json" + ], + "tags": [ + "Merch" + ], + "summary": "Добавить новый мерч", + "parameters": [ + { + "description": "новый мерч", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/merch.MerchDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse400" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse500" + } + } + } + } + }, "/merch/": { "get": { "security": [ @@ -96,49 +141,6 @@ const docTemplate = `{ } } } - }, - "post": { - "security": [ - { - "BearerAuth": [] - } - ], - "description": "Добавить новый мерч", - "consumes": [ - "application/json" - ], - "tags": [ - "Merch" - ], - "summary": "Добавить новый мерч", - "parameters": [ - { - "description": "новый мерч", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/merch.MerchDTO" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse400" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse500" - } - } - } } }, "/merch/images/{uuid}": { @@ -673,53 +675,6 @@ const docTemplate = `{ } } }, - "/merch/zeroprices/period": { - "delete": { - "security": [ - { - "BearerAuth": [] - } - ], - "description": "Пометить нулевые цены как удаленные за указанный период", - "tags": [ - "Merch zero prices" - ], - "summary": "Пометить нулевые цены как удаленные за указанный период", - "parameters": [ - { - "type": "string", - "description": "start", - "name": "start", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "end", - "name": "end", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse400" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse500" - } - } - } - } - }, "/merch/{uuid}": { "get": { "security": [ @@ -1220,14 +1175,6 @@ const docTemplate = `{ } } }, - "merch.AmiamiDTO": { - "type": "object", - "properties": { - "link": { - "type": "string" - } - } - }, "merch.DeleteZeroPrices": { "type": "object", "properties": { @@ -1332,9 +1279,6 @@ const docTemplate = `{ "name": { "type": "string" }, - "origin_amiami": { - "$ref": "#/definitions/merch.AmiamiDTO" - }, "origin_mandarake": { "$ref": "#/definitions/merch.MandarakeDTO" }, @@ -1346,7 +1290,7 @@ const docTemplate = `{ "merch.OriginWithPrices": { "type": "object", "properties": { - "origins": { + "origin": { "type": "integer" }, "prices": { @@ -1405,7 +1349,7 @@ const docTemplate = `{ "name": { "type": "string" }, - "origins": { + "origin": { "type": "string" } } @@ -1425,8 +1369,8 @@ const docTemplate = `{ "name": { "type": "string" }, - "origins": { - "type": "integer" + "origin": { + "type": "string" } } }, diff --git a/docs/swagger.json b/docs/swagger.json index d132129..f746266 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -7,6 +7,51 @@ }, "basePath": "/api/v2", "paths": { + "/merch": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Добавить новый мерч", + "consumes": [ + "application/json" + ], + "tags": [ + "Merch" + ], + "summary": "Добавить новый мерч", + "parameters": [ + { + "description": "новый мерч", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/merch.MerchDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse400" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse500" + } + } + } + } + }, "/merch/": { "get": { "security": [ @@ -88,49 +133,6 @@ } } } - }, - "post": { - "security": [ - { - "BearerAuth": [] - } - ], - "description": "Добавить новый мерч", - "consumes": [ - "application/json" - ], - "tags": [ - "Merch" - ], - "summary": "Добавить новый мерч", - "parameters": [ - { - "description": "новый мерч", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/merch.MerchDTO" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse400" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse500" - } - } - } } }, "/merch/images/{uuid}": { @@ -665,53 +667,6 @@ } } }, - "/merch/zeroprices/period": { - "delete": { - "security": [ - { - "BearerAuth": [] - } - ], - "description": "Пометить нулевые цены как удаленные за указанный период", - "tags": [ - "Merch zero prices" - ], - "summary": "Пометить нулевые цены как удаленные за указанный период", - "parameters": [ - { - "type": "string", - "description": "start", - "name": "start", - "in": "query", - "required": true - }, - { - "type": "string", - "description": "end", - "name": "end", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse400" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/responses.ErrorResponse500" - } - } - } - } - }, "/merch/{uuid}": { "get": { "security": [ @@ -1212,14 +1167,6 @@ } } }, - "merch.AmiamiDTO": { - "type": "object", - "properties": { - "link": { - "type": "string" - } - } - }, "merch.DeleteZeroPrices": { "type": "object", "properties": { @@ -1324,9 +1271,6 @@ "name": { "type": "string" }, - "origin_amiami": { - "$ref": "#/definitions/merch.AmiamiDTO" - }, "origin_mandarake": { "$ref": "#/definitions/merch.MandarakeDTO" }, @@ -1338,7 +1282,7 @@ "merch.OriginWithPrices": { "type": "object", "properties": { - "origins": { + "origin": { "type": "integer" }, "prices": { @@ -1397,7 +1341,7 @@ "name": { "type": "string" }, - "origins": { + "origin": { "type": "string" } } @@ -1417,8 +1361,8 @@ "name": { "type": "string" }, - "origins": { - "type": "integer" + "origin": { + "type": "string" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ea2f927..883b177 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -7,11 +7,6 @@ definitions: thumbnail: type: string type: object - merch.AmiamiDTO: - properties: - link: - type: string - type: object merch.DeleteZeroPrices: properties: id: @@ -79,8 +74,6 @@ definitions: type: string name: type: string - origin_amiami: - $ref: '#/definitions/merch.AmiamiDTO' origin_mandarake: $ref: '#/definitions/merch.MandarakeDTO' origin_surugaya: @@ -88,7 +81,7 @@ definitions: type: object merch.OriginWithPrices: properties: - origins: + origin: type: integer prices: items: @@ -126,7 +119,7 @@ definitions: type: string name: type: string - origins: + origin: type: string type: object merch.ZeroPrice: @@ -139,8 +132,8 @@ definitions: type: string name: type: string - origins: - type: integer + origin: + type: string type: object responses.ErrorResponse400: properties: @@ -209,31 +202,7 @@ info: title: Merch Parser version: 2.0.0-alpha paths: - /merch/: - get: - description: Получить все записи мерча - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/merch.ListResponse' - type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/responses.ErrorResponse400' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/responses.ErrorResponse500' - security: - - BearerAuth: [] - summary: Получить все записи мерча - tags: - - Merch + /merch: post: consumes: - application/json @@ -261,6 +230,31 @@ paths: summary: Добавить новый мерч tags: - Merch + /merch/: + get: + description: Получить все записи мерча + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/merch.ListResponse' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/responses.ErrorResponse400' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/responses.ErrorResponse500' + security: + - BearerAuth: [] + summary: Получить все записи мерча + tags: + - Merch put: consumes: - application/json @@ -680,36 +674,6 @@ paths: summary: Получить нулевые цены tags: - Merch zero prices - /merch/zeroprices/period: - delete: - description: Пометить нулевые цены как удаленные за указанный период - parameters: - - description: start - in: query - name: start - required: true - type: string - - description: end - in: query - name: end - required: true - type: string - responses: - "200": - description: OK - "400": - description: Bad Request - schema: - $ref: '#/definitions/responses.ErrorResponse400' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/responses.ErrorResponse500' - security: - - BearerAuth: [] - summary: Пометить нулевые цены как удаленные за указанный период - tags: - - Merch zero prices /prices: get: description: Получить цены мерча за период diff --git a/internal/api/merch/controller.go b/internal/api/merch/controller.go index 994c677..7ea9636 100644 --- a/internal/api/merch/controller.go +++ b/internal/api/merch/controller.go @@ -54,9 +54,6 @@ func (h *Handler) RegisterRoutes(r *gin.RouterGroup, authMW gin.HandlerFunc, ref zeroPricesGroup := merchGroup.Group("/zeroprices", authMW) zeroPricesGroup.GET("", h.controller.getZeroPrices) zeroPricesGroup.DELETE("", h.controller.deleteZeroPrices) - - zeroPricesGroup.DELETE("/period", h.controller.deleteZeroPricesPeriod) - } // @Summary Добавить новый мерч @@ -68,7 +65,7 @@ func (h *Handler) RegisterRoutes(r *gin.RouterGroup, authMW gin.HandlerFunc, ref // @Success 200 // @Failure 400 {object} responses.ErrorResponse400 // @Failure 500 {object} responses.ErrorResponse500 -// @Router /merch/ [post] +// @Router /merch [post] func (co *controller) addMerch(c *gin.Context) { var payload MerchDTO if err := c.ShouldBind(&payload); err != nil { @@ -159,7 +156,7 @@ func (co *controller) getAllMerch(c *gin.Context) { // @Description Обновить информацию про мерч по его uuid в json-е // @Tags Merch // @Security BearerAuth -// @Accept json +// @Accept json // @Param body body UpdateMerchDTO true "merch_uuid" // @Success 200 // @Failure 400 {object} responses.ErrorResponse400 @@ -197,7 +194,7 @@ func (co *controller) updateMerch(c *gin.Context) { // @Failure 400 {object} responses.ErrorResponse400 // @Failure 500 {object} responses.ErrorResponse500 // -// @Router /merch/{uuid} [delete] +// @Router /merch/{uuid} [delete] func (co *controller) deleteMerch(c *gin.Context) { merchUuid := c.Param("uuid") if merchUuid == "" { @@ -231,6 +228,10 @@ func (co *controller) deleteMerch(c *gin.Context) { // @Failure 400 {object} responses.ErrorResponse400 // @Failure 500 {object} responses.ErrorResponse500 // @Router /prices [get] +// +// @Failure 400 {object} responses.ErrorResponse400 +// @Failure 500 {object} responses.ErrorResponse500 +// @Router /prices [get] func (co *controller) getChartsPrices(c *gin.Context) { daysQuery := strings.ToLower(c.DefaultQuery("days", "")) @@ -441,7 +442,7 @@ func (co *controller) deleteMerchImage(c *gin.Context) { // @Description Создать новую метку для товара // @Tags Merch labels // @Security BearerAuth -// @Accept json +// @Accept json // @Param payload body LabelDTO true "payload" // @Success 200 // @Failure 400 {object} responses.ErrorResponse400 @@ -506,7 +507,7 @@ func (co *controller) getLabels(c *gin.Context) { // @Description Изменить метку // @Tags Merch labels // @Security BearerAuth -// @Accept json +// @Accept json // @Param uuid path string true "label uuid" // @Param payload body LabelDTO true "payload" // @Success 200 @@ -579,16 +580,16 @@ func (co *controller) deleteLabel(c *gin.Context) { c.Status(http.StatusOK) } -// @Summary Прикрепить метку к товару -// @Description Прикрепить метку к товару -// @Tags Merch labels -// @Security BearerAuth -// @Accept json -// @Param payload body LabelLink true "payload" -// @Success 200 -// @Failure 400 {object} responses.ErrorResponse400 -// @Failure 500 {object} responses.ErrorResponse500 -// @Router /merch/labels/attach [post] +// @Summary Прикрепить метку к товару +// @Description Прикрепить метку к товару +// @Tags Merch labels +// @Security BearerAuth +// @Accept json +// @Param payload body LabelLink true "payload" +// @Success 200 +// @Failure 400 {object} responses.ErrorResponse400 +// @Failure 500 {object} responses.ErrorResponse500 +// @Router /merch/labels/attach [post] func (co *controller) attachLabel(c *gin.Context) { const logMsg = "Merch | Attach label" @@ -614,16 +615,16 @@ func (co *controller) attachLabel(c *gin.Context) { c.Status(http.StatusOK) } -// @Summary Удалить привязку метки к товару -// @Description Удалить привязку метки к товару -// @Tags Merch labels -// @Security BearerAuth -// @Accept json -// @Param payload body LabelLink true "payload" -// @Success 200 -// @Failure 400 {object} responses.ErrorResponse400 -// @Failure 500 {object} responses.ErrorResponse500 -// @Router /merch/labels/detach [post] +// @Summary Удалить привязку метки к товару +// @Description Удалить привязку метки к товару +// @Tags Merch labels +// @Security BearerAuth +// @Accept json +// @Param payload body LabelLink true "payload" +// @Success 200 +// @Failure 400 {object} responses.ErrorResponse400 +// @Failure 500 {object} responses.ErrorResponse500 +// @Router /merch/labels/detach [post] func (co *controller) detachLabel(c *gin.Context) { const logMsg = "Merch | Detach label" @@ -718,7 +719,7 @@ func (co *controller) getZeroPrices(c *gin.Context) { // @Description Пометить нулевые цены как удаленные // @Tags Merch zero prices // @Security BearerAuth -// @Accept json +// @Accept json // @Param payload body DeleteZeroPrices true "payload" // @Success 200 // @Failure 400 {object} responses.ErrorResponse400 @@ -748,45 +749,3 @@ func (co *controller) deleteZeroPrices(c *gin.Context) { } c.Status(http.StatusOK) } - -// @Summary Пометить нулевые цены как удаленные за указанный период -// @Description Пометить нулевые цены как удаленные за указанный период -// @Tags Merch zero prices -// @Security BearerAuth -// @Param start query string true "start" -// @Param end query string true "end" -// @Success 200 -// @Failure 400 {object} responses.ErrorResponse400 -// @Failure 500 {object} responses.ErrorResponse500 -// @Router /merch/zeroprices/period [delete] -func (co *controller) deleteZeroPricesPeriod(c *gin.Context) { - const logMsg = "Merch | Delete zero prices period" - - userUuid, err := co.utils.GetUserUuidFromContext(c) - if err != nil { - c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()}) - log.WithError(err).Error(logMsg) - return - } - - start, err := co.utils.ParseTime(c.Query("start")) - if err != nil { - c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: err.Error()}) - log.WithError(err).Error(logMsg) - return - } - - end, err := co.utils.ParseTime(c.Query("end")) - if err != nil { - c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: err.Error()}) - log.WithError(err).Error(logMsg) - return - } - - if err = co.service.deleteZeroPricesPeriod(userUuid, start, end); err != nil { - c.JSON(http.StatusInternalServerError, responses.ErrorResponse500{Error: err.Error()}) - log.WithError(err).Error(logMsg) - return - } - c.Status(http.StatusOK) -} diff --git a/internal/api/merch/dto.go b/internal/api/merch/dto.go index c64787e..7ee7281 100644 --- a/internal/api/merch/dto.go +++ b/internal/api/merch/dto.go @@ -1,46 +1,32 @@ package merch -import ( - "merch-parser-api/internal/api/merch/origins" - "time" -) +import "time" type merchBundle struct { Merch *Merch - Surugaya *origins.OriginSurugaya - Mandarake *origins.OriginMandarake - Amiami *origins.OriginAmiami + Surugaya *Surugaya + Mandarake *Mandarake } type MerchDTO struct { MerchUuid string `json:"merch_uuid"` Name string `json:"name"` OriginSurugaya SurugayaDTO `json:"origin_surugaya"` OriginMandarake MandarakeDTO `json:"origin_mandarake"` - OriginAmiami AmiamiDTO `json:"origin_amiami"` Labels []string `json:"labels,omitempty" gorm:"-"` } -type OriginDTO struct { - Link string `json:"link"` - Name origins.Origin `json:"name,omitempty"` -} - type SurugayaDTO struct { - OriginDTO + Link string `json:"link"` } type MandarakeDTO struct { - OriginDTO -} - -type AmiamiDTO struct { - OriginDTO + Link string `json:"link"` } type SingleMerchResponse struct { - MerchUuid string `json:"merch_uuid"` - Name string `json:"name"` - Origins []OriginDTO `json:"origins"` + MerchUuid string `json:"merch_uuid"` + Name string `json:"name"` + Origins []any `json:"origins"` } type ListResponse struct { @@ -55,7 +41,7 @@ type PriceEntry struct { } type OriginWithPrices struct { - Origin origins.Origin `json:"origin"` + Origin Origin `json:"origin"` Prices []PriceEntry } @@ -96,11 +82,11 @@ type LabelLink struct { } type ZeroPrice struct { - Id int `json:"id"` - CreatedAt time.Time `json:"created_at"` - MerchUuid string `json:"merch_uuid"` - Name string `json:"name"` - Origin origins.Origin `json:"origin"` + Id int `json:"id"` + CreatedAt time.Time `json:"created_at"` + MerchUuid string `json:"merch_uuid"` + Name string `json:"name"` + Origin string `json:"origin"` } type DeleteZeroPrices struct { diff --git a/internal/api/merch/model.go b/internal/api/merch/model.go index 702edf0..2dd6e0e 100644 --- a/internal/api/merch/model.go +++ b/internal/api/merch/model.go @@ -2,7 +2,6 @@ package merch import ( "database/sql" - "merch-parser-api/internal/api/merch/origins" "time" ) @@ -20,14 +19,36 @@ func (Merch) TableName() string { return "merch" } +type Surugaya struct { + Id uint `gorm:"primary_key" json:"-"` + DeletedAt sql.NullTime `json:"-"` + MerchUuid string `json:"-"` + Link string `json:"link"` +} + +func (Surugaya) TableName() string { + return "origin_surugaya" +} + +type Mandarake struct { + Id uint `gorm:"primary_key" json:"-"` + DeletedAt sql.NullTime `json:"-"` + MerchUuid string `json:"-"` + Link string `json:"link"` +} + +func (Mandarake) TableName() string { + return "origin_mandarake" +} + type Price struct { - Id uint `json:"id" gorm:"primary_key"` - CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` - UpdatedAt sql.NullTime `json:"updated_at,omitempty" gorm:"column:updated_at"` - DeletedAt sql.NullTime `json:"deleted_at,omitempty" gorm:"column:deleted_at"` - MerchUuid string `json:"merch_uuid" gorm:"column:merch_uuid"` - Price int `json:"price" gorm:"column:price"` - Origin origins.Origin `json:"origin" gorm:"column:origin;type:integer"` + Id uint `json:"id" gorm:"primary_key"` + CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` + UpdatedAt sql.NullTime `json:"updated_at,omitempty" gorm:"column:updated_at"` + DeletedAt sql.NullTime `json:"deleted_at,omitempty" gorm:"column:deleted_at"` + MerchUuid string `json:"merch_uuid" gorm:"column:merch_uuid"` + Price int `json:"price" gorm:"column:price"` + Origin Origin `json:"origin" gorm:"column:origin;type:integer"` } type Label struct { diff --git a/internal/api/merch/origins/types.go b/internal/api/merch/origins.go similarity index 83% rename from internal/api/merch/origins/types.go rename to internal/api/merch/origins.go index 303176c..22175e5 100644 --- a/internal/api/merch/origins/types.go +++ b/internal/api/merch/origins.go @@ -1,4 +1,4 @@ -package origins +package merch import ( "database/sql/driver" @@ -9,15 +9,13 @@ import ( type Origin int const ( - Surugaya = (iota + 1) * 1000 - Mandarake - Amiami + surugaya = (iota + 1) * 1000 + mandarake ) var Origins = [...]string{ "surugaya", "mandarake", - "amiami", } func (o Origin) String() string { @@ -32,7 +30,7 @@ func (o Origin) MarshalJSON() ([]byte, error) { return json.Marshal(o.String()) } -func ParseOrigin(s string) (Origin, bool) { +func parseOrigin(s string) (Origin, bool) { for i, name := range Origins { if name == strings.ToLower(s) { return Origin((i + 1) * 1000), true diff --git a/internal/api/merch/origins/constructor.go b/internal/api/merch/origins/constructor.go deleted file mode 100644 index 2a51534..0000000 --- a/internal/api/merch/origins/constructor.go +++ /dev/null @@ -1,55 +0,0 @@ -package origins - -import "database/sql" - -func AllOriginModels() []interface{} { - return []interface{}{ - &OriginSurugaya{}, - &OriginMandarake{}, - &OriginAmiami{}, - } -} - -func NewSurugaya(merchUuid, link string) *OriginSurugaya { - return &OriginSurugaya{ - BaseOrigin{ - DeletedAt: sql.NullTime{}, - MerchUuid: merchUuid, - Link: link, - }, - } -} - -func NewMandarake(merchUuid, link string) *OriginMandarake { - return &OriginMandarake{ - BaseOrigin{ - DeletedAt: sql.NullTime{}, - MerchUuid: merchUuid, - Link: link, - }, - } -} - -func NewAmiami(merchUuid, link string) *OriginAmiami { - return &OriginAmiami{ - BaseOrigin{ - DeletedAt: sql.NullTime{}, - MerchUuid: merchUuid, - Link: link, - }, - } -} - -type OriginFactory func(merchUuid, link string) interface{} - -var OriginFactories = map[string]OriginFactory{ - "surugaya": func(merchUuid, link string) interface{} { - return &OriginSurugaya{BaseOrigin: BaseOrigin{MerchUuid: merchUuid, Link: link}} - }, - "mandarake": func(merchUuid, link string) interface{} { - return &OriginMandarake{BaseOrigin: BaseOrigin{MerchUuid: merchUuid, Link: link}} - }, - "amiami": func(merchUuid, link string) interface{} { - return &OriginAmiami{BaseOrigin: BaseOrigin{MerchUuid: merchUuid, Link: link}} - }, -} diff --git a/internal/api/merch/origins/model.go b/internal/api/merch/origins/model.go deleted file mode 100644 index d2ee8cf..0000000 --- a/internal/api/merch/origins/model.go +++ /dev/null @@ -1,34 +0,0 @@ -package origins - -import "database/sql" - -type BaseOrigin struct { - Id uint `gorm:"primary_key" json:"-"` - DeletedAt sql.NullTime `json:"-"` - MerchUuid string `json:"-"` - Link string `json:"link"` -} - -type OriginSurugaya struct { - BaseOrigin -} - -func (OriginSurugaya) TableName() string { - return "origin_surugaya" -} - -type OriginMandarake struct { - BaseOrigin -} - -func (OriginMandarake) TableName() string { - return "origin_mandarake" -} - -type OriginAmiami struct { - BaseOrigin -} - -func (OriginAmiami) TableName() string { - return "origin_amiami" -} diff --git a/internal/api/merch/provider.go b/internal/api/merch/provider.go index c70da91..27ab846 100644 --- a/internal/api/merch/provider.go +++ b/internal/api/merch/provider.go @@ -4,14 +4,13 @@ import ( "database/sql" log "github.com/sirupsen/logrus" "gorm.io/gorm" - "merch-parser-api/internal/api/merch/origins" "merch-parser-api/internal/shared" "time" ) type Link struct { - Surugaya []origins.OriginSurugaya - Mandarake []origins.OriginMandarake + Surugaya []Surugaya + Mandarake []Mandarake } type TaskProvider struct { @@ -85,7 +84,7 @@ func (p *TaskProvider) InsertPrices(prices []shared.TaskResult) error { var insertPrices []Price for _, item := range prices { - origin, ok := origins.ParseOrigin(item.Origin) + origin, ok := parseOrigin(item.Origin) if !ok { continue } @@ -108,13 +107,13 @@ func (p *TaskProvider) InsertPrices(prices []shared.TaskResult) error { } func (r *TaskRepo) getLinks() (*Link, error) { - var surugayaList []origins.OriginSurugaya - if err := r.db.Model(&origins.OriginSurugaya{}).Where("deleted_at IS NULL").Find(&surugayaList).Error; err != nil { + var surugayaList []Surugaya + if err := r.db.Model(&Surugaya{}).Where("deleted_at IS NULL").Find(&surugayaList).Error; err != nil { return nil, err } - var mandarakeList []origins.OriginMandarake - if err := r.db.Model(&origins.OriginMandarake{}).Where("deleted_at IS NULL").Find(&mandarakeList).Error; err != nil { + var mandarakeList []Mandarake + if err := r.db.Model(&Mandarake{}).Where("deleted_at IS NULL").Find(&mandarakeList).Error; err != nil { return nil, err } diff --git a/internal/api/merch/repository.go b/internal/api/merch/repository.go index 7283fa9..e84f551 100644 --- a/internal/api/merch/repository.go +++ b/internal/api/merch/repository.go @@ -3,10 +3,8 @@ package merch import ( "database/sql" "errors" - "fmt" "gorm.io/gorm" "gorm.io/gorm/clause" - "merch-parser-api/internal/api/merch/origins" "time" ) @@ -44,7 +42,6 @@ type prices interface { getZeroPrices(userUuid string) ([]ZeroPrice, error) deleteZeroPrices(list []DeleteZeroPrices) error - deleteZeroPricesPeriod(userUuid string, start, end time.Time) error } type labels interface { @@ -63,15 +60,11 @@ func (r *Repo) addMerch(bundle merchBundle) error { return err } - if err := r.db.Model(&origins.OriginSurugaya{}).Create(bundle.Surugaya).Error; err != nil { + if err := r.db.Model(&Surugaya{}).Create(bundle.Surugaya).Error; err != nil { return err } - if err := r.db.Model(&origins.OriginMandarake{}).Create(bundle.Mandarake).Error; err != nil { - return err - } - - if err := r.db.Model(&origins.OriginAmiami{}).Create(bundle.Amiami).Error; err != nil { + if err := r.db.Model(&Mandarake{}).Create(bundle.Mandarake).Error; err != nil { return err } @@ -118,7 +111,7 @@ func (r *Repo) getSingleMerch(userUuid, merchUuid string) (merchBundle, error) { return merchBundle{}, err } - var surugaya origins.OriginSurugaya + var surugaya Surugaya if err := r.db. Where("merch_uuid = ?", merchUuid). First(&surugaya).Error; err != nil { @@ -127,7 +120,7 @@ func (r *Repo) getSingleMerch(userUuid, merchUuid string) (merchBundle, error) { } } - var mandarake origins.OriginMandarake + var mandarake Mandarake if err := r.db. Where("merch_uuid = ?", merchUuid). First(&mandarake).Error; err != nil { @@ -136,20 +129,10 @@ func (r *Repo) getSingleMerch(userUuid, merchUuid string) (merchBundle, error) { } } - var amiami origins.OriginAmiami - if err := r.db. - Where("merch_uuid = ?", merchUuid). - First(&amiami).Error; err != nil { - if !errors.Is(err, gorm.ErrRecordNotFound) { - return merchBundle{}, err - } - } - return merchBundle{ Merch: &merch, Surugaya: &surugaya, Mandarake: &mandarake, - Amiami: &amiami, }, nil } @@ -180,13 +163,22 @@ func (r *Repo) updateMerch(payload UpdateMerchDTO, userUuid string) error { return err } - if factory, ok := origins.OriginFactories[payload.Origin]; ok { - model := factory(payload.MerchUuid, payload.Link) - if err := r.upsertOrigin(model); err != nil { + switch payload.Origin { + case "surugaya": + if err := r.upsertOrigin(&Surugaya{ + MerchUuid: payload.MerchUuid, + Link: payload.Link, + }); err != nil { + return err + } + + case "mandarake": + if err := r.upsertOrigin(&Mandarake{ + MerchUuid: payload.MerchUuid, + Link: payload.Link, + }); err != nil { return err } - } else if payload.Origin != "" { - return fmt.Errorf("unsupported origin: %s", payload.Origin) } return nil @@ -203,15 +195,18 @@ func (r *Repo) deleteMerch(userUuid, merchUuid string) error { return err } - ors := origins.AllOriginModels() + if err := r.db. + Model(&Surugaya{}). + Where("merch_uuid = ?", merchUuid). + Update("deleted_at", now).Error; err != nil { + return err + } - for _, origin := range ors { - if err := r.db. - Model(origin). - Where("merch_uuid = ?", merchUuid). - Update("deleted_at", now).Error; err != nil { - return err - } + if err := r.db. + Model(&Mandarake{}). + Where("merch_uuid = ?", merchUuid). + Update("deleted_at", now).Error; err != nil { + return err } return nil @@ -342,9 +337,9 @@ func (r *Repo) getZeroPrices(userUuid string) ([]ZeroPrice, error) { if err := r.db.Raw(` WITH price_with_neighbors AS ( SELECT - p.id, p.created_at, p.merch_uuid, p.price, p.origins, m.name, - LAG(price) OVER (PARTITION BY p.merch_uuid, p.origins ORDER BY p.created_at, p.id) AS prev_price, - LEAD(price) OVER (PARTITION BY p.merch_uuid, p.origins ORDER BY p.created_at, p.id) AS next_price + p.id, p.created_at, p.merch_uuid, p.price, p.origin, m.name, + LAG(price) OVER (PARTITION BY p.merch_uuid ORDER BY p.created_at, p.id) AS prev_price, + LEAD(price) OVER (PARTITION BY p.merch_uuid ORDER BY p.created_at, p.id) AS next_price FROM prices AS p JOIN merch as m ON m.merch_uuid = p.merch_uuid WHERE p.deleted_at IS NULL @@ -352,7 +347,7 @@ func (r *Repo) getZeroPrices(userUuid string) ([]ZeroPrice, error) { AND m.user_uuid = ?) SELECT - id, created_at, merch_uuid, origins, name + id, created_at, merch_uuid, origin, name FROM price_with_neighbors WHERE price = 0 @@ -376,19 +371,3 @@ func (r *Repo) deleteZeroPrices(list []DeleteZeroPrices) error { } return nil } - -func (r *Repo) deleteZeroPricesPeriod(userUuid string, start, end time.Time) error { - if err := r.db.Exec(` - UPDATE prices - SET deleted_at = ? - FROM merch - WHERE prices.merch_uuid = merch.merch_uuid - AND merch.user_uuid = ? - AND prices.price = 0 - AND prices.deleted_at IS NULL - AND prices.created_at BETWEEN ? AND ?; - `, time.Now().UTC(), userUuid, start, end).Error; err != nil { - return err - } - return nil -} diff --git a/internal/api/merch/service.go b/internal/api/merch/service.go index e5ef790..d409b71 100644 --- a/internal/api/merch/service.go +++ b/internal/api/merch/service.go @@ -12,7 +12,6 @@ import ( "image" "image/jpeg" "io" - "merch-parser-api/internal/api/merch/origins" "merch-parser-api/internal/interfaces" is "merch-parser-api/proto/imageStorage" "mime/multipart" @@ -59,7 +58,7 @@ func (s *service) addMerch(payload MerchDTO, userUuid string) error { merchUuid := uuid.NewString() bundle := merchBundle{ - Merch: &Merch{ + &Merch{ CreatedAt: time.Time{}, UpdatedAt: sql.NullTime{Valid: false}, DeletedAt: sql.NullTime{Valid: false}, @@ -68,40 +67,36 @@ func (s *service) addMerch(payload MerchDTO, userUuid string) error { Name: payload.Name, }, - Surugaya: origins.NewSurugaya(merchUuid, payload.OriginSurugaya.Link), - Mandarake: origins.NewMandarake(merchUuid, payload.OriginMandarake.Link), - Amiami: origins.NewAmiami(merchUuid, payload.OriginAmiami.Link), + &Surugaya{ + DeletedAt: sql.NullTime{}, + MerchUuid: merchUuid, + Link: payload.OriginSurugaya.Link, + }, + + &Mandarake{ + DeletedAt: sql.NullTime{}, + MerchUuid: merchUuid, + Link: payload.OriginMandarake.Link, + }, } return s.repo.addMerch(bundle) } -func (s *service) getSingleMerch(userUuid, merchUuid string) (SingleMerchResponse, error) { +func (s *service) getSingleMerch(userUuid, merchUuid string) (MerchDTO, error) { bundle, err := s.repo.getSingleMerch(userUuid, merchUuid) if err != nil { - return SingleMerchResponse{}, err + return MerchDTO{}, err } - var originsSlice []OriginDTO - - originsSlice = append(originsSlice, OriginDTO{ - Link: bundle.Surugaya.Link, - Name: origins.Surugaya, - }) - - originsSlice = append(originsSlice, OriginDTO{ - Link: bundle.Mandarake.Link, - Name: origins.Mandarake, - }) - - originsSlice = append(originsSlice, OriginDTO{ - Link: bundle.Amiami.Link, - Name: origins.Amiami, - }) - - return SingleMerchResponse{ + return MerchDTO{ MerchUuid: bundle.Merch.MerchUuid, Name: bundle.Merch.Name, - Origins: originsSlice, + OriginSurugaya: SurugayaDTO{ + Link: bundle.Surugaya.Link, + }, + OriginMandarake: MandarakeDTO{ + Link: bundle.Mandarake.Link, + }, }, nil } @@ -142,7 +137,7 @@ func (s *service) updateMerch(payload UpdateMerchDTO, userUuid string) error { } if payload.Origin == "" { - return errors.New("no origins provided") + return errors.New("no origin provided") } return s.repo.updateMerch(payload, userUuid) @@ -183,10 +178,10 @@ func (s *service) getPrices(userUuid string, days string) ([]PricesResponse, err return nil, err } - pricesMap := make(map[string]map[origins.Origin][]PriceEntry) + pricesMap := make(map[string]map[Origin][]PriceEntry) for _, item := range pricesList { if _, ok := pricesMap[item.MerchUuid]; !ok { - pricesMap[item.MerchUuid] = make(map[origins.Origin][]PriceEntry) + pricesMap[item.MerchUuid] = make(map[Origin][]PriceEntry) } pricesMap[item.MerchUuid][item.Origin] = append(pricesMap[item.MerchUuid][item.Origin], PriceEntry{ @@ -197,22 +192,16 @@ func (s *service) getPrices(userUuid string, days string) ([]PricesResponse, err for i := range response { originSurugaya := OriginWithPrices{ - Origin: origins.Surugaya, - Prices: pricesMap[response[i].MerchUuid][origins.Surugaya], + Origin: surugaya, + Prices: pricesMap[response[i].MerchUuid][surugaya], } response[i].Origins = append(response[i].Origins, originSurugaya) originMandarake := OriginWithPrices{ - Origin: origins.Mandarake, - Prices: pricesMap[response[i].MerchUuid][origins.Mandarake], + Origin: mandarake, + Prices: pricesMap[response[i].MerchUuid][mandarake], } response[i].Origins = append(response[i].Origins, originMandarake) - - originAmiami := OriginWithPrices{ - Origin: origins.Amiami, - Prices: pricesMap[response[i].MerchUuid][origins.Amiami], - } - response[i].Origins = append(response[i].Origins, originAmiami) } return response, nil @@ -229,37 +218,27 @@ func (s *service) getDistinctPrices(userUuid, merchUuid, days string) (PricesRes } originSurugaya := OriginWithPrices{ - Origin: origins.Surugaya, + Origin: surugaya, Prices: []PriceEntry{}, } originMandarake := OriginWithPrices{ - Origin: origins.Mandarake, - Prices: []PriceEntry{}, - } - - originAmiami := OriginWithPrices{ - Origin: origins.Amiami, + Origin: mandarake, Prices: []PriceEntry{}, } for _, item := range result { switch item.Origin { - case origins.Surugaya: + case surugaya: originSurugaya.Prices = append(originSurugaya.Prices, PriceEntry{ CreatedAt: item.CreatedAt.Unix(), Value: item.Price, }) - case origins.Mandarake: + case mandarake: originMandarake.Prices = append(originMandarake.Prices, PriceEntry{ CreatedAt: item.CreatedAt.Unix(), Value: item.Price, }) - case origins.Amiami: - originAmiami.Prices = append(originAmiami.Prices, PriceEntry{ - CreatedAt: item.CreatedAt.Unix(), - Value: item.Price, - }) } } @@ -683,7 +662,3 @@ func (s *service) deleteZeroPrices(userUuid string, list []DeleteZeroPrices) err return s.repo.deleteZeroPrices(toDelete) } - -func (s *service) deleteZeroPricesPeriod(userUuid string, start, end time.Time) error { - return s.repo.deleteZeroPricesPeriod(userUuid, start, end) -} diff --git a/internal/interfaces/utils.go b/internal/interfaces/utils.go index 31cd891..dd6b773 100644 --- a/internal/interfaces/utils.go +++ b/internal/interfaces/utils.go @@ -1,9 +1,6 @@ package interfaces -import ( - "github.com/gin-gonic/gin" - "time" -) +import "github.com/gin-gonic/gin" type Utils interface { IsEmail(email string) bool @@ -11,5 +8,4 @@ type Utils interface { GetRefreshUuidFromContext(c *gin.Context) (string, error) HashPassword(password string) (string, error) ComparePasswords(hashedPassword string, plainPassword string) error - ParseTime(t string) (time.Time, error) } diff --git a/migrations.sql b/migrations.sql index 69e7a93..1ffe7e5 100644 --- a/migrations.sql +++ b/migrations.sql @@ -46,13 +46,6 @@ CREATE TABLE origin_mandarake( link TEXT ); -CREATE TABLE origin_amiami( - id BIGSERIAL PRIMARY KEY, - deleted_at TIMESTAMP WITH TIME ZONE NULL, - merch_uuid VARCHAR(36) NOT NULL UNIQUE, - link TEXT -); - CREATE TABLE prices( id BIGSERIAL PRIMARY KEY, diff --git a/pkg/utils/time.go b/pkg/utils/time.go deleted file mode 100644 index 01bfaf6..0000000 --- a/pkg/utils/time.go +++ /dev/null @@ -1,11 +0,0 @@ -package utils - -import "time" - -func (u *Utils) ParseTime(t string) (time.Time, error) { - timeStr, err := time.Parse(time.RFC3339, t) - if err != nil { - return time.Time{}, err - } - return timeStr, nil -}