diff --git a/app/api/openapi.json b/app/api/openapi.json index caf17fd..398bb8b 100644 --- a/app/api/openapi.json +++ b/app/api/openapi.json @@ -1127,21 +1127,32 @@ } } }, - "/api/v1/restricted/menu/get-menu": { + "/api/v1/restricted/menu/get-category-tree": { "get": { "tags": ["Menu"], - "summary": "Get menu structure", - "description": "Returns the menu structure for the current language. Requires authentication.", - "operationId": "getMenu", + "summary": "Get category tree", + "description": "Returns the category tree rooted at the given category ID for the current language. Requires authentication.", + "operationId": "getCategoryTree", "security": [ { "CookieAuth": [], "BearerAuth": [] } ], + "parameters": [ + { + "name": "root_category_id", + "in": "query", + "description": "Root category ID to build the tree from", + "required": true, + "schema": { + "type": "integer" + } + } + ], "responses": { "200": { - "description": "Menu retrieved successfully", + "description": "Category tree retrieved successfully", "content": { "application/json": { "schema": { @@ -1151,7 +1162,73 @@ } }, "400": { - "description": "Invalid request", + "description": "Invalid request or root category not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/restricted/menu/get-breadcrumb": { + "get": { + "tags": ["Menu"], + "summary": "Get breadcrumb", + "description": "Returns the breadcrumb path from the root category to the specified category for the current language. Requires authentication.", + "operationId": "getBreadcrumb", + "security": [ + { + "CookieAuth": [], + "BearerAuth": [] + } + ], + "parameters": [ + { + "name": "root_category_id", + "in": "query", + "description": "Root category ID (breadcrumb starting point)", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "category_id", + "in": "query", + "description": "Target category ID (breadcrumb destination)", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Breadcrumb retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "400": { + "description": "Invalid request, category not found, or root never reached", "content": { "application/json": { "schema": { @@ -1221,7 +1298,23 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiResponse" + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/B2BTopMenu" + }, + "description": "Root menu items with nested children" + }, + "count": { + "type": "integer", + "description": "Number of root menu items" + } + } } } } @@ -1995,46 +2088,6 @@ } } }, - "MenuItem": { - "type": "object", - "description": "Menu item structure", - "properties": { - "category_id": { - "type": "integer", - "format": "uint", - "description": "Category ID" - }, - "label": { - "type": "string", - "description": "Menu item label" - }, - "params": { - "$ref": "#/components/schemas/MenuItemParams" - }, - "children": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MenuItem" - }, - "description": "Child menu items" - } - } - }, - "MenuItemParams": { - "type": "object", - "properties": { - "category_id": { - "type": "integer", - "format": "uint" - }, - "link_rewrite": { - "type": "string" - }, - "locale": { - "type": "string" - } - } - }, "Route": { "type": "object", "description": "Application route", @@ -2338,6 +2391,58 @@ "description": "Build date in RFC3339 format" } } + }, + "CategoryInBreadcrumb": { + "type": "object", + "description": "A single item in a category breadcrumb path", + "properties": { + "category_id": { + "type": "integer", + "format": "uint", + "description": "Category ID" + }, + "name": { + "type": "string", + "description": "Category name" + } + } + }, + "B2BTopMenu": { + "type": "object", + "description": "Top-level menu item for B2B back-office", + "properties": { + "menu_id": { + "type": "integer", + "description": "Menu item ID" + }, + "label": { + "type": "object", + "description": "Menu label as JSON (multilingual, e.g. {\"en\": \"Dashboard\", \"pl\": \"Panel\"})" + }, + "parent_id": { + "type": "integer", + "description": "Parent menu ID (null for root items)" + }, + "params": { + "type": "object", + "description": "Menu item parameters as JSON" + }, + "active": { + "type": "integer", + "description": "Active status (1 = active, 0 = inactive)" + }, + "position": { + "type": "integer", + "description": "Sort position" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/components/schemas/B2BTopMenu" + }, + "description": "Child menu items" + } + } } }, "securitySchemes": { diff --git a/app/model/productDescription.go b/app/model/productDescription.go index cb84fc8..3e7d5c1 100644 --- a/app/model/productDescription.go +++ b/app/model/productDescription.go @@ -19,6 +19,8 @@ type ProductDescription struct { DeliveryInStock string `gorm:"column:delivery_in_stock;type:varchar(255)" json:"delivery_in_stock" form:"delivery_in_stock"` DeliveryOutStock string `gorm:"column:delivery_out_stock;type:varchar(255)" json:"delivery_out_stock" form:"delivery_out_stock"` Usage string `gorm:"column:usage;type:text" json:"usage" form:"usage"` + + ExistsInDatabse bool `gorm:"-" json:"exists_in_database"` } type ProductRow struct { diff --git a/app/repos/productDescriptionRepo/productDescriptionRepo.go b/app/repos/productDescriptionRepo/productDescriptionRepo.go index 76463cd..d569a75 100644 --- a/app/repos/productDescriptionRepo/productDescriptionRepo.go +++ b/app/repos/productDescriptionRepo/productDescriptionRepo.go @@ -1,6 +1,7 @@ package productDescriptionRepo import ( + "errors" "fmt" "git.ma-al.com/goc_daniel/b2b/app/db" @@ -8,6 +9,7 @@ import ( "git.ma-al.com/goc_daniel/b2b/app/model/dbmodel" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" "github.com/WinterYukky/gorm-extra-clause-plugin/exclause" + "gorm.io/gorm" ) type UIProductDescriptionRepo interface { @@ -35,8 +37,14 @@ func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productid IDLang: int32(productid_lang), }). First(&ProductDescription).Error - if err != nil { + + if errors.Is(err, gorm.ErrRecordNotFound) { + // handle "not found" case only + ProductDescription.ExistsInDatabse = false + } else if err != nil { return nil, fmt.Errorf("database error: %w", err) + } else { + ProductDescription.ExistsInDatabse = true } return &ProductDescription, nil diff --git a/bruno/b2b-daniel/get-product-description.yml b/bruno/b2b-daniel/get-product-description.yml index 23e3c8e..326b790 100644 --- a/bruno/b2b-daniel/get-product-description.yml +++ b/bruno/b2b-daniel/get-product-description.yml @@ -5,13 +5,13 @@ info: http: method: GET - url: http://localhost:3000/api/v1/restricted/product-translation/get-product-description?productID=51&productLangID=2 + url: http://localhost:3000/api/v1/restricted/product-translation/get-product-description?productID=51&productLangID=4 params: - name: productID value: "51" type: query - name: productLangID - value: "2" + value: "4" type: query auth: inherit