diff --git a/internal/merch/controller.go b/internal/merch/controller.go index 00e21e8..0374bc1 100644 --- a/internal/merch/controller.go +++ b/internal/merch/controller.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/gin-gonic/gin" "github.com/google/uuid" + log "github.com/sirupsen/logrus" "merch-api/pkg/responses" "merch-api/pkg/utils" "net/http" @@ -87,7 +88,37 @@ func (co *controller) create(c *gin.Context) { c.Status(http.StatusCreated) } -func (co *controller) getOne(c *gin.Context) {} +// getOne godoc +// +// @Summary Получить всю информацию про мерч +// @Description Получить всю информацию про мерч по его uuid +// @Tags Merch +// @Security BearerAuth +// @Produce json +// @Param uuid path string true "merch_uuid" +// @Success 200 {object} singleMerchResponse +// +// @Failure 400 {object} responses.BadRequest +// @Failure 401 {object} responses.Unauthorized +// @Failure 500 {object} responses.InternalServerError +// +// @Router /merch/{uuid} [get] +func (co *controller) getOne(c *gin.Context) { + merchUuid := c.Param("uuid") + if merchUuid == "" { + c.JSON(http.StatusBadRequest, responses.BadRequest{Error: "MerchUuid is empty"}) + return + } + + response, err := co.service.getSingleMerch(c, getUserId(c), merchUuid) + if err != nil { + c.JSON(http.StatusBadRequest, responses.InternalServerError{Error: err.Error()}) + log.WithError(err).Error("Merch | Failed to get single merch") + return + } + + c.JSON(http.StatusOK, response) +} // getMany godoc // @@ -95,7 +126,7 @@ func (co *controller) getOne(c *gin.Context) {} // @Description Get all merch without origins // @Tags Merch // @Produce json -// @Success 200 {array} ListResponse +// @Success 200 {array} listResponse // @Success 204 // @Failure 400 {object} responses.BadRequest // @Failure 401 {object} responses.Unauthorized diff --git a/internal/merch/dto.go b/internal/merch/dto.go index 103db31..a56f3b4 100644 --- a/internal/merch/dto.go +++ b/internal/merch/dto.go @@ -46,12 +46,18 @@ type extraDataDTO struct { Links []originLink `json:"links"` } -type ListResponse struct { +type listResponse struct { MerchUuid string `json:"merch_uuid"` Name string `json:"name"` Labels []string `json:"labels,omitempty"` } +type singleMerchResponse struct { + MerchUuid string `json:"merch_uuid"` + Name string `json:"name"` + Origins []originLink `json:"origins"` +} + type getMerchInternal struct { Id int64 `json:"id"` MerchUuid string `json:"merch_uuid"` diff --git a/internal/merch/repository_merch.go b/internal/merch/repository_merch.go index b407347..4051f7a 100644 --- a/internal/merch/repository_merch.go +++ b/internal/merch/repository_merch.go @@ -13,6 +13,9 @@ type MerchRepo interface { // createMerch creates new merch record and inserts extra data if given createMerch(ctx context.Context, merch *Merch, extra []ExtraData) error + getSingleMerch(ctx context.Context, userId int64, merchUuid string) (*Merch, error) + getSingleMerchExtraData(ctx context.Context, merchId int64) ([]originLink, error) + // getMany returns list of only main merch record, without origins extra data getMany(ctx context.Context, userId int64) ([]getMerchInternal, error) @@ -75,6 +78,50 @@ func (r *repo) createMerch(ctx context.Context, merch *Merch, extra []ExtraData) return tx.Commit(ctx) } +func (r *repo) getSingleMerch(ctx context.Context, userId int64, merchUuid string) (*Merch, error) { + q := `SELECT id, name FROM merch WHERE merch_uuid = $1 AND user_id = $2 AND deleted_at IS NULL` + + var m Merch + + if err := r.db.QueryRow(ctx, q, merchUuid, userId).Scan(&m.Id, &m.Name); err != nil { + return nil, err + } + return &m, nil +} + +func (r *repo) getSingleMerchExtraData(ctx context.Context, merchId int64) ([]originLink, error) { + q := ` + SELECT mo.name, med.url + FROM merch_extra_data AS med + JOIN merch_origins AS mo ON mo.id = med.origin_id + WHERE med.merch_id = $1 + AND med.deleted_at IS NULL + AND mo.deleted_at IS NULL + ` + + rows, err := r.db.Query(ctx, q, merchId) + if err != nil { + return nil, err + } + + var result []originLink + for rows.Next() { + var o originLink + if err = rows.Scan(&o.Origin, &o.Link); err != nil { + rows.Close() + return nil, err + } + result = append(result, o) + } + + rows.Close() + if err = rows.Err(); err != nil { + return nil, err + } + return result, nil + +} + func (r *repo) getMany(ctx context.Context, userId int64) ([]getMerchInternal, error) { q := `SELECT id, merch_uuid, name FROM merch WHERE deleted_at IS NULL AND user_id = $1` @@ -82,16 +129,18 @@ func (r *repo) getMany(ctx context.Context, userId int64) ([]getMerchInternal, e if err != nil { return nil, err } - defer rows.Close() var result []getMerchInternal for rows.Next() { var m getMerchInternal if err = rows.Scan(&m.Id, &m.MerchUuid, &m.Name); err != nil { + rows.Close() return nil, err } result = append(result, m) } + + rows.Close() if err = rows.Err(); err != nil { return nil, err } diff --git a/internal/merch/service_merch.go b/internal/merch/service_merch.go index 2f05823..72241b6 100644 --- a/internal/merch/service_merch.go +++ b/internal/merch/service_merch.go @@ -49,7 +49,31 @@ func (s *service) createMerch(ctx context.Context, userId int64, payload *newMer return s.repo.createMerch(ctx, newMerch, merchExtra) } -func (s *service) getMany(ctx context.Context, userId int64) ([]ListResponse, error) { +func (s *service) getSingleMerch(ctx context.Context, userId int64, merchUuid string) (*singleMerchResponse, error) { + merch, err := s.repo.getSingleMerch(ctx, userId, merchUuid) + if err != nil { + logErr(serviceLogHeader, err) + return nil, err + } + + if merch == nil { + return nil, nil + } + + links, err := s.repo.getSingleMerchExtraData(ctx, merch.Id) + if err != nil { + logErr(serviceLogHeader, err) + return nil, err + } + + return &singleMerchResponse{ + MerchUuid: merch.MerchUuid, + Name: merch.Name, + Origins: links, + }, nil +} + +func (s *service) getMany(ctx context.Context, userId int64) ([]listResponse, error) { allUserMerch, err := s.repo.getMany(ctx, userId) if err != nil { return nil, err @@ -70,9 +94,9 @@ func (s *service) getMany(ctx context.Context, userId int64) ([]ListResponse, er return nil, err } - var response []ListResponse + var response []listResponse for _, m := range allUserMerch { - response = append(response, ListResponse{ + response = append(response, listResponse{ MerchUuid: m.MerchUuid, Name: m.Name, Labels: cardLabels[m.Id],