This commit is contained in:
seb
2026-10-03 23:13:36 +02:00
parent 1786879c4e
commit 9a7f345d8b
39 changed files with 4611 additions and 50 deletions

View File

@@ -144,6 +144,13 @@ Generated from `@openapi` annotations in [`src/api/routes/`](../../src/api/route
| [`routes/ledger.post.md`](routes/ledger.post.md) | `POST /ledger` |
| [`routes/ledger/manifestarticle/_manifestarticleId.md`](routes/ledger/manifestarticle/_manifestarticleId.md) | `GET /ledger/manifestarticle/{manifestarticleId}` |
| [`routes/ledger/sku/_sku.md`](routes/ledger/sku/_sku.md) | `GET /ledger/sku/{sku}` |
| [`routes/modelconversation.get.md`](routes/modelconversation.get.md) | `GET /modelconversation` |
| [`routes/modelconversation.post.md`](routes/modelconversation.post.md) | `POST /modelconversation` |
| [`routes/modelconversation/_id.delete.md`](routes/modelconversation/_id.delete.md) | `DELETE /modelconversation/{id}` |
| [`routes/modelconversation/_id.get.md`](routes/modelconversation/_id.get.md) | `GET /modelconversation/{id}` |
| [`routes/modelconversation/_id/message.get.md`](routes/modelconversation/_id/message.get.md) | `GET /modelconversation/{id}/message` |
| [`routes/modelconversation/_id/message.post.md`](routes/modelconversation/_id/message.post.md) | `POST /modelconversation/{id}/message` |
| [`routes/modelconversation/_id/stream.md`](routes/modelconversation/_id/stream.md) | `GET /modelconversation/{id}/stream` |
| [`routes/number/list.md`](routes/number/list.md) | `GET /number` |
| [`routes/number/update.md`](routes/number/update.md) | `PATCH /number/{id}` |
| [`routes/order/list.md`](routes/order/list.md) | `GET /order` |
@@ -170,6 +177,9 @@ Generated from `@openapi` annotations in [`src/api/routes/`](../../src/api/route
| [`routes/propertyname/order.md`](routes/propertyname/order.md) | `PUT /propertyname/order` |
| [`routes/propertyname/_id.delete.md`](routes/propertyname/_id.delete.md) | `DELETE /propertyname/{id}` |
| [`routes/propertyname/_id.patch.md`](routes/propertyname/_id.patch.md) | `PATCH /propertyname/{id}` |
| [`routes/public/_companyId/articles.md`](routes/public/_companyId/articles.md) | `GET /public/{companyId}/articles` |
| [`routes/public/_companyId/articles/_sku.md`](routes/public/_companyId/articles/_sku.md) | `GET /public/{companyId}/articles/{sku}` |
| [`routes/public/_companyId/categories.md`](routes/public/_companyId/categories.md) | `GET /public/{companyId}/categories` |
| [`routes/quote/list.md`](routes/quote/list.md) | `GET /quote` |
| [`routes/quote/create.md`](routes/quote/create.md) | `POST /quote` |
| [`routes/quote/delete.md`](routes/quote/delete.md) | `DELETE /quote/{id}` |

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Dash API Routes Overview (All)
Overview of all 167 API endpoints across all modules.
Overview of all 177 API endpoints across all modules.
### Parameter Notation
@@ -124,6 +124,13 @@ Overview of all 167 API endpoints across all modules.
| `POST` | `/ledger` | `body: { manifestarticle_id, transaction_type, amount, transaction_text }` | `201 { ledger: { id, manifestarticle_id, transaction_type, amount, transaction_text, hash_version, prev_hash, sku, created_at } }` | Add ledger entry |
| `GET` | `/ledger/manifestarticle/{manifestarticleId}` | `manifestarticleId:integer, query: transaction_type?:string` | `200 { ledger: { id, manifestarticle_id, transaction_type, amount, transaction_text, hash_version, prev_hash, sku, created_at }[] }` | Query ledger by manifest article ID |
| `GET` | `/ledger/sku/{sku}` | `sku:string, query: transaction_type?:string` | `200 { ledger: { id, manifestarticle_id, transaction_type, amount, transaction_text, hash_version, prev_hash, sku, created_at }[] }` | Query ledger by article SKU |
| `GET` | `/modelconversation` | — | `200 { conversations: { id, companyuser_id, provider, model, created_at, updated_at, state }[] }` | List conversations |
| `POST` | `/modelconversation` | `body: { provider, model }` | `201 { conversation: { id, companyuser_id, provider, model, created_at, updated_at, state } }` | Create conversation |
| `DELETE` | `/modelconversation/{id}` | `id:integer` | `204 void` | Delete conversation |
| `GET` | `/modelconversation/{id}` | `id:integer` | `200 { conversation: { id, companyuser_id, provider, model, created_at, updated_at, state } }` | Get conversation |
| `GET` | `/modelconversation/{id}/message` | `id:integer` | `200 { messages: { id, conversation_id, created_at, role, message }[] }` | List conversation messages |
| `POST` | `/modelconversation/{id}/message` | `id:integer, body: { message?, role?, tool_call_id?, content?, answer? }` | `201 { message: { id, conversation_id, created_at, role, message } }` | Post a user message |
| `GET` | `/modelconversation/{id}/stream` | `id:integer` | `200 SSE` | Stream conversation events (SSE) |
| `GET` | `/number` | — | `200 { numbers: { id, type, prefix, padding, next }[] }` | List number sequences |
| `PATCH` | `/number/{id}` | `id:integer, body: { prefix?, padding?, next? }` | `200 { number: { id, type, prefix, padding, next } }` | Update number sequence |
| `GET` | `/order` | — | `200 { orders: { id, number, type, entityId, date, createdAt }[] }` | List orders |
@@ -150,6 +157,9 @@ Overview of all 167 API endpoints across all modules.
| `PUT` | `/propertyname/order` | `body: { propertynameIds: integer[] }` | `200` | Reorder property names |
| `DELETE` | `/propertyname/{id}` | `id:integer` | `200` | Delete property name |
| `PATCH` | `/propertyname/{id}` | `id:integer, body: { name?, sort?, exclusive? }` | `200 { propertyname: { id, name, sort, exclusive } }` | Update property name |
| `GET` | `/public/{companyId}/articles` | `companyId:integer, query: categoryId?:integer, search?:string, limit?:integer, offset?:integer` | `200 { articles: { id, sku, name, slug, net, taxRate, gross, trackStock, brand, fullHash, thumbW, thumbH, thumbHash }[] }` | List public articles |
| `GET` | `/public/{companyId}/articles/{sku}` | `companyId:integer, sku:string` | `200 { article: { id, sku, name, slug, description, unitamount, weight, trackStock, unit, brand, price, prices: object[], categories: object[], photos: object[], eans: string[], isFather, fatherSku, variants: object[] } }` | Get public article detail |
| `GET` | `/public/{companyId}/categories` | `companyId:integer` | `200 { categories: { id, parentId, sort, name, slug, fullHash, thumbW, thumbH, thumbHash }[] }` | List public categories |
| `GET` | `/quote` | — | `200 { quotes: { id, number, type, entityId, date, createdAt }[] }` | List quotes |
| `POST` | `/quote` | `body: { number, date, lines: { amount, net, taxrate, sku?: string, name?, pu?, rebate?, comment? }[], entityId? }` | `201 { quote: { id, number, type, entityId, date, createdAt, lines: { id, sku, name, pu, amount, net, rebate, taxrate, comment }[] } }` | Create quote |
| `DELETE` | `/quote/{id}` | `id:integer` | `204 void` | Delete quote |

View File

@@ -4,7 +4,7 @@ Protected. Requires a valid session cookie (`credentials: 'include'`).
List label templates
Lists all ZPL label templates for the selected company. The `thumb` field is returned as a base64-encoded PNG string when present. `content.objects` is omitted to reduce payload size.
Lists all ZPL label templates for the selected company. The `thumb` field is returned as a base64-encoded PNG string when present. The `content` field is omitted to reduce payload size (use GET /labeltemplate/{id} for it).
## Response `200`

View File

@@ -0,0 +1,39 @@
# `GET /modelconversation`
Protected. Requires a valid session cookie (`credentials: 'include'`).
List conversations
Lists the authenticated user's model conversations in the selected company, most recently updated first.
## Response `200`
List of conversations
```json
{
"conversations": [
{
"id": 1,
"companyuser_id": 1,
"provider": "…",
"model": "…",
"created_at": "…",
"updated_at": "…",
"state": "idle"
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | No company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,51 @@
# `POST /modelconversation`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Create conversation
Creates a new conversation in state `idle`.
## Body (JSON)
| Field | Required | Type | Description |
|-------|----------|------|-------------|
| `provider` | yes | string | |
| `model` | yes | string | |
```json
{
"provider": "…",
"model": "…"
}
```
## Response `201`
Created conversation
```json
{
"conversation": {
"id": 1,
"companyuser_id": 1,
"provider": "…",
"model": "…",
"created_at": "…",
"updated_at": "…",
"state": "idle"
}
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid input or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,32 @@
# `DELETE /modelconversation/{id}`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Delete conversation
Deletes one of the authenticated user's model conversations and all its messages.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Conversation ID |
## Response `204`
Conversation deleted
_No content_
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid ID or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Conversation not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,44 @@
# `GET /modelconversation/{id}`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Get conversation
Gets details and current state of one of the authenticated user's model conversations.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Conversation ID |
## Response `200`
Conversation details
```json
{
"conversation": {
"id": 1,
"companyuser_id": 1,
"provider": "…",
"model": "…",
"created_at": "…",
"updated_at": "…",
"state": "idle"
}
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid ID or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Conversation not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,44 @@
# `GET /modelconversation/{id}/message`
Protected. Requires a valid session cookie (`credentials: 'include'`).
List conversation messages
Lists messages of one of the user's own conversations, oldest first.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Conversation ID |
## Response `200`
List of messages
```json
{
"messages": [
{
"id": 1,
"conversation_id": 1,
"created_at": "…",
"role": "system",
"message": "…"
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid ID or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Conversation not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,65 @@
# `POST /modelconversation/{id}/message`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Post a user message
Appends a message with role `user` to the conversation.
Refused with 409 unless the conversation state is `idle`.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Conversation ID |
## Body (JSON)
| Field | Required | Type | Description |
|-------|----------|------|-------------|
| `message` | no | string | User message text or fallback content |
| `role` | no | string | Message role ('user' or 'tool') |
| `tool_call_id` | no | string | Target tool call ID when responding to a tool like ask_user |
| `content` | no | | Tool response content payload |
| `answer` | no | | Shorthand answer for ask_user response |
```json
{
"message": "…",
"role": "user",
"tool_call_id": "…",
"content": "…",
"answer": "…"
}
```
## Response `201`
Created message
```json
{
"message": {
"id": 1,
"conversation_id": 1,
"created_at": "…",
"role": "system",
"message": "…"
}
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid ID, empty message or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Conversation not found — `{"error":"…"}` |
| 409 | Conversation is not idle — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,37 @@
# `GET /modelconversation/{id}/stream`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Stream conversation events (SSE)
Opens a Server-Sent Events stream for the specified conversation.
Streams `message` events (persisted user/assistant messages), live `delta`
text chunks of the model answer, and `state` events (`thinking`, `working`,
`done`). The SSE states are not stored; the database only knows `idle`/`busy`.
`done` carries `usage` (`input`, `cached`, `output`, `cost`) on success or
`error` (string) if the run failed.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Conversation ID |
## Response `200`
SSE stream (`text/event-stream`). Emits `state`, `delta`, and `message` events.
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid ID or no company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Conversation not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,62 @@
# `GET /public/{companyId}/articles`
Public. No cookie required.
List public articles
Returns a paginated list of catalog articles for the specified company, optionally filtered by category.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `companyId` | yes | integer | Company ID |
## Query parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `categoryId` | no | integer | Optional category ID to filter by |
| `search` | no | string | Search query for name or SKU |
| `limit` | no | integer | Number of articles to return (max 200) |
| `offset` | no | integer | Number of articles to skip |
## Response `200`
Articles list
```json
{
"articles": [
{
"id": 1,
"sku": "…",
"name": "…",
"slug": "…",
"net": 1,
"taxRate": 1,
"gross": 1,
"trackStock": true,
"brand": {
"id": 1,
"name": "…"
},
"fullHash": "…",
"thumbW": 1,
"thumbH": 1,
"thumbHash": "…"
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid parameters — `{"error":"…"}` |
| 404 | Company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,64 @@
# `GET /public/{companyId}/articles/{sku}`
Public. No cookie required.
Get public article detail
Returns detailed public catalog data for a single article identified by SKU.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `companyId` | yes | integer | Company ID |
| `sku` | yes | string | Article SKU |
## Response `200`
Article detail
```json
{
"article": {
"id": 1,
"sku": "…",
"name": "…",
"slug": "…",
"description": "…",
"unitamount": 1,
"weight": 1,
"trackStock": true,
"unit": {},
"brand": {},
"price": {},
"prices": [
{}
],
"categories": [
{}
],
"photos": [
{}
],
"eans": [
"…"
],
"isFather": true,
"fatherSku": "…",
"variants": [
{}
]
}
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid parameters — `{"error":"…"}` |
| 404 | Article or Company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,46 @@
# `GET /public/{companyId}/categories`
Public. No cookie required.
List public categories
Returns the category tree for the specified company.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `companyId` | yes | integer | Company ID |
## Response `200`
Category list
```json
{
"categories": [
{
"id": 1,
"parentId": 1,
"sort": 1,
"name": "…",
"slug": "…",
"fullHash": "…",
"thumbW": 1,
"thumbH": 1,
"thumbHash": "…"
}
]
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Invalid parameters — `{"error":"…"}` |
| 404 | Company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._