get single merch

This commit is contained in:
nquidox 2026-03-16 21:09:01 +03:00
parent ec4fe5151e
commit 7922c00238
4 changed files with 117 additions and 7 deletions

View file

@ -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

View file

@ -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"`

View file

@ -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
}

View file

@ -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],