From 9f27436d5d75058451aedd516fcb877bbdb92fd7 Mon Sep 17 00:00:00 2001 From: Tran Anh Tuan Date: Fri, 8 May 2026 18:17:07 +0700 Subject: [PATCH] feat: add shelve management functionality --- configs/constants/constants.go | 1 + db/queries/shelve.sql | 31 + docs/swagger/docs.go | 363 +++ docs/swagger/swagger.json | 2626 +++++++++++------- docs/swagger/swagger.yaml | 229 ++ internal/mapper/shelve_mapper.go | 46 + internal/models/requests/shelve_request.go | 14 + internal/models/responses/shelve_response.go | 13 + internal/models/shelve_model.go | 13 + internal/repositories/shelve_repository.go | 55 + internal/routers/router.go | 9 + internal/services/shelve_service.go | 192 ++ sqlc_gen/querier.go | 5 + sqlc_gen/shelve.sql.go | 159 ++ 14 files changed, 2682 insertions(+), 1074 deletions(-) create mode 100644 db/queries/shelve.sql create mode 100644 internal/mapper/shelve_mapper.go create mode 100644 internal/models/requests/shelve_request.go create mode 100644 internal/models/responses/shelve_response.go create mode 100644 internal/models/shelve_model.go create mode 100644 internal/repositories/shelve_repository.go create mode 100644 internal/services/shelve_service.go create mode 100644 sqlc_gen/shelve.sql.go diff --git a/configs/constants/constants.go b/configs/constants/constants.go index bd11588..2852adc 100644 --- a/configs/constants/constants.go +++ b/configs/constants/constants.go @@ -14,6 +14,7 @@ const ( API_GROUP_WAREHOUSE = "/warehouses" API_GROUP_ROOM = "/rooms" API_GROUP_CABINET = "/cabinets" + API_GROUP_SHELF = "/shelves" ) const ( diff --git a/db/queries/shelve.sql b/db/queries/shelve.sql new file mode 100644 index 0000000..b37c7f2 --- /dev/null +++ b/db/queries/shelve.sql @@ -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); diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 6df1cea..372d0bd 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -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": { "get": { "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": { "type": "object", "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": { "type": "object", "required": [ @@ -1088,6 +1409,20 @@ const docTemplate = `{ } } }, + "requests.UpdateShelveRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "levelIndex": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, "requests.UpdateWarehouseRequest": { "type": "object", "properties": { @@ -1159,6 +1494,14 @@ const docTemplate = `{ } } }, + "responses.CreateShelveResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, "responses.CreateWarehouseResponse": { "type": "object", "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": { "type": "object", "properties": { diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index 72f84a8..6a36769 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -1,1101 +1,1579 @@ { - "swagger": "2.0", - "info": { - "description": "This is the Warehouse Management API server.", - "title": "Warehouse Management API", - "contact": {}, - "version": "1.0" - }, - "host": "localhost:3000", - "basePath": "/api/v1", - "paths": { - "/auth/register": { - "post": { - "description": "Register with email, username and password", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["auth"], - "summary": "Register a new user", - "parameters": [ - { - "description": "Register request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.BodyRegisterRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.BodyRegisterResponse" - } - } - } - ] - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - }, - "409": { - "description": "Conflict", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - } + "swagger": "2.0", + "info": { + "description": "This is the Warehouse Management API server.", + "title": "Warehouse Management API", + "contact": {}, + "version": "1.0" }, - "/ping": { - "get": { - "description": "Check server is running", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["health"], - "summary": "Health check", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "host": "localhost:3000", + "basePath": "/api/v1", + "paths": { + "/auth/register": { + "post": { + "description": "Register with email, username and password", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "Register a new user", + "parameters": [ + { + "description": "Register request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.BodyRegisterRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.BodyRegisterResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + } + }, + "/ping": { + "get": { + "description": "Check server is running", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "health" + ], + "summary": "Health check", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/v1/cabinets": { + "get": { + "description": "Retrieve a list of all cabinets ordered by creation date", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "cabinet" + ], + "summary": "List all cabinets", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Cabinet" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + }, + "post": { + "description": "Create a new cabinet with the provided details", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "cabinet" + ], + "summary": "Create a new cabinet", + "parameters": [ + { + "description": "Cabinet request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.CreateCabinetRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.CreateCabinetResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + } + }, + "/v1/cabinets/{id}": { + "get": { + "description": "Retrieve a single cabinet using its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "cabinet" + ], + "summary": "Get cabinet by ID", + "parameters": [ + { + "type": "integer", + "description": "Cabinet ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Cabinet" + } + } + } + ] + } + }, + "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 cabinet by its ID. Only non-empty fields will be updated.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "cabinet" + ], + "summary": "Update cabinet", + "parameters": [ + { + "type": "integer", + "description": "Cabinet ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Cabinet request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.UpdateCabinetRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.UpdateCabinetResponse" + } + } + } + ] + } + }, + "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 cabinet by its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "cabinet" + ], + "summary": "Delete cabinet", + "parameters": [ + { + "type": "integer", + "description": "Cabinet 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/rooms": { + "get": { + "description": "Retrieve a list of all rooms ordered by creation date", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "room" + ], + "summary": "List all rooms", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Room" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + }, + "post": { + "description": "Create a new room with the provided details", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "room" + ], + "summary": "Create a new room", + "parameters": [ + { + "description": "Room request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.CreateRoomRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.CreateRoomResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + } + }, + "/v1/rooms/{id}": { + "get": { + "description": "Retrieve a single room using its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "room" + ], + "summary": "Get room by ID", + "parameters": [ + { + "type": "integer", + "description": "Room ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Room" + } + } + } + ] + } + }, + "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 room by its ID. Only non-empty fields will be updated.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "room" + ], + "summary": "Update room", + "parameters": [ + { + "type": "integer", + "description": "Room ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Room request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.UpdateRoomRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.UpdateRoomResponse" + } + } + } + ] + } + }, + "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 room by its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "room" + ], + "summary": "Delete room", + "parameters": [ + { + "type": "integer", + "description": "Room 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/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": { + "get": { + "description": "Retrieve a list of all warehouses ordered by creation date", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "warehouse" + ], + "summary": "List all warehouses", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Warehouse" + } + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + }, + "post": { + "description": "Create a new warehouse with the provided details", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "warehouse" + ], + "summary": "Create a new warehouse", + "parameters": [ + { + "description": "Warehouse request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.CreateWarehouseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.CreateWarehouseResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + } + }, + "/v1/warehouses/{id}": { + "get": { + "description": "Retrieve a single warehouse using its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "warehouse" + ], + "summary": "Get warehouse by ID", + "parameters": [ + { + "type": "integer", + "description": "Warehouse ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.Warehouse" + } + } + } + ] + } + }, + "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 warehouse by its ID with the provided details", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "warehouse" + ], + "summary": "Update warehouse", + "parameters": [ + { + "type": "integer", + "description": "Warehouse ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Warehouse request body", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/requests.UpdateWarehouseRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/responses.UpdateWarehouseResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.ErrorResponse" + } + } + } + }, + "delete": { + "description": "Delete a warehouse by its unique identifier", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "warehouse" + ], + "summary": "Delete warehouse", + "parameters": [ + { + "type": "integer", + "description": "Warehouse 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/cabinets": { - "get": { - "description": "Retrieve a list of all cabinets ordered by creation date", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["cabinet"], - "summary": "List all cabinets", - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "definitions": { + "models.Cabinet": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.Cabinet" - } - } - } - } - ] - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - }, - "post": { - "description": "Create a new cabinet with the provided details", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["cabinet"], - "summary": "Create a new cabinet", - "parameters": [ - { - "description": "Cabinet request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.CreateCabinetRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "description": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.CreateCabinetResponse" - } - } - } - ] - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - } - }, - "/v1/cabinets/{id}": { - "get": { - "description": "Retrieve a single cabinet using its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["cabinet"], - "summary": "Get cabinet by ID", - "parameters": [ - { - "type": "integer", - "description": "Cabinet ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "id": { + "type": "integer" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.Cabinet" - } - } - } - ] - } - }, - "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 cabinet by its ID. Only non-empty fields will be updated.", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["cabinet"], - "summary": "Update cabinet", - "parameters": [ - { - "type": "integer", - "description": "Cabinet ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Cabinet request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.UpdateCabinetRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "name": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.UpdateCabinetResponse" - } - } - } - ] - } - }, - "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 cabinet by its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["cabinet"], - "summary": "Delete cabinet", - "parameters": [ - { - "type": "integer", - "description": "Cabinet 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/rooms": { - "get": { - "description": "Retrieve a list of all rooms ordered by creation date", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["room"], - "summary": "List all rooms", - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "roomId": { + "type": "integer" }, - { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.Room" - } - } - } + "updatedAt": { + "type": "string" } - ] } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - }, - "post": { - "description": "Create a new room with the provided details", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["room"], - "summary": "Create a new room", - "parameters": [ - { - "description": "Room request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.CreateRoomRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + }, + "models.Room": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.CreateRoomResponse" - } - } - } - ] - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - } - }, - "/v1/rooms/{id}": { - "get": { - "description": "Retrieve a single room using its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["room"], - "summary": "Get room by ID", - "parameters": [ - { - "type": "integer", - "description": "Room ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "description": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.Room" - } - } - } - ] - } - }, - "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 room by its ID. Only non-empty fields will be updated.", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["room"], - "summary": "Update room", - "parameters": [ - { - "type": "integer", - "description": "Room ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Room request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.UpdateRoomRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "id": { + "type": "integer" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.UpdateRoomResponse" - } - } - } - ] - } - }, - "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 room by its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["room"], - "summary": "Delete room", - "parameters": [ - { - "type": "integer", - "description": "Room 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": { - "get": { - "description": "Retrieve a list of all warehouses ordered by creation date", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["warehouse"], - "summary": "List all warehouses", - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "name": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/models.Warehouse" - } - } - } - } - ] - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - }, - "post": { - "description": "Create a new warehouse with the provided details", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["warehouse"], - "summary": "Create a new warehouse", - "parameters": [ - { - "description": "Warehouse request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.CreateWarehouseRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "updatedAt": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.CreateWarehouseResponse" - } - } + "warehouseId": { + "type": "integer" } - ] } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" - } - } - } - } - }, - "/v1/warehouses/{id}": { - "get": { - "description": "Retrieve a single warehouse using its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["warehouse"], - "summary": "Get warehouse by ID", - "parameters": [ - { - "type": "integer", - "description": "Warehouse ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + }, + "models.Shelve": { + "type": "object", + "properties": { + "cabinetId": { + "type": "integer" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.Warehouse" - } - } - } - ] - } - }, - "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 warehouse by its ID with the provided details", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["warehouse"], - "summary": "Update warehouse", - "parameters": [ - { - "type": "integer", - "description": "Warehouse ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Warehouse request body", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/requests.UpdateWarehouseRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.SuccessResponse" + "createdAt": { + "type": "string" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/responses.UpdateWarehouseResponse" - } - } + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "levelIndex": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" } - ] } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" + }, + "models.Warehouse": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.ErrorResponse" + }, + "requests.BodyRegisterRequest": { + "type": "object", + "required": [ + "email", + "password", + "username" + ], + "properties": { + "email": { + "type": "string" + }, + "fullName": { + "type": "string" + }, + "password": { + "type": "string", + "minLength": 8 + }, + "username": { + "type": "string" + } + } + }, + "requests.CreateCabinetRequest": { + "type": "object", + "required": [ + "name", + "roomId" + ], + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "roomId": { + "type": "integer" + } + } + }, + "requests.CreateRoomRequest": { + "type": "object", + "required": [ + "name", + "warehouseId" + ], + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "warehouseId": { + "type": "integer" + } + } + }, + "requests.CreateShelveRequest": { + "type": "object", + "required": [ + "cabinetId", + "levelIndex", + "name" + ], + "properties": { + "cabinetId": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "levelIndex": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "requests.CreateWarehouseRequest": { + "type": "object", + "required": [ + "address", + "name" + ], + "properties": { + "address": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "requests.UpdateCabinetRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "requests.UpdateRoomRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "requests.UpdateShelveRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "levelIndex": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "requests.UpdateWarehouseRequest": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "response.ErrorResponse": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "now": { + "type": "integer" + }, + "status": { + "type": "integer" + } + } + }, + "response.SuccessResponse": { + "type": "object", + "properties": { + "data": {}, + "message": { + "type": "string" + }, + "option": {}, + "reason_status_code": { + "type": "string" + }, + "status": { + "type": "integer" + } + } + }, + "responses.BodyRegisterResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "responses.CreateCabinetResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "responses.CreateRoomResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "responses.CreateShelveResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "responses.CreateWarehouseResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, + "responses.UpdateCabinetResponse": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "roomId": { + "type": "integer" + } + } + }, + "responses.UpdateRoomResponse": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "warehouseId": { + "type": "integer" + } + } + }, + "responses.UpdateShelveResponse": { + "type": "object", + "properties": { + "cabinetId": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "levelIndex": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "responses.UpdateWarehouseResponse": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } } - } } - }, - "delete": { - "description": "Delete a warehouse by its unique identifier", - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["warehouse"], - "summary": "Delete warehouse", - "parameters": [ - { - "type": "integer", - "description": "Warehouse 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" - } - } - } - } } - }, - "definitions": { - "models.Cabinet": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "roomId": { - "type": "integer" - }, - "updatedAt": { - "type": "string" - } - } - }, - "models.Room": { - "type": "object", - "properties": { - "createdAt": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updatedAt": { - "type": "string" - }, - "warehouseId": { - "type": "integer" - } - } - }, - "models.Warehouse": { - "type": "object", - "properties": { - "address": { - "type": "string" - }, - "createdAt": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updatedAt": { - "type": "string" - } - } - }, - "requests.BodyRegisterRequest": { - "type": "object", - "required": ["email", "password", "username"], - "properties": { - "email": { - "type": "string" - }, - "fullName": { - "type": "string" - }, - "password": { - "type": "string", - "minLength": 8 - }, - "username": { - "type": "string" - } - } - }, - "requests.CreateCabinetRequest": { - "type": "object", - "required": ["name", "roomId"], - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "roomId": { - "type": "integer" - } - } - }, - "requests.CreateRoomRequest": { - "type": "object", - "required": ["name", "warehouseId"], - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "warehouseId": { - "type": "integer" - } - } - }, - "requests.CreateWarehouseRequest": { - "type": "object", - "required": ["address", "name"], - "properties": { - "address": { - "type": "string" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "requests.UpdateCabinetRequest": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "requests.UpdateRoomRequest": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "requests.UpdateWarehouseRequest": { - "type": "object", - "properties": { - "address": { - "type": "string" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "response.ErrorResponse": { - "type": "object", - "properties": { - "code": { - "type": "integer" - }, - "message": { - "type": "string" - }, - "now": { - "type": "integer" - }, - "status": { - "type": "integer" - } - } - }, - "response.SuccessResponse": { - "type": "object", - "properties": { - "data": {}, - "message": { - "type": "string" - }, - "option": {}, - "reason_status_code": { - "type": "string" - }, - "status": { - "type": "integer" - } - } - }, - "responses.BodyRegisterResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - } - } - }, - "responses.CreateCabinetResponse": { - "type": "object", - "properties": { - "id": { - "type": "integer" - } - } - }, - "responses.CreateRoomResponse": { - "type": "object", - "properties": { - "id": { - "type": "integer" - } - } - }, - "responses.CreateWarehouseResponse": { - "type": "object", - "properties": { - "id": { - "type": "integer" - } - } - }, - "responses.UpdateCabinetResponse": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "roomId": { - "type": "integer" - } - } - }, - "responses.UpdateRoomResponse": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "warehouseId": { - "type": "integer" - } - } - }, - "responses.UpdateWarehouseResponse": { - "type": "object", - "properties": { - "address": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - } - } - } - } -} +} \ No newline at end of file diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 55eb4e5..66f71a2 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -30,6 +30,23 @@ definitions: warehouseId: type: integer 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: properties: address: @@ -85,6 +102,21 @@ definitions: - name - warehouseId 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: properties: address: @@ -111,6 +143,15 @@ definitions: name: type: string type: object + requests.UpdateShelveRequest: + properties: + description: + type: string + levelIndex: + type: integer + name: + type: string + type: object requests.UpdateWarehouseRequest: properties: address: @@ -157,6 +198,11 @@ definitions: id: type: integer type: object + responses.CreateShelveResponse: + properties: + id: + type: integer + type: object responses.CreateWarehouseResponse: properties: id: @@ -184,6 +230,19 @@ definitions: warehouseId: type: integer type: object + responses.UpdateShelveResponse: + properties: + cabinetId: + type: integer + description: + type: string + id: + type: integer + levelIndex: + type: integer + name: + type: string + type: object responses.UpdateWarehouseResponse: properties: address: @@ -598,6 +657,176 @@ paths: summary: Update room tags: - 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: get: consumes: diff --git a/internal/mapper/shelve_mapper.go b/internal/mapper/shelve_mapper.go new file mode 100644 index 0000000..f316989 --- /dev/null +++ b/internal/mapper/shelve_mapper.go @@ -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, + } +} diff --git a/internal/models/requests/shelve_request.go b/internal/models/requests/shelve_request.go new file mode 100644 index 0000000..5a75c43 --- /dev/null +++ b/internal/models/requests/shelve_request.go @@ -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"` +} diff --git a/internal/models/responses/shelve_response.go b/internal/models/responses/shelve_response.go new file mode 100644 index 0000000..ea4a6e1 --- /dev/null +++ b/internal/models/responses/shelve_response.go @@ -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"` +} diff --git a/internal/models/shelve_model.go b/internal/models/shelve_model.go new file mode 100644 index 0000000..7d01788 --- /dev/null +++ b/internal/models/shelve_model.go @@ -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"` +} diff --git a/internal/repositories/shelve_repository.go b/internal/repositories/shelve_repository.go new file mode 100644 index 0000000..1501ef6 --- /dev/null +++ b/internal/repositories/shelve_repository.go @@ -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 +} diff --git a/internal/routers/router.go b/internal/routers/router.go index 615a3ef..ee0e9e2 100644 --- a/internal/routers/router.go +++ b/internal/routers/router.go @@ -55,6 +55,15 @@ func NewRouter() *gin.Engine { cabinet.PUT("/:id", utils.AsyncHandler(services.CabinetUpdate)) 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) diff --git a/internal/services/shelve_service.go b/internal/services/shelve_service.go new file mode 100644 index 0000000..c62e52a --- /dev/null +++ b/internal/services/shelve_service.go @@ -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 +} diff --git a/sqlc_gen/querier.go b/sqlc_gen/querier.go index 1416f20..e77ea1f 100644 --- a/sqlc_gen/querier.go +++ b/sqlc_gen/querier.go @@ -16,15 +16,18 @@ type Querier interface { CreateCabinet(ctx context.Context, arg CreateCabinetParams) (Cabinet, error) CreateRole(ctx context.Context, arg CreateRoleParams) (Role, 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) CreateWarehouse(ctx context.Context, arg CreateWarehouseParams) (Warehouse, error) DeleteCabinet(ctx context.Context, id int64) (int64, error) DeleteRole(ctx context.Context, id uuid.UUID) (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) GetCabinetByID(ctx context.Context, id int64) (Cabinet, error) GetRoleByID(ctx context.Context, id uuid.UUID) (Role, 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) GetUserByID(ctx context.Context, id uuid.UUID) (User, error) GetUserByUsername(ctx context.Context, username string) (User, error) @@ -35,12 +38,14 @@ type Querier interface { ListCabinets(ctx context.Context) ([]Cabinet, error) ListRoles(ctx context.Context) ([]Role, error) ListRooms(ctx context.Context) ([]Room, error) + ListShelves(ctx context.Context) ([]Shelf, error) ListWarehouses(ctx context.Context) ([]Warehouse, error) RemoveAllRolesFromUser(ctx context.Context, userID uuid.UUID) error RemoveRoleFromUser(ctx context.Context, arg RemoveRoleFromUserParams) error UpdateCabinet(ctx context.Context, arg UpdateCabinetParams) (Cabinet, error) UpdateRole(ctx context.Context, arg UpdateRoleParams) (Role, 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) } diff --git a/sqlc_gen/shelve.sql.go b/sqlc_gen/shelve.sql.go new file mode 100644 index 0000000..6f4b2b8 --- /dev/null +++ b/sqlc_gen/shelve.sql.go @@ -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 +}