feat(api): add GET and POST /supplier/:id/articles endpoints and openapi docs

This commit is contained in:
seb
2026-09-18 02:54:06 +02:00
parent fe8fa55fbb
commit adb529d14f
8 changed files with 776 additions and 1 deletions

View File

@@ -124,6 +124,8 @@ Generated from `@openapi` annotations in [`src/api/routes/`](../../src/api/route
| [`routes/supplier/create.md`](routes/supplier/create.md) | `POST /supplier` |
| [`routes/supplier/delete.md`](routes/supplier/delete.md) | `DELETE /supplier/{id}` |
| [`routes/supplier/update.md`](routes/supplier/update.md) | `PATCH /supplier/{id}` |
| [`routes/supplier/articles.get.md`](routes/supplier/articles.get.md) | `GET /supplier/{id}/articles` |
| [`routes/supplier/articles.post.md`](routes/supplier/articles.post.md) | `POST /supplier/{id}/articles` |
| [`routes/thumb/get.md`](routes/thumb/get.md) | `GET /thumb/{fullHash}` |
| [`routes/unit/delete.md`](routes/unit/delete.md) | `DELETE /unit` |
| [`routes/unit/list.md`](routes/unit/list.md) | `GET /unit` |

View File

@@ -683,6 +683,220 @@
}
}
},
"/supplier/{id}/articles": {
"get": {
"tags": [
"Supplier"
],
"summary": "List supplier articles by SKUs",
"description": "Lists article-supplier assignments for the specified supplier (entity ID),\noptionally filtered by a list of SKUs (matching either article SKU or supplier SKU).\nIncludes linked article details (name, slug, photos/articlepic, eans/articleean).\n",
"security": [
{
"cookieAuth": []
}
],
"x-markdown": "supplier/articles.get.md",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "integer"
},
"description": "Supplier entity ID"
},
{
"in": "query",
"name": "skus",
"required": false,
"schema": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string"
}
]
},
"description": "Optional SKU or comma-separated SKUs to filter by"
}
],
"responses": {
"200": {
"description": "List of supplier articles",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"articles": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SupplierArticle"
}
}
}
}
}
}
},
"400": {
"description": "No company selected or invalid id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not authorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Supplier or company not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"tags": [
"Supplier"
],
"summary": "Query supplier articles by SKUs (bulk)",
"description": "Queries article-supplier assignments for the specified supplier (entity ID) with a\nJSON list of SKUs in the request body, avoiding URL length limits for large SKU lists.\nIncludes linked article details (name, slug, photos/articlepic, eans/articleean).\n",
"security": [
{
"cookieAuth": []
}
],
"x-markdown": "supplier/articles.post.md",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "integer"
},
"description": "Supplier entity ID"
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"skus": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of SKUs to filter by (empty array returns empty list)"
}
},
"example": {
"skus": [
"SKU-1",
"SKU-2"
]
}
}
}
}
},
"responses": {
"200": {
"description": "List of supplier articles",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"articles": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SupplierArticle"
}
}
}
}
}
}
},
"400": {
"description": "No company selected or invalid id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not authorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Supplier or company not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/quote": {
"get": {
"tags": [
@@ -9335,6 +9549,98 @@
}
}
},
"SupplierArticlePhoto": {
"type": "object",
"required": [
"sort",
"thumbhash",
"hash",
"thumbw",
"thumbh"
],
"properties": {
"sort": {
"type": "integer"
},
"thumbhash": {
"type": "string"
},
"hash": {
"type": "string"
},
"thumbw": {
"type": "integer"
},
"thumbh": {
"type": "integer"
}
}
},
"SupplierArticleInfo": {
"type": "object",
"required": [
"id",
"sku"
],
"properties": {
"id": {
"type": "integer"
},
"sku": {
"type": "string"
},
"name": {
"type": "string",
"nullable": true
},
"slug": {
"type": "string",
"nullable": true
},
"photos": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SupplierArticlePhoto"
}
},
"articlepic": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SupplierArticlePhoto"
}
},
"eans": {
"type": "array",
"items": {
"type": "string"
}
},
"articleean": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"SupplierArticle": {
"allOf": [
{
"$ref": "#/components/schemas/ArticleSupplier"
},
{
"type": "object",
"required": [
"article"
],
"properties": {
"article": {
"$ref": "#/components/schemas/SupplierArticleInfo"
}
}
}
]
},
"Brand": {
"type": "object",
"required": [

View File

@@ -0,0 +1,92 @@
# `GET /supplier/{id}/articles`
Protected. Requires a valid session cookie (`credentials: 'include'`).
List supplier articles by SKUs
Lists article-supplier assignments for the specified supplier (entity ID),
optionally filtered by a list of SKUs (matching either article SKU or supplier SKU).
Includes linked article details (name, slug, photos/articlepic, eans/articleean).
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Supplier entity ID |
## Query parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `skus` | no | | Optional SKU or comma-separated SKUs to filter by |
## Response `200`
List of supplier articles
```json
{
"articles": [
{
"id": 1,
"articleId": 1,
"entityId": 1,
"supplierName": "…",
"sku": "…",
"pu": 1,
"stock": 1,
"sort": 1,
"priceId": 1,
"price": {
"net": 1,
"taxId": 1,
"taxRate": 1
},
"article": {
"id": 1,
"sku": "…",
"name": "…",
"slug": "…",
"photos": [
{
"sort": 1,
"thumbhash": "…",
"hash": "…",
"thumbw": 1,
"thumbh": 1
}
],
"articlepic": [
{
"sort": 1,
"thumbhash": "…",
"hash": "…",
"thumbw": 1,
"thumbh": 1
}
],
"eans": [
"…"
],
"articleean": [
"…"
]
}
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | No company selected or invalid id — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Supplier or company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,97 @@
# `POST /supplier/{id}/articles`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Query supplier articles by SKUs (bulk)
Queries article-supplier assignments for the specified supplier (entity ID) with a
JSON list of SKUs in the request body, avoiding URL length limits for large SKU lists.
Includes linked article details (name, slug, photos/articlepic, eans/articleean).
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Supplier entity ID |
## Body (JSON)
```json
{
"skus": [
"SKU-1",
"SKU-2"
]
}
```
## Response `200`
List of supplier articles
```json
{
"articles": [
{
"id": 1,
"articleId": 1,
"entityId": 1,
"supplierName": "…",
"sku": "…",
"pu": 1,
"stock": 1,
"sort": 1,
"priceId": 1,
"price": {
"net": 1,
"taxId": 1,
"taxRate": 1
},
"article": {
"id": 1,
"sku": "…",
"name": "…",
"slug": "…",
"photos": [
{
"sort": 1,
"thumbhash": "…",
"hash": "…",
"thumbw": 1,
"thumbh": 1
}
],
"articlepic": [
{
"sort": 1,
"thumbhash": "…",
"hash": "…",
"thumbw": 1,
"thumbh": 1
}
],
"eans": [
"…"
],
"articleean": [
"…"
]
}
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | No company selected or invalid id — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Supplier or company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._