From bc3eee64342f63bab54f343d86137b0bd4230d11 Mon Sep 17 00:00:00 2001 From: nquidox Date: Wed, 4 Mar 2026 17:59:46 +0300 Subject: [PATCH] get and delete methods --- internal/app/handler.go | 5 +-- internal/merch/controller.go | 74 ++++++++++++++++++++++++++++++++++-- internal/merch/dto.go | 9 +++++ internal/merch/repository.go | 52 +++++++++++++++++++++++++ internal/merch/service.go | 20 ++++++++++ 5 files changed, 154 insertions(+), 6 deletions(-) diff --git a/internal/app/handler.go b/internal/app/handler.go index 3121362..9e98919 100644 --- a/internal/app/handler.go +++ b/internal/app/handler.go @@ -2,7 +2,9 @@ package app import ( "context" + "github.com/gin-gonic/gin" "github.com/jackc/pgx/v5/pgxpool" + log "github.com/sirupsen/logrus" "merch-api/config" "merch-api/internal/merch" "merch-api/internal/user" @@ -10,9 +12,6 @@ import ( "merch-api/pkg/router" "merch-api/pkg/utils" "time" - - "github.com/gin-gonic/gin" - log "github.com/sirupsen/logrus" ) const pkgLogHeader string = "Application |" diff --git a/internal/merch/controller.go b/internal/merch/controller.go index 8e9a4e1..24aed98 100644 --- a/internal/merch/controller.go +++ b/internal/merch/controller.go @@ -2,6 +2,7 @@ package merch import ( "github.com/gin-gonic/gin" + "github.com/google/uuid" "merch-api/pkg/responses" "merch-api/pkg/utils" "net/http" @@ -26,7 +27,7 @@ func (h *Handler) RegisterRoutes(r *gin.RouterGroup) { merchGroup.GET("/:id", h.controller.getOne) merchGroup.GET("/list", h.controller.getMany) merchGroup.PUT("/update", h.controller.update) - merchGroup.DELETE("/delete", h.controller.delete) + merchGroup.DELETE("/:id", h.controller.deleteMerch) originsGroup := merchGroup.Group("/origins") originsGroup.POST("", h.controller.createOrigin) @@ -73,11 +74,78 @@ func (co *controller) create(c *gin.Context) { func (co *controller) getOne(c *gin.Context) {} -func (co *controller) getMany(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) { + userUuid, err := co.utils.GetUserUuidFromContext(c) + if err != nil { + c.JSON(http.StatusUnauthorized, responses.Unauthorized{Error: err.Error()}) + logErrController(err) + return + } + + response, err := co.service.getMany(c, userUuid) + if err != nil { + c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()}) + logErrController(err) + return + } + + if len(response) == 0 { + c.Status(http.StatusNoContent) + return + } + + c.JSON(http.StatusOK, response) +} func (co *controller) update(c *gin.Context) {} -func (co *controller) delete(c *gin.Context) {} +// 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) { + userUuid, err := co.utils.GetUserUuidFromContext(c) + if err != nil { + c.JSON(http.StatusUnauthorized, responses.Unauthorized{Error: err.Error()}) + logErrController(err) + return + } + + merchUuid := c.Param("id") + if err = uuid.Validate(merchUuid); err != nil { + c.JSON(http.StatusBadRequest, responses.BadRequest{Error: err.Error()}) + logErrController(err) + return + } + + if err = co.service.deleteOneMerchRecord(c, userUuid, merchUuid); err != nil { + c.JSON(http.StatusInternalServerError, responses.InternalServerError{Error: err.Error()}) + logErrController(err) + return + } + + c.Status(http.StatusNoContent) +} // createOrigin godoc // diff --git a/internal/merch/dto.go b/internal/merch/dto.go index f7b2304..ccd0b29 100644 --- a/internal/merch/dto.go +++ b/internal/merch/dto.go @@ -1,5 +1,7 @@ package merch +import "time" + // Origins type newOriginDTO struct { Name string `json:"name"` @@ -26,3 +28,10 @@ type originLink struct { Name string `json:"origin_name"` Link string `json:"origin_link"` } + +type merchDTO struct { + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + MerchUuid string `json:"merch_uuid"` + Name string `json:"name"` +} diff --git a/internal/merch/repository.go b/internal/merch/repository.go index fa36c09..5f5e0c4 100644 --- a/internal/merch/repository.go +++ b/internal/merch/repository.go @@ -6,11 +6,19 @@ import ( "fmt" "github.com/jackc/pgx/v5/pgxpool" "strings" + "time" ) type Repository interface { + // createMerch creates new merch record and inserts extra data if given createMerch(ctx context.Context, merch *Merch, extra []ExtraData) error + // getMany returns list of only main merch record, without origins extra data + getMany(ctx context.Context, userId string) ([]merchDTO, error) + + // deleteOneMerchRecord sets deleted_at in merch + extra tables + deleteOneMerchRecord(ctx context.Context, userId, merchUuid string, delTime time.Time) error + Origins } @@ -126,3 +134,47 @@ func (r *repo) createMerch(ctx context.Context, merch *Merch, extra []ExtraData) return tx.Commit(ctx) } + +func (r *repo) getMany(ctx context.Context, userId string) ([]merchDTO, error) { + q := `SELECT created_at, updated_at, merch_uuid, name FROM merch WHERE deleted_at IS NULL AND user_id = $1` + + rows, err := r.db.Query(ctx, q, userId) + if err != nil { + return nil, err + } + defer rows.Close() + + var result []merchDTO + for rows.Next() { + var m merchDTO + if err = rows.Scan(&m.CreatedAt, &m.UpdatedAt, &m.MerchUuid, &m.Name); err != nil { + return nil, err + } + result = append(result, m) + } + if err = rows.Err(); err != nil { + return nil, err + } + return result, nil +} + +func (r *repo) deleteOneMerchRecord(ctx context.Context, userId, merchUuid string, delTime time.Time) error { + tx, err := r.db.Begin(ctx) + if err != nil { + return err + } + + var merch_id int64 + qMerch := `UPDATE merch SET deleted_at = $1 WHERE merch_uuid = $2 AND user_id = $3 RETURNING id` + if err = tx.QueryRow(ctx, qMerch, delTime, merchUuid, userId).Scan(&merch_id); err != nil { + tx.Rollback(ctx) + return err + } + + if merch_id != 0 { + qExtra := `UPDATE merch_extra_data SET deleted_at = $1 WHERE merch_id = $2` + _, err = tx.Exec(ctx, qExtra, delTime, merch_id) + } + + return tx.Commit(ctx) +} diff --git a/internal/merch/service.go b/internal/merch/service.go index 02b92b1..d8e8c3d 100644 --- a/internal/merch/service.go +++ b/internal/merch/service.go @@ -129,3 +129,23 @@ func (s *service) getOriginsMap(ctx context.Context) (map[string]int64, error) { return originsMap, nil } + +func (s *service) getMany(ctx context.Context, userUuid string) ([]merchDTO, error) { + userId, err := s.userProvider.GetUserId(ctx, userUuid) + if err != nil { + logErrService(err) + return nil, err + } + + return s.repo.getMany(ctx, userId) +} + +func (s *service) deleteOneMerchRecord(ctx context.Context, userUuid, merchUuid string) error { + userId, err := s.userProvider.GetUserId(ctx, userUuid) + if err != nil { + logErrService(err) + return err + } + + return s.repo.deleteOneMerchRecord(ctx, userId, merchUuid, s.utils.TimeNowUTC()) +}