feat: add shelve management functionality

This commit is contained in:
Tran Anh Tuan
2026-05-08 18:17:07 +07:00
parent 8562d39071
commit 9f27436d5d
14 changed files with 2682 additions and 1074 deletions

View File

@@ -14,6 +14,7 @@ const (
API_GROUP_WAREHOUSE = "/warehouses" API_GROUP_WAREHOUSE = "/warehouses"
API_GROUP_ROOM = "/rooms" API_GROUP_ROOM = "/rooms"
API_GROUP_CABINET = "/cabinets" API_GROUP_CABINET = "/cabinets"
API_GROUP_SHELF = "/shelves"
) )
const ( const (

31
db/queries/shelve.sql Normal file
View File

@@ -0,0 +1,31 @@
-- name: GetShelveByID :one
SELECT * FROM shelves
WHERE id = sqlc.arg(id);
-- name: ListShelves :many
SELECT * FROM shelves
ORDER BY created_at DESC;
-- name: CreateShelve :one
INSERT INTO shelves (cabinet_id,name,level_index, description, created_at)
VALUES (
sqlc.arg(cabinet_id),
sqlc.arg(name),
sqlc.arg(level_index),
sqlc.arg(description),
sqlc.arg(created_at)
)
RETURNING *;
-- name: UpdateShelve :one
UPDATE shelves
SET name = CASE WHEN sqlc.arg(name) = '' THEN name ELSE sqlc.arg(name) END,
level_index = CASE WHEN sqlc.arg(level_index) = 0 THEN level_index ELSE sqlc.arg(level_index) END,
description = coalesce(sqlc.arg(description), description),
updated_at = sqlc.arg(updated_at)
WHERE id = sqlc.arg(id)
RETURNING *;
-- name: DeleteShelve :execrows
DELETE FROM shelves
WHERE id = sqlc.arg(id);

View File

@@ -651,6 +651,279 @@ const docTemplate = `{
} }
} }
}, },
"/v1/shelves": {
"get": {
"description": "Retrieve a list of all shelves ordered by creation date",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"shelve"
],
"summary": "List all shelves",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/models.Shelve"
}
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
}
}
},
"post": {
"description": "Create a new shelve with the provided details",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"shelve"
],
"summary": "Create a new shelve",
"parameters": [
{
"description": "Shelve request body",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.CreateShelveRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/responses.CreateShelveResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
}
}
}
},
"/v1/shelves/{id}": {
"get": {
"description": "Retrieve a single shelve using its unique identifier",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"shelve"
],
"summary": "Get shelve by ID",
"parameters": [
{
"type": "integer",
"description": "Shelve ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/models.Shelve"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
}
}
},
"put": {
"description": "Update an existing shelve by its ID. Only non-empty fields will be updated.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"shelve"
],
"summary": "Update shelve",
"parameters": [
{
"type": "integer",
"description": "Shelve ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Shelve request body",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.UpdateShelveRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.SuccessResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/responses.UpdateShelveResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
}
}
},
"delete": {
"description": "Delete a shelve by its unique identifier",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"shelve"
],
"summary": "Delete shelve",
"parameters": [
{
"type": "integer",
"description": "Shelve ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.SuccessResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.ErrorResponse"
}
}
}
}
},
"/v1/warehouses": { "/v1/warehouses": {
"get": { "get": {
"description": "Retrieve a list of all warehouses ordered by creation date", "description": "Retrieve a list of all warehouses ordered by creation date",
@@ -966,6 +1239,32 @@ const docTemplate = `{
} }
} }
}, },
"models.Shelve": {
"type": "object",
"properties": {
"cabinetId": {
"type": "integer"
},
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"levelIndex": {
"type": "integer"
},
"name": {
"type": "string"
},
"updatedAt": {
"type": "string"
}
}
},
"models.Warehouse": { "models.Warehouse": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -1048,6 +1347,28 @@ const docTemplate = `{
} }
} }
}, },
"requests.CreateShelveRequest": {
"type": "object",
"required": [
"cabinetId",
"levelIndex",
"name"
],
"properties": {
"cabinetId": {
"type": "integer"
},
"description": {
"type": "string"
},
"levelIndex": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"requests.CreateWarehouseRequest": { "requests.CreateWarehouseRequest": {
"type": "object", "type": "object",
"required": [ "required": [
@@ -1088,6 +1409,20 @@ const docTemplate = `{
} }
} }
}, },
"requests.UpdateShelveRequest": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"levelIndex": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"requests.UpdateWarehouseRequest": { "requests.UpdateWarehouseRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -1159,6 +1494,14 @@ const docTemplate = `{
} }
} }
}, },
"responses.CreateShelveResponse": {
"type": "object",
"properties": {
"id": {
"type": "integer"
}
}
},
"responses.CreateWarehouseResponse": { "responses.CreateWarehouseResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -1201,6 +1544,26 @@ const docTemplate = `{
} }
} }
}, },
"responses.UpdateShelveResponse": {
"type": "object",
"properties": {
"cabinetId": {
"type": "integer"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"levelIndex": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"responses.UpdateWarehouseResponse": { "responses.UpdateWarehouseResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,23 @@ definitions:
warehouseId: warehouseId:
type: integer type: integer
type: object type: object
models.Shelve:
properties:
cabinetId:
type: integer
createdAt:
type: string
description:
type: string
id:
type: integer
levelIndex:
type: integer
name:
type: string
updatedAt:
type: string
type: object
models.Warehouse: models.Warehouse:
properties: properties:
address: address:
@@ -85,6 +102,21 @@ definitions:
- name - name
- warehouseId - warehouseId
type: object type: object
requests.CreateShelveRequest:
properties:
cabinetId:
type: integer
description:
type: string
levelIndex:
type: integer
name:
type: string
required:
- cabinetId
- levelIndex
- name
type: object
requests.CreateWarehouseRequest: requests.CreateWarehouseRequest:
properties: properties:
address: address:
@@ -111,6 +143,15 @@ definitions:
name: name:
type: string type: string
type: object type: object
requests.UpdateShelveRequest:
properties:
description:
type: string
levelIndex:
type: integer
name:
type: string
type: object
requests.UpdateWarehouseRequest: requests.UpdateWarehouseRequest:
properties: properties:
address: address:
@@ -157,6 +198,11 @@ definitions:
id: id:
type: integer type: integer
type: object type: object
responses.CreateShelveResponse:
properties:
id:
type: integer
type: object
responses.CreateWarehouseResponse: responses.CreateWarehouseResponse:
properties: properties:
id: id:
@@ -184,6 +230,19 @@ definitions:
warehouseId: warehouseId:
type: integer type: integer
type: object type: object
responses.UpdateShelveResponse:
properties:
cabinetId:
type: integer
description:
type: string
id:
type: integer
levelIndex:
type: integer
name:
type: string
type: object
responses.UpdateWarehouseResponse: responses.UpdateWarehouseResponse:
properties: properties:
address: address:
@@ -598,6 +657,176 @@ paths:
summary: Update room summary: Update room
tags: tags:
- room - room
/v1/shelves:
get:
consumes:
- application/json
description: Retrieve a list of all shelves ordered by creation date
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.SuccessResponse'
- properties:
data:
items:
$ref: '#/definitions/models.Shelve'
type: array
type: object
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.ErrorResponse'
summary: List all shelves
tags:
- shelve
post:
consumes:
- application/json
description: Create a new shelve with the provided details
parameters:
- description: Shelve request body
in: body
name: body
required: true
schema:
$ref: '#/definitions/requests.CreateShelveRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/response.SuccessResponse'
- properties:
data:
$ref: '#/definitions/responses.CreateShelveResponse'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.ErrorResponse'
summary: Create a new shelve
tags:
- shelve
/v1/shelves/{id}:
delete:
consumes:
- application/json
description: Delete a shelve by its unique identifier
parameters:
- description: Shelve ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.SuccessResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.ErrorResponse'
summary: Delete shelve
tags:
- shelve
get:
consumes:
- application/json
description: Retrieve a single shelve using its unique identifier
parameters:
- description: Shelve ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.SuccessResponse'
- properties:
data:
$ref: '#/definitions/models.Shelve'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.ErrorResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.ErrorResponse'
summary: Get shelve by ID
tags:
- shelve
put:
consumes:
- application/json
description: Update an existing shelve by its ID. Only non-empty fields will
be updated.
parameters:
- description: Shelve ID
in: path
name: id
required: true
type: integer
- description: Shelve request body
in: body
name: body
required: true
schema:
$ref: '#/definitions/requests.UpdateShelveRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.SuccessResponse'
- properties:
data:
$ref: '#/definitions/responses.UpdateShelveResponse'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.ErrorResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.ErrorResponse'
summary: Update shelve
tags:
- shelve
/v1/warehouses: /v1/warehouses:
get: get:
consumes: consumes:

View File

@@ -0,0 +1,46 @@
package mapper
import (
"wm-backend/internal/models"
db "wm-backend/sqlc_gen"
"github.com/jackc/pgx/v5/pgtype"
)
func ToDomainShelve(r db.Shelf) *models.Shelve {
return &models.Shelve{
ID: r.ID,
CabinetID: r.CabinetID,
Name: r.Name,
LevelIndex: r.LevelIndex,
Description: r.Description.String,
CreatedAt: r.CreatedAt,
UpdatedAt: r.UpdatedAt,
}
}
func ToModelShelve(r *models.Shelve) *db.CreateShelveParams {
return &db.CreateShelveParams{
CabinetID: r.CabinetID,
Name: r.Name,
LevelIndex: r.LevelIndex,
Description: pgtype.Text{
String: r.Description,
Valid: r.Description != "",
},
CreatedAt: r.CreatedAt,
}
}
func ToUpdateModelShelve(r *models.Shelve) *db.UpdateShelveParams {
return &db.UpdateShelveParams{
Name: r.Name,
LevelIndex: r.LevelIndex,
Description: pgtype.Text{
String: r.Description,
Valid: r.Description != "",
},
UpdatedAt: r.UpdatedAt,
ID: r.ID,
}
}

View File

@@ -0,0 +1,14 @@
package requests
type CreateShelveRequest struct {
CabinetID int64 `json:"cabinetId" binding:"required"`
Name string `json:"name" binding:"required"`
LevelIndex int32 `json:"levelIndex" binding:"required"`
Description string `json:"description"`
}
type UpdateShelveRequest struct {
Name string `json:"name"`
LevelIndex int32 `json:"levelIndex"`
Description string `json:"description"`
}

View File

@@ -0,0 +1,13 @@
package responses
type CreateShelveResponse struct {
ID int64 `json:"id"`
}
type UpdateShelveResponse struct {
ID int64 `json:"id"`
CabinetID int64 `json:"cabinetId"`
Name string `json:"name"`
LevelIndex int32 `json:"levelIndex"`
Description string `json:"description"`
}

View File

@@ -0,0 +1,13 @@
package models
import "time"
type Shelve struct {
ID int64 `json:"id"`
CabinetID int64 `json:"cabinetId"`
Name string `json:"name"`
LevelIndex int32 `json:"levelIndex"`
Description string `json:"description"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

View File

@@ -0,0 +1,55 @@
package repositories
import (
"context"
"wm-backend/internal/mapper"
"wm-backend/internal/models"
db "wm-backend/sqlc_gen"
"github.com/rs/zerolog/log"
)
func CreateShelve(ctx context.Context, queries *db.Queries, body models.Shelve) (models.Shelve, error) {
result, err := queries.CreateShelve(ctx, *mapper.ToModelShelve(&body))
if err != nil {
return models.Shelve{}, err
}
return *mapper.ToDomainShelve(result), nil
}
func GetShelveByID(ctx context.Context, queries *db.Queries, id int64) (models.Shelve, error) {
result, err := queries.GetShelveByID(ctx, id)
if err != nil {
return models.Shelve{}, err
}
return *mapper.ToDomainShelve(result), nil
}
func ListShelves(ctx context.Context, queries *db.Queries) ([]models.Shelve, error) {
results, err := queries.ListShelves(ctx)
if err != nil {
return nil, err
}
var items []models.Shelve
for _, r := range results {
items = append(items, *mapper.ToDomainShelve(r))
}
return items, nil
}
func UpdateShelve(ctx context.Context, queries *db.Queries, body models.Shelve) (models.Shelve, error) {
result, err := queries.UpdateShelve(ctx, *mapper.ToUpdateModelShelve(&body))
if err != nil {
return models.Shelve{}, err
}
return *mapper.ToDomainShelve(result), nil
}
func DeleteShelve(ctx context.Context, queries *db.Queries, id int64) (int64, error) {
rowsAffected, err := queries.DeleteShelve(ctx, id)
log.Info().Int64("id", id).Int64("rowsAffected", rowsAffected).Msg("Deleted shelve")
if err != nil {
return rowsAffected, err
}
return rowsAffected, nil
}

View File

@@ -55,6 +55,15 @@ func NewRouter() *gin.Engine {
cabinet.PUT("/:id", utils.AsyncHandler(services.CabinetUpdate)) cabinet.PUT("/:id", utils.AsyncHandler(services.CabinetUpdate))
cabinet.DELETE("/:id", utils.AsyncHandler(services.CabinetDelete)) cabinet.DELETE("/:id", utils.AsyncHandler(services.CabinetDelete))
} }
shelve := v1.Group(constants.API_GROUP_SHELF)
{
shelve.GET("", utils.AsyncHandler(services.ShelveList))
shelve.GET("/:id", utils.AsyncHandler(services.ShelveGetByID))
shelve.POST("", utils.AsyncHandler(services.ShelveCreate))
shelve.PUT("/:id", utils.AsyncHandler(services.ShelveUpdate))
shelve.DELETE("/:id", utils.AsyncHandler(services.ShelveDelete))
}
} }
r.GET(constants.API_PATH_PING, services.PingHandler) r.GET(constants.API_PATH_PING, services.PingHandler)

View File

@@ -0,0 +1,192 @@
package services
import (
"net/http"
"strconv"
"time"
"wm-backend/global"
"wm-backend/internal/models"
"wm-backend/internal/models/requests"
"wm-backend/internal/models/responses"
"wm-backend/internal/repositories"
"wm-backend/pkg/helper"
"wm-backend/response"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
)
// ShelveCreate creates a new shelve.
// It validates the request body and creates the shelve in the database.
//
// @Summary Create a new shelve
// @Description Create a new shelve with the provided details
// @Tags shelve
// @Accept json
// @Produce json
// @Param body body requests.CreateShelveRequest true "Shelve request body"
// @Success 201 {object} response.SuccessResponse{data=responses.CreateShelveResponse}
// @Failure 400 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/shelves [post]
func ShelveCreate(c *gin.Context) error {
requestBody := requests.CreateShelveRequest{}
if helper.IsShouldBindJSON(c, &requestBody) {
return nil
}
shelveModel := &models.Shelve{
CabinetID: requestBody.CabinetID,
Name: requestBody.Name,
LevelIndex: requestBody.LevelIndex,
Description: requestBody.Description,
CreatedAt: time.Now(),
}
shelve, err := repositories.CreateShelve(c.Request.Context(), global.Queries, *shelveModel)
if err != nil {
log.Error().Err(err).Msg("Failed to create shelve")
response.InternalServerError(c, http.StatusInternalServerError, "Failed to create shelve")
return nil
}
response.Created(c, "Shelve created successfully", &responses.CreateShelveResponse{
ID: shelve.ID,
})
return nil
}
// ShelveGetByID retrieves a single shelve by its ID.
//
// @Summary Get shelve by ID
// @Description Retrieve a single shelve using its unique identifier
// @Tags shelve
// @Accept json
// @Produce json
// @Param id path int true "Shelve ID"
// @Success 200 {object} response.SuccessResponse{data=models.Shelve}
// @Failure 400 {object} response.ErrorResponse
// @Failure 404 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/shelves/{id} [get]
func ShelveGetByID(c *gin.Context) error {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.BadRequestError(c, http.StatusBadRequest, "Invalid ID")
return nil
}
shelve, err := repositories.GetShelveByID(c.Request.Context(), global.Queries, id)
if err != nil {
log.Error().Err(err).Msgf("Failed to get shelve by ID: %d", id)
response.NotFoundError(c, http.StatusNotFound, "Shelve not found")
return nil
}
response.Ok(c, "Success", shelve)
return nil
}
// ShelveList retrieves all shelves.
//
// @Summary List all shelves
// @Description Retrieve a list of all shelves ordered by creation date
// @Tags shelve
// @Accept json
// @Produce json
// @Success 200 {object} response.SuccessResponse{data=[]models.Shelve}
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/shelves [get]
func ShelveList(c *gin.Context) error {
shelves, err := repositories.ListShelves(c.Request.Context(), global.Queries)
if err != nil {
response.InternalServerError(c, http.StatusInternalServerError, "Failed to list shelves")
return nil
}
response.Ok(c, "Success", shelves)
return nil
}
// ShelveUpdate updates an existing shelve by its ID.
// It validates the request body, fetches the existing record,
// merges non-empty fields from the request, and updates the shelve in the database.
//
// @Summary Update shelve
// @Description Update an existing shelve by its ID. Only non-empty fields will be updated.
// @Tags shelve
// @Accept json
// @Produce json
// @Param id path int true "Shelve ID"
// @Param body body requests.UpdateShelveRequest true "Shelve request body"
// @Success 200 {object} response.SuccessResponse{data=responses.UpdateShelveResponse}
// @Failure 400 {object} response.ErrorResponse
// @Failure 404 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/shelves/{id} [put]
func ShelveUpdate(c *gin.Context) error {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.BadRequestError(c, http.StatusBadRequest, "Invalid ID")
return nil
}
requestBody := requests.UpdateShelveRequest{}
if helper.IsShouldBindJSON(c, &requestBody) {
return nil
}
existing, err := repositories.GetShelveByID(c.Request.Context(), global.Queries, id)
if err != nil {
response.NotFoundError(c, http.StatusNotFound, "Shelve not found")
return nil
}
if requestBody.Name != "" {
existing.Name = requestBody.Name
}
if requestBody.LevelIndex != 0 {
existing.LevelIndex = requestBody.LevelIndex
}
if requestBody.Description != "" {
existing.Description = requestBody.Description
}
existing.UpdatedAt = time.Now()
shelve, err := repositories.UpdateShelve(c.Request.Context(), global.Queries, existing)
if err != nil {
log.Error().Err(err).Msgf("Failed to update shelve with ID: %d", id)
response.InternalServerError(c, http.StatusInternalServerError, "Failed to update shelve")
return nil
}
response.Ok(c, "Shelve updated successfully", &responses.UpdateShelveResponse{
ID: shelve.ID,
CabinetID: shelve.CabinetID,
Name: shelve.Name,
LevelIndex: shelve.LevelIndex,
Description: shelve.Description,
})
return nil
}
// ShelveDelete deletes a shelve by its ID.
//
// @Summary Delete shelve
// @Description Delete a shelve by its unique identifier
// @Tags shelve
// @Accept json
// @Produce json
// @Param id path int true "Shelve ID"
// @Success 200 {object} response.SuccessResponse
// @Failure 400 {object} response.ErrorResponse
// @Failure 500 {object} response.ErrorResponse
// @Router /v1/shelves/{id} [delete]
func ShelveDelete(c *gin.Context) error {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.BadRequestError(c, http.StatusBadRequest, "Invalid ID")
return nil
}
rowsAffected, err := repositories.DeleteShelve(c.Request.Context(), global.Queries, id)
if err != nil {
log.Error().Err(err).Msgf("Failed to delete shelve with ID: %d", id)
response.InternalServerError(c, http.StatusInternalServerError, "Failed to delete shelve")
return nil
}
if rowsAffected == 0 {
response.NotFoundError(c, http.StatusNotFound, "Shelve not found")
return nil
}
response.Ok(c, "Delete Success", nil)
return nil
}

View File

@@ -16,15 +16,18 @@ type Querier interface {
CreateCabinet(ctx context.Context, arg CreateCabinetParams) (Cabinet, error) CreateCabinet(ctx context.Context, arg CreateCabinetParams) (Cabinet, error)
CreateRole(ctx context.Context, arg CreateRoleParams) (Role, error) CreateRole(ctx context.Context, arg CreateRoleParams) (Role, error)
CreateRoom(ctx context.Context, arg CreateRoomParams) (Room, error) CreateRoom(ctx context.Context, arg CreateRoomParams) (Room, error)
CreateShelve(ctx context.Context, arg CreateShelveParams) (Shelf, error)
CreateUser(ctx context.Context, arg CreateUserParams) (uuid.UUID, error) CreateUser(ctx context.Context, arg CreateUserParams) (uuid.UUID, error)
CreateWarehouse(ctx context.Context, arg CreateWarehouseParams) (Warehouse, error) CreateWarehouse(ctx context.Context, arg CreateWarehouseParams) (Warehouse, error)
DeleteCabinet(ctx context.Context, id int64) (int64, error) DeleteCabinet(ctx context.Context, id int64) (int64, error)
DeleteRole(ctx context.Context, id uuid.UUID) (int64, error) DeleteRole(ctx context.Context, id uuid.UUID) (int64, error)
DeleteRoom(ctx context.Context, id int64) (int64, error) DeleteRoom(ctx context.Context, id int64) (int64, error)
DeleteShelve(ctx context.Context, id int64) (int64, error)
DeleteWarehouse(ctx context.Context, id int64) (int64, error) DeleteWarehouse(ctx context.Context, id int64) (int64, error)
GetCabinetByID(ctx context.Context, id int64) (Cabinet, error) GetCabinetByID(ctx context.Context, id int64) (Cabinet, error)
GetRoleByID(ctx context.Context, id uuid.UUID) (Role, error) GetRoleByID(ctx context.Context, id uuid.UUID) (Role, error)
GetRoomByID(ctx context.Context, id int64) (Room, error) GetRoomByID(ctx context.Context, id int64) (Room, error)
GetShelveByID(ctx context.Context, id int64) (Shelf, error)
GetUserByEmail(ctx context.Context, email string) (User, error) GetUserByEmail(ctx context.Context, email string) (User, error)
GetUserByID(ctx context.Context, id uuid.UUID) (User, error) GetUserByID(ctx context.Context, id uuid.UUID) (User, error)
GetUserByUsername(ctx context.Context, username string) (User, error) GetUserByUsername(ctx context.Context, username string) (User, error)
@@ -35,12 +38,14 @@ type Querier interface {
ListCabinets(ctx context.Context) ([]Cabinet, error) ListCabinets(ctx context.Context) ([]Cabinet, error)
ListRoles(ctx context.Context) ([]Role, error) ListRoles(ctx context.Context) ([]Role, error)
ListRooms(ctx context.Context) ([]Room, error) ListRooms(ctx context.Context) ([]Room, error)
ListShelves(ctx context.Context) ([]Shelf, error)
ListWarehouses(ctx context.Context) ([]Warehouse, error) ListWarehouses(ctx context.Context) ([]Warehouse, error)
RemoveAllRolesFromUser(ctx context.Context, userID uuid.UUID) error RemoveAllRolesFromUser(ctx context.Context, userID uuid.UUID) error
RemoveRoleFromUser(ctx context.Context, arg RemoveRoleFromUserParams) error RemoveRoleFromUser(ctx context.Context, arg RemoveRoleFromUserParams) error
UpdateCabinet(ctx context.Context, arg UpdateCabinetParams) (Cabinet, error) UpdateCabinet(ctx context.Context, arg UpdateCabinetParams) (Cabinet, error)
UpdateRole(ctx context.Context, arg UpdateRoleParams) (Role, error) UpdateRole(ctx context.Context, arg UpdateRoleParams) (Role, error)
UpdateRoom(ctx context.Context, arg UpdateRoomParams) (Room, error) UpdateRoom(ctx context.Context, arg UpdateRoomParams) (Room, error)
UpdateShelve(ctx context.Context, arg UpdateShelveParams) (Shelf, error)
UpdateWarehouse(ctx context.Context, arg UpdateWarehouseParams) (Warehouse, error) UpdateWarehouse(ctx context.Context, arg UpdateWarehouseParams) (Warehouse, error)
} }

159
sqlc_gen/shelve.sql.go Normal file
View File

@@ -0,0 +1,159 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: shelve.sql
package db
import (
"context"
"time"
"github.com/jackc/pgx/v5/pgtype"
)
const createShelve = `-- name: CreateShelve :one
INSERT INTO shelves (cabinet_id,name,level_index, description, created_at)
VALUES (
$1,
$2,
$3,
$4,
$5
)
RETURNING id, cabinet_id, name, level_index, description, created_at, updated_at
`
type CreateShelveParams struct {
CabinetID int64 `db:"cabinet_id" json:"cabinetId"`
Name string `db:"name" json:"name"`
LevelIndex int32 `db:"level_index" json:"levelIndex"`
Description pgtype.Text `db:"description" json:"description"`
CreatedAt time.Time `db:"created_at" json:"createdAt"`
}
func (q *Queries) CreateShelve(ctx context.Context, arg CreateShelveParams) (Shelf, error) {
row := q.db.QueryRow(ctx, createShelve,
arg.CabinetID,
arg.Name,
arg.LevelIndex,
arg.Description,
arg.CreatedAt,
)
var i Shelf
err := row.Scan(
&i.ID,
&i.CabinetID,
&i.Name,
&i.LevelIndex,
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const deleteShelve = `-- name: DeleteShelve :execrows
DELETE FROM shelves
WHERE id = $1
`
func (q *Queries) DeleteShelve(ctx context.Context, id int64) (int64, error) {
result, err := q.db.Exec(ctx, deleteShelve, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const getShelveByID = `-- name: GetShelveByID :one
SELECT id, cabinet_id, name, level_index, description, created_at, updated_at FROM shelves
WHERE id = $1
`
func (q *Queries) GetShelveByID(ctx context.Context, id int64) (Shelf, error) {
row := q.db.QueryRow(ctx, getShelveByID, id)
var i Shelf
err := row.Scan(
&i.ID,
&i.CabinetID,
&i.Name,
&i.LevelIndex,
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listShelves = `-- name: ListShelves :many
SELECT id, cabinet_id, name, level_index, description, created_at, updated_at FROM shelves
ORDER BY created_at DESC
`
func (q *Queries) ListShelves(ctx context.Context) ([]Shelf, error) {
rows, err := q.db.Query(ctx, listShelves)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Shelf
for rows.Next() {
var i Shelf
if err := rows.Scan(
&i.ID,
&i.CabinetID,
&i.Name,
&i.LevelIndex,
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateShelve = `-- name: UpdateShelve :one
UPDATE shelves
SET name = CASE WHEN $1 = '' THEN name ELSE $1 END,
level_index = CASE WHEN $2 = 0 THEN level_index ELSE $2 END,
description = coalesce($3, description),
updated_at = $4
WHERE id = $5
RETURNING id, cabinet_id, name, level_index, description, created_at, updated_at
`
type UpdateShelveParams struct {
Name interface{} `db:"name" json:"name"`
LevelIndex interface{} `db:"level_index" json:"levelIndex"`
Description pgtype.Text `db:"description" json:"description"`
UpdatedAt time.Time `db:"updated_at" json:"updatedAt"`
ID int64 `db:"id" json:"id"`
}
func (q *Queries) UpdateShelve(ctx context.Context, arg UpdateShelveParams) (Shelf, error) {
row := q.db.QueryRow(ctx, updateShelve,
arg.Name,
arg.LevelIndex,
arg.Description,
arg.UpdatedAt,
arg.ID,
)
var i Shelf
err := row.Scan(
&i.ID,
&i.CabinetID,
&i.Name,
&i.LevelIndex,
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}