u
This commit is contained in:
@@ -126,8 +126,8 @@ _none_
|
|||||||
- Params: `sku: str, body: { eans: str[] }`
|
- Params: `sku: str, body: { eans: str[] }`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Get article history by SKU — `GET /article/{sku}/history`
|
#### Get article history by SKU — `GET /article/{sku}/history`
|
||||||
- Params: `sku: str, query: limit?: int`
|
- Params: `sku: str, query: offset?: int, limit?: int, search?: str, seekMonths?: int`
|
||||||
- Returns: `200 { history: { id: int, date: str, text: str }[], truncated: bool }`
|
- Returns: `200 { history: { id: int, date: str, text: str }[], total: int, unfilteredTotal: int, offset: int, limit: int }`
|
||||||
#### Add article image — `POST /article/{sku}/image`
|
#### Add article image — `POST /article/{sku}/image`
|
||||||
- Params: `sku: str, image/avif`
|
- Params: `sku: str, image/avif`
|
||||||
- Returns: `201 { image: { picId: int, sort: int, full: { w: int, h: int, size: int }, thumb: { w: int, h: int }, hash: str, thumbHash: str } }`
|
- Returns: `201 { image: { picId: int, sort: int, full: { w: int, h: int, size: int }, thumb: { w: int, h: int }, hash: str, thumbHash: str } }`
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
- Params: `sku: str, body: { eans: str[] }`
|
- Params: `sku: str, body: { eans: str[] }`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Get article history by SKU — `GET /article/{sku}/history`
|
#### Get article history by SKU — `GET /article/{sku}/history`
|
||||||
- Params: `sku: str, query: limit?: int`
|
- Params: `sku: str, query: offset?: int, limit?: int, search?: str, seekMonths?: int`
|
||||||
- Returns: `200 { history: { id: int, date: str, text: str }[], truncated: bool }`
|
- Returns: `200 { history: { id: int, date: str, text: str }[], total: int, unfilteredTotal: int, offset: int, limit: int }`
|
||||||
#### Delete article image — `DELETE /article/{sku}/image/{fullHash}`
|
#### Delete article image — `DELETE /article/{sku}/image/{fullHash}`
|
||||||
- Params: `sku: str, fullHash: str`
|
- Params: `sku: str, fullHash: str`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ Protected. Requires a valid session cookie (`credentials: 'include'`).
|
|||||||
Get article history by SKU
|
Get article history by SKU
|
||||||
|
|
||||||
Returns `articlehistory` rows for the article, newest first (`date` DESC, `id` DESC).
|
Returns `articlehistory` rows for the article, newest first (`date` DESC, `id` DESC).
|
||||||
|
Supports pagination, search filter, and date cutoff via `seekMonths`.
|
||||||
Auth like GET by SKU.
|
Auth like GET by SKU.
|
||||||
|
|
||||||
|
|
||||||
@@ -18,11 +19,14 @@ Auth like GET by SKU.
|
|||||||
|
|
||||||
| Param | Required | Type | Description |
|
| Param | Required | Type | Description |
|
||||||
|-------|----------|------|-------------|
|
|-------|----------|------|-------------|
|
||||||
| `limit` | no | integer | Maximum number of entries to return (newest first). Omit for all entries. |
|
| `offset` | no | integer | Paging offset |
|
||||||
|
| `limit` | no | integer | Page size |
|
||||||
|
| `search` | no | string | Optional search filter for history text |
|
||||||
|
| `seekMonths` | no | integer | Negative integer cutoff months ago (e.g. -13) |
|
||||||
|
|
||||||
## Response `200`
|
## Response `200`
|
||||||
|
|
||||||
Article history (newest first)
|
Paged article history list
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -37,7 +41,11 @@ Article history (newest first)
|
|||||||
"date": "2026-08-01T09:00:00.000Z",
|
"date": "2026-08-01T09:00:00.000Z",
|
||||||
"text": "Name geändert von \"\" auf \"Tee\""
|
"text": "Name geändert von \"\" auf \"Tee\""
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"total": 2,
|
||||||
|
"unfilteredTotal": 2,
|
||||||
|
"offset": 0,
|
||||||
|
"limit": 50
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -45,7 +53,7 @@ Article history (newest first)
|
|||||||
|
|
||||||
| Status | Description |
|
| Status | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| 400 | Missing sku — `{"error":"…"}` |
|
| 400 | Missing sku or invalid query parameters — `{"error":"…"}` |
|
||||||
| 401 | Unauthorized — `{"error":"…"}` |
|
| 401 | Unauthorized — `{"error":"…"}` |
|
||||||
| 403 | Not authorized — `{"error":"…"}` |
|
| 403 | Not authorized — `{"error":"…"}` |
|
||||||
| 404 | Article not found — `{"error":"…"}` |
|
| 404 | Article not found — `{"error":"…"}` |
|
||||||
|
|||||||
104
package-lock.json
generated
104
package-lock.json
generated
@@ -32,7 +32,7 @@
|
|||||||
"react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor",
|
"react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor",
|
||||||
"selfsigned": "^5.5.0",
|
"selfsigned": "^5.5.0",
|
||||||
"sharp": "^0.35.5",
|
"sharp": "^0.35.5",
|
||||||
"skelehash-wasm": "^0.1.0",
|
"skelehash-wasm": "file:../skelehash-wasm",
|
||||||
"swagger-ui-dist": "^5.33.3",
|
"swagger-ui-dist": "^5.33.3",
|
||||||
"vm2": "^3.12.2",
|
"vm2": "^3.12.2",
|
||||||
"zod": "^4.6.7"
|
"zod": "^4.6.7"
|
||||||
@@ -72,6 +72,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"../llmorbiter": {
|
"../llmorbiter": {
|
||||||
|
"name": "llmorbiter",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "0BSD",
|
"license": "0BSD",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -81,6 +82,13 @@
|
|||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"../skelehash-wasm": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"sharp": "^0.35.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@alcalzone/ansi-tokenize": {
|
"node_modules/@alcalzone/ansi-tokenize": {
|
||||||
"version": "0.3.1",
|
"version": "0.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.3.1.tgz",
|
||||||
@@ -216,9 +224,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@hpcc-js/wasm-graphviz": {
|
"node_modules/@hpcc-js/wasm-graphviz": {
|
||||||
"version": "1.29.2",
|
"version": "1.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@hpcc-js/wasm-graphviz/-/wasm-graphviz-1.29.2.tgz",
|
"resolved": "https://registry.npmjs.org/@hpcc-js/wasm-graphviz/-/wasm-graphviz-1.30.0.tgz",
|
||||||
"integrity": "sha512-AkArBAZERT5OxH52/+kvCHB07cZ6ZNd9GnOvjw+S880bR88D6i27XfK6xj4dBhUDxNA2QPPMdgEcky3x4TJ3KA==",
|
"integrity": "sha512-T20IKosOZuex2qV049fQokVJy2MWv8w9Md5V/4mRKCXDf49fBCR50VD1yBlPYHaQlHPsFGRdqXN//r59vZliWQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
@@ -787,9 +795,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@modelcontextprotocol/sdk": {
|
"node_modules/@modelcontextprotocol/sdk": {
|
||||||
"version": "1.32.1",
|
"version": "1.32.2",
|
||||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz",
|
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.2.tgz",
|
||||||
"integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==",
|
"integrity": "sha512-SWsVtH/0vULSQStoZ6xxH2K09Li8fXYTMC64ZeogCdpZ3XSi1eCPOByV1OpuJxuI3OcmHhosDWYyii07tpPsLw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hono/node-server": "^1.19.9 || ^2.0.5",
|
"@hono/node-server": "^1.19.9 || ^2.0.5",
|
||||||
@@ -1467,18 +1475,18 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "2.3.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.4.0.tgz",
|
||||||
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
|
"integrity": "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
"content-type": "^2.0.0",
|
"content-type": "^2.1.0",
|
||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"http-errors": "^2.0.1",
|
"http-errors": "^2.0.1",
|
||||||
"iconv-lite": "^0.7.2",
|
"iconv-lite": "^0.7.3",
|
||||||
"on-finished": "^2.4.1",
|
"on-finished": "^2.4.1",
|
||||||
"qs": "^6.15.2",
|
"qs": "^6.16.1",
|
||||||
"raw-body": "^3.0.2",
|
"raw-body": "^3.0.2",
|
||||||
"type-is": "^2.1.0"
|
"type-is": "^2.1.0"
|
||||||
},
|
},
|
||||||
@@ -2267,9 +2275,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "18.0.8",
|
"version": "18.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-18.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-18.0.9.tgz",
|
||||||
"integrity": "sha512-2KDeoFoK/zRtcnbunCDlLG5VWVMcyqeQc6iK65o231nfNAcuGrKoqUQfJFUtBI+QlShk5HKIHxwebBtUl3rEfA==",
|
"integrity": "sha512-3fVOW4cB02R066PUSwn8O4TJyz9NckQl7F81blIbaq9jKBm2tSmOKky7ZHIXzGvkVPXCSn6jkpziBPZdGFs8Tw==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"bin": {
|
"bin": {
|
||||||
"dotenv": "dist/index.cjs"
|
"dotenv": "dist/index.cjs"
|
||||||
@@ -2748,9 +2756,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-uri": {
|
"node_modules/fast-uri": {
|
||||||
"version": "3.1.8",
|
"version": "3.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz",
|
||||||
"integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
|
"integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -2988,9 +2996,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/gaxios": {
|
"node_modules/gaxios": {
|
||||||
"version": "8.3.1",
|
"version": "8.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-8.3.2.tgz",
|
||||||
"integrity": "sha512-h4/R7ay7JFXU5kmAkp/Y4Y4Vmm7m83tD579GUgfQQsRRGQ4TzSedyHla6XgTWohQuVffT3ldN4FF6uCqlRGaEA==",
|
"integrity": "sha512-7VsaTExxjbDv2ZK1YuC4jbgfN33NI/6/7zdYWUHB6mcg51v4tCBZe+xzjqPzOpVzI+C5k1Kk9OQ80WVrXAHOqw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"extend": "^3.0.2",
|
"extend": "^3.0.2",
|
||||||
@@ -3002,9 +3010,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/gcp-metadata": {
|
"node_modules/gcp-metadata": {
|
||||||
"version": "9.2.1",
|
"version": "9.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-9.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-9.2.2.tgz",
|
||||||
"integrity": "sha512-5/LvxarRKbGCA5LJ+ha2aV1iVm7/aALIW4PzeXnQR5dyXiNMWbeA4UOBnqERInLfH/xSFp0ZREcxodUzxhEw2Q==",
|
"integrity": "sha512-hlaHpCBoNCzoUjMnBZq0LbUiYqPAhXFaAgyNwQqwWU44TZIYJK3RD3o2wkNdvPs8nnUXqJjTudnodLJkLMBjow==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"gaxios": "^8.3.0",
|
"gaxios": "^8.3.0",
|
||||||
@@ -3926,9 +3934,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jose": {
|
"node_modules/jose": {
|
||||||
"version": "6.2.12",
|
"version": "6.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz",
|
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.13.tgz",
|
||||||
"integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==",
|
"integrity": "sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/panva"
|
"url": "https://github.com/sponsors/panva"
|
||||||
@@ -4439,9 +4447,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/multer": {
|
"node_modules/multer": {
|
||||||
"version": "2.4.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/multer/-/multer-2.5.0.tgz",
|
||||||
"integrity": "sha512-7dqa0ZcFfzbefdTuIkzOSMvZWC0J7FLqBOjJUZvDCXShIURWKxAyTT1wHhnE5q19c7jOJf43IYYKjBmZVZmvhg==",
|
"integrity": "sha512-BsqOzYGVq49JcW2IzoSAxeKYRevb+dGGPPWleOR8Lrlk4igwxu1/9pwSXlByhCb7MVZDrNJFC0IBP5/O5nLYRw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"append-field": "^1.0.0",
|
"append-field": "^1.0.0",
|
||||||
@@ -4535,9 +4543,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-abi": {
|
"node_modules/node-abi": {
|
||||||
"version": "3.99.0",
|
"version": "3.101.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.99.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.101.0.tgz",
|
||||||
"integrity": "sha512-lLdwkeg2XUVPTHqWjPltTxH81zbQNbUWC+AEb9ni50KjxkUzAAx1HGtMT21sbntzfUGfIphhcklvs3imJeqDXw==",
|
"integrity": "sha512-bkb/RkuWCE64eWu1PCh3Fu2pGc9mKRs+kOE+FU2bGHRYlQa86/D321DSATV54AsCQMKz3/xSt9sRgraZTpqdhQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"semver": "^7.3.5"
|
"semver": "^7.3.5"
|
||||||
@@ -4653,15 +4661,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.2.tgz",
|
||||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
"integrity": "sha512-ATWUv387i+nLD49EiDoOft5scf32Vsdz3ktrQJG9bi7jRFmaXTssvyvj1EmeKVVgvesbqUtvQQvaS2TpTukAZQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ee-first": "1.1.1"
|
"ee-first": "1.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/once": {
|
"node_modules/once": {
|
||||||
@@ -4865,9 +4877,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pkijs": {
|
"node_modules/pkijs": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.3.tgz",
|
||||||
"integrity": "sha512-Oo/NZcSWccq8KyoG7gLE9fnltgHns+pNCjCAp/WmjsUySi+sX7y4z4Xqu4fVb42CDHzRPl33fjzT15V1wvcyhA==",
|
"integrity": "sha512-V9kOzaItwDgqlryhXysQsAXUEKi5O7kqWUaP3dXI7MLvkPqWWMb4wVb1QAtmEDCKI+XIAINsZoNKMFF7sZb1eg==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"website"
|
"website"
|
||||||
@@ -5727,10 +5739,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/skelehash-wasm": {
|
"node_modules/skelehash-wasm": {
|
||||||
"version": "0.1.0",
|
"resolved": "../skelehash-wasm",
|
||||||
"resolved": "https://registry.npmjs.org/skelehash-wasm/-/skelehash-wasm-0.1.0.tgz",
|
"link": true
|
||||||
"integrity": "sha512-QdxF9YsJvKlT93O70dXFaWnsKVX7KDD0RgYf9cwgOT6kGnSMOdsO0rsdge+5Tg+vv6BjivbJ/2o5P1KcQsavEw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/slice-ansi": {
|
"node_modules/slice-ansi": {
|
||||||
"version": "9.0.1",
|
"version": "9.0.1",
|
||||||
@@ -6000,9 +6010,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/swagger-ui-dist": {
|
"node_modules/swagger-ui-dist": {
|
||||||
"version": "5.33.3",
|
"version": "5.34.0",
|
||||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.33.3.tgz",
|
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.34.0.tgz",
|
||||||
"integrity": "sha512-7xJKxAjf+/ajlW/V/dMfbiY+NC5BWtbvzzdI/AsX5UzMtOMudmFz/tjuKN0jN7QVe5drKKnx01CdYEJvTFvQlw==",
|
"integrity": "sha512-H6tAIjr3XqE31PbkZl0OFya1ziRLDfTwh3J6OHdumPtPCLfjTnyLeagl/55kFNZcTOz9a9QI9WP0FXldwiGJag==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scarf/scarf": "=1.4.0"
|
"@scarf/scarf": "=1.4.0"
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
"react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor",
|
"react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor",
|
||||||
"selfsigned": "^5.5.0",
|
"selfsigned": "^5.5.0",
|
||||||
"sharp": "^0.35.5",
|
"sharp": "^0.35.5",
|
||||||
"skelehash-wasm": "^0.1.0",
|
"skelehash-wasm": "file:../skelehash-wasm",
|
||||||
"swagger-ui-dist": "^5.33.3",
|
"swagger-ui-dist": "^5.33.3",
|
||||||
"vm2": "^3.12.2",
|
"vm2": "^3.12.2",
|
||||||
"zod": "^4.6.7"
|
"zod": "^4.6.7"
|
||||||
@@ -60,4 +60,4 @@
|
|||||||
"uuid": "^11.1.1"
|
"uuid": "^11.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -602,6 +602,7 @@ export function register(app, basePath = '') {
|
|||||||
* summary: Get article history by SKU
|
* summary: Get article history by SKU
|
||||||
* description: |
|
* description: |
|
||||||
* Returns `articlehistory` rows for the article, newest first (`date` DESC, `id` DESC).
|
* Returns `articlehistory` rows for the article, newest first (`date` DESC, `id` DESC).
|
||||||
|
* Supports pagination, search filter, and date cutoff via `seekMonths`.
|
||||||
* Auth like GET by SKU.
|
* Auth like GET by SKU.
|
||||||
* security:
|
* security:
|
||||||
* - cookieAuth: []
|
* - cookieAuth: []
|
||||||
@@ -614,29 +615,51 @@ export function register(app, basePath = '') {
|
|||||||
* type: string
|
* type: string
|
||||||
* description: Article SKU
|
* description: Article SKU
|
||||||
* - in: query
|
* - in: query
|
||||||
|
* name: offset
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* minimum: 0
|
||||||
|
* default: 0
|
||||||
|
* description: Paging offset
|
||||||
|
* - in: query
|
||||||
* name: limit
|
* name: limit
|
||||||
* required: false
|
|
||||||
* schema:
|
* schema:
|
||||||
* type: integer
|
* type: integer
|
||||||
* minimum: 1
|
* minimum: 1
|
||||||
* maximum: 1000
|
* maximum: 1000
|
||||||
* description: Maximum number of entries to return (newest first). Omit for all entries.
|
* default: 50
|
||||||
|
* description: Page size
|
||||||
|
* - in: query
|
||||||
|
* name: search
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Optional search filter for history text
|
||||||
|
* - in: query
|
||||||
|
* name: seekMonths
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* description: Negative integer cutoff months ago (e.g. -13)
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: Article history (newest first)
|
* description: Paged article history list
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: object
|
* type: object
|
||||||
* required: [history, truncated]
|
* required: [history, total, unfilteredTotal, offset, limit]
|
||||||
* properties:
|
* properties:
|
||||||
* history:
|
* history:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: '#/components/schemas/ArticleHistoryEntry'
|
* $ref: '#/components/schemas/ArticleHistoryEntry'
|
||||||
* truncated:
|
* total:
|
||||||
* type: boolean
|
* type: integer
|
||||||
* description: True when a limit was applied and the result set was exactly that size (more entries may exist).
|
* unfilteredTotal:
|
||||||
|
* type: integer
|
||||||
|
* offset:
|
||||||
|
* type: integer
|
||||||
|
* limit:
|
||||||
|
* type: integer
|
||||||
* example:
|
* example:
|
||||||
* history:
|
* history:
|
||||||
* - id: 42
|
* - id: 42
|
||||||
@@ -645,8 +668,12 @@ export function register(app, basePath = '') {
|
|||||||
* - id: 41
|
* - id: 41
|
||||||
* date: '2026-08-01T09:00:00.000Z'
|
* date: '2026-08-01T09:00:00.000Z'
|
||||||
* text: 'Name geändert von "" auf "Tee"'
|
* text: 'Name geändert von "" auf "Tee"'
|
||||||
|
* total: 2
|
||||||
|
* unfilteredTotal: 2
|
||||||
|
* offset: 0
|
||||||
|
* limit: 50
|
||||||
* 400:
|
* 400:
|
||||||
* description: Missing sku
|
* description: Missing sku or invalid query parameters
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
@@ -678,8 +705,19 @@ export function register(app, basePath = '') {
|
|||||||
return res.status(400).json({ error: 'sku is required' });
|
return res.status(400).json({ error: 'sku is required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rawOffset = req.query.offset;
|
||||||
const rawLimit = req.query.limit;
|
const rawLimit = req.query.limit;
|
||||||
let limit = null;
|
|
||||||
|
let offset = 0;
|
||||||
|
let limit = 50;
|
||||||
|
|
||||||
|
if (rawOffset !== undefined) {
|
||||||
|
offset = parseInt(rawOffset, 10);
|
||||||
|
if (!Number.isInteger(offset) || offset < 0) {
|
||||||
|
return res.status(400).json({ error: 'offset must be an integer >= 0' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rawLimit !== undefined) {
|
if (rawLimit !== undefined) {
|
||||||
limit = parseInt(rawLimit, 10);
|
limit = parseInt(rawLimit, 10);
|
||||||
if (!Number.isInteger(limit) || limit < 1 || limit > 1000) {
|
if (!Number.isInteger(limit) || limit < 1 || limit > 1000) {
|
||||||
@@ -687,10 +725,26 @@ export function register(app, basePath = '') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const search = typeof req.query.search === 'string' && req.query.search.trim() !== ''
|
||||||
|
? req.query.search.trim()
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
let seekMonths = undefined;
|
||||||
|
if (req.query.seekMonths !== undefined) {
|
||||||
|
seekMonths = parseInt(req.query.seekMonths, 10);
|
||||||
|
if (!Number.isInteger(seekMonths)) {
|
||||||
|
return res.status(400).json({ error: 'seekMonths must be an integer' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const history = await db.getHistoryBySku(req.user.id, decodeURIComponent(sku), limit != null ? { limit } : undefined);
|
const result = await db.getHistoryBySku(req.user.id, decodeURIComponent(sku), {
|
||||||
const truncated = limit != null && history.length === limit;
|
offset,
|
||||||
res.status(200).json({ history, truncated });
|
limit,
|
||||||
|
search,
|
||||||
|
seekMonths,
|
||||||
|
});
|
||||||
|
res.status(200).json(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const status = articleErrorStatus(error);
|
const status = articleErrorStatus(error);
|
||||||
if (status === 500) console.error('Get article history by sku failed:', error);
|
if (status === 500) console.error('Get article history by sku failed:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user