# API Documentation # Simple endpoint reference for the Marketplace Backoffice. ## Projects ### Get All Projects ``` GET /api/projects Response: [ { "id": "dexar", "name": "dexar", "displayName": "Dexar Marketplace", "active": true, "logoUrl": "https://..." } ] ``` ## Categories ### Get Categories for Project ``` GET /api/projects/:projectId/categories Response: [ { "id": "cat1", "name": "Electronics", "visible": true, "priority": 1, "img": "https://...", "projectId": "dexar", "subcategories": [...] } ] ``` ### Get Single Category ``` GET /api/categories/:categoryId Response: { "id": "cat1", "name": "Electronics", "visible": true, "priority": 1, "img": "https://...", "projectId": "dexar", "subcategories": [...] } ``` ### Create Category ``` POST /api/projects/:projectId/categories Body: { "name": "New Category", "visible": true, "priority": 10, "img": "https://..." } Response: (created category object) ``` ### Update Category ``` PATCH /api/categories/:categoryId Body: (any field to update) { "name": "Updated Name", "visible": false, "priority": 5 } Response: (updated category object) ``` ### Delete Category ``` DELETE /api/categories/:categoryId Response: 204 No Content ``` ## Subcategories ### Get Subcategories ``` GET /api/categories/:categoryId/subcategories Response: [ { "id": "sub1", "name": "Smartphones", "visible": true, "priority": 1, "img": "https://...", "categoryId": "cat1", "itemCount": 15, "hasItems": true, "subcategories": [] } ] Note: - Subcategories can have nested subcategories (recursive) - If hasItems is true, cannot create child subcategories ``` ### Get Single Subcategory ``` GET /api/subcategories/:subcategoryId Response: (subcategory object with nested subcategories if any) ``` ### Create Subcategory ``` POST /api/categories/:categoryId/subcategories Note: categoryId can be either a category ID or a parent subcategory ID for nested structure Body: { "id": "custom-id", // Optional, auto-generated if not provided "name": "New Subcategory", "visible": true, "priority": 10 } Response: (created subcategory object) Error: Returns 400 if parent subcategory already has items ``` ### Update Subcategory ``` PATCH /api/subcategories/:subcategoryId Body: (any field) { "id": "new-id", // ID is now editable (used for routing) "name": "Updated Name", "visible": false } Response: (updated subcategory object) ``` ### Delete Subcategory ``` DELETE /api/subcategories/:subcategoryId Response: 204 No Content ``` ## Items ### Get Items (Paginated) ``` GET /api/subcategories/:subcategoryId/items?page=1&limit=20&search=phone&visible=true Query Params: - page: number (default: 1) - limit: number (default: 20) - search: string (optional - filters by name) - visible: boolean (optional - filters by visibility) - tags: string (optional - comma separated tags) Response: { "items": [ { "id": "item1", "name": "iPhone 15 Pro", "visible": true, "priority": 1, "quantity": 50, "price": 1299, "currency": "USD", "imgs": ["https://...", "https://..."], "tags": ["new", "featured"], "simpleDescription": "Latest iPhone...", "description": [ { "key": "Color", "value": "Black" }, { "key": "Storage", "value": "256GB" } ], "subcategoryId": "sub1", "comments": [ { "id": "c1", "text": "Great product!", "author": "John Doe", "stars": 5, "createdAt": "2024-01-10T10:30:00Z" } ] } ], "total": 150, "page": 1, "limit": 20, "hasMore": true } ``` ### Get Single Item ``` GET /api/items/:itemId Response: (item object with all fields) ``` ### Create Item ``` POST /api/subcategories/:subcategoryId/items Body: { "name": "New Product", "visible": true, "priority": 10, "quantity": 100, "price": 999, "currency": "USD", "imgs": ["https://..."], "tags": ["new"], "simpleDescription": "Product description", "description": [ { "key": "Size", "value": "Large" } ] } Response: (created item object) ``` ### Update Item ``` PATCH /api/items/:itemId Body: (any field to update) { "name": "Updated Name", "price": 899, "quantity": 80, "visible": false } Response: (updated item object) ``` **Example: Update only images** ``` PATCH /api/items/item123 Body: { "imgs": ["https://new-image1.jpg", "https://new-image2.jpg"] } Note: Send the complete array of images (not just changed ones) Response: (updated item object) ``` ### Delete Item ``` DELETE /api/items/:itemId Response: 204 No Content ``` ### Bulk Update Items ``` PATCH /api/items/bulk Body: { "itemIds": ["item1", "item2", "item3"], "data": { "visible": true } } Response: 204 No Content ``` ## Upload ### Upload Image ``` POST /api/upload Body: multipart/form-data - image: File Response: { "url": "https://cdn.example.com/image.jpg" } ``` ## Notes - All endpoints return JSON - Use PATCH for partial updates - Priority: lower numbers = appears first - Currency codes: USD, EUR, RUB, GBP, UAH - Images: array of URLs - Description: array of key-value pairs - Auto-save triggers PATCH with single field every 500ms ### Business Rules 1. **Nested Subcategories** - Subcategories can have unlimited nesting levels - A subcategory with items (`hasItems: true`) cannot have child subcategories - Creating a subcategory under a parent with items will fail 2. **Item Management** - When first item is created in a subcategory, `hasItems` is set to true - When last item is deleted, `hasItems` is set to false - Items belong to the deepest subcategory in the hierarchy 3. **Comments** - Stars field is optional (1-5 rating) - createdAt is ISO 8601 timestamp - author is optional (can be anonymous) 4. **URL Structure for Marketplace** - Items: `/{categoryId}/{subcategoryId}/.../{itemId}` - Example: `/electronics/smartphones/iphone-15` - Example nested: `/electronics/smartphones/apple/iphone-15`