u
This commit is contained in:
@@ -10,7 +10,7 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
### Reusable types
|
### Reusable types
|
||||||
|
|
||||||
- `T1` = `{ article: T2 }`
|
- `T1` = `{ article: T2 }`
|
||||||
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T32, brand: T28|null, categoryIds: int[], photos: T26[], eans: str[], prices: T36[], suppliers: T12[] }`
|
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T31, brand: T28|null, categoryIds: int[], photos: T26[], eans: str[], prices: T35[], suppliers: T12[] }`
|
||||||
- `T3` = `{ delivery: T4 }`
|
- `T3` = `{ delivery: T4 }`
|
||||||
- `T4` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T20[], files: T9[], externalNumber?: str|null, createdAt?: str, ledger?: T40 }`
|
- `T4` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T20[], files: T9[], externalNumber?: str|null, createdAt?: str, ledger?: T40 }`
|
||||||
- `T5` = `{ labeltemplate: T6 }`
|
- `T5` = `{ labeltemplate: T6 }`
|
||||||
@@ -38,13 +38,13 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
- `T27` = `{ id: int, customergroupId: int, firstName: str|null, name: str, number: str|null, createdAt: str, updatedAt: str }`
|
- `T27` = `{ id: int, customergroupId: int, firstName: str|null, name: str, number: str|null, createdAt: str, updatedAt: str }`
|
||||||
- `T28` = `{ name: str, id?: int|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null }`
|
- `T28` = `{ name: str, id?: int|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null }`
|
||||||
- `T29` = `{ id: int, companyuser_id: int, provider: str, model: str, created_at: str, updated_at: str, state: str }`
|
- `T29` = `{ id: int, companyuser_id: int, provider: str, model: str, created_at: str, updated_at: str, state: str }`
|
||||||
- `T30` = `{ id: int, sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }`
|
- `T30` = `{ article: T33 }`
|
||||||
- `T31` = `{ article: T34 }`
|
- `T31` = `{ si: str, basesi: str, basesifactor: num, symbol?: str|null, name?: str|null }`
|
||||||
- `T32` = `{ si: str, basesi: str, basesifactor: num, symbol?: str|null, name?: str|null }`
|
- `T32` = `{ id: int, iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
||||||
- `T33` = `{ id: int, iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
- `T33` = `{ id: int, categoryId: int, name: str, sku: str, track_stock: bool }`
|
||||||
- `T34` = `{ id: int, categoryId: int, name: str, sku: str, track_stock: bool }`
|
- `T34` = `{ id: int, email: str, selectedCompanyId: int|null, picture?: str }`
|
||||||
- `T35` = `{ id: int, email: str, selectedCompanyId: int|null, picture?: str }`
|
- `T35` = `{ minmultiplier: num, net: num, taxRate: num, customergroupId: int }`
|
||||||
- `T36` = `{ minmultiplier: num, net: num, taxRate: num, customergroupId: int }`
|
- `T36` = `{ fullHash: str, thumbW: int, thumbH: int, thumbHash: str }`
|
||||||
- `T37` = `{ id: int, entityId: int, contactType: str, contact: str }`
|
- `T37` = `{ id: int, entityId: int, contactType: str, contact: str }`
|
||||||
- `T38` = `{ id: int, attributeId: int, value: str, sort: int }`
|
- `T38` = `{ id: int, attributeId: int, value: str, sort: int }`
|
||||||
- `T39` = `{ id: int, name: str, createdAt: str, updatedAt: str }`
|
- `T39` = `{ id: int, name: str, createdAt: str, updatedAt: str }`
|
||||||
@@ -68,7 +68,7 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Create article in category — `POST /article`
|
#### Create article in category — `POST /article`
|
||||||
- Params: `body: { categoryId: int, name: str, desc?: str, seo?: str, track_stock?: bool }`
|
- Params: `body: { categoryId: int, name: str, desc?: str, seo?: str, track_stock?: bool }`
|
||||||
- Returns: `201 T31`
|
- Returns: `201 T30`
|
||||||
#### Export articles as ZIP — `GET /article/export.zip`
|
#### Export articles as ZIP — `GET /article/export.zip`
|
||||||
- Params: `query: categoryId?: int`
|
- Params: `query: categoryId?: int`
|
||||||
- Returns: `200 zip`
|
- Returns: `200 zip`
|
||||||
@@ -104,10 +104,10 @@ _none_
|
|||||||
- Returns: `200 { children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
- Returns: `200 { children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
||||||
#### Create and attach a new child article to a parent article — `POST /article/{sku}/children`
|
#### Create and attach a new child article to a parent article — `POST /article/{sku}/children`
|
||||||
- Params: `sku: str, body: { attributeValueId?: int, value?: str, name?: str }`
|
- Params: `sku: str, body: { attributeValueId?: int, value?: str, name?: str }`
|
||||||
- Returns: `201 T31`
|
- Returns: `201 T30`
|
||||||
#### Attach an existing article as a child to a parent article — `PUT /article/{sku}/children`
|
#### Attach an existing article as a child to a parent article — `PUT /article/{sku}/children`
|
||||||
- Params: `sku: str, body: { sku: str, attributeValueId?: int, value?: str, reparent?: bool }`
|
- Params: `sku: str, body: { sku: str, attributeValueId?: int, value?: str, reparent?: bool }`
|
||||||
- Returns: `200 { article: T34, children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
- Returns: `200 { article: T33, children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
||||||
#### Remove a child article from a parent article — `DELETE /article/{sku}/children/{childSku}`
|
#### Remove a child article from a parent article — `DELETE /article/{sku}/children/{childSku}`
|
||||||
- Params: `sku: str, childSku: str, query: deleteArticle?: bool`
|
- Params: `sku: str, childSku: str, query: deleteArticle?: bool`
|
||||||
- Returns: `200 { success: bool, deleted: bool }`
|
- Returns: `200 { success: bool, deleted: bool }`
|
||||||
@@ -134,7 +134,7 @@ _none_
|
|||||||
- Returns: `200 { options: { id: int, articleId: int, sku: str, name: str, count: int, sort: int, mandated: bool }[] }`
|
- Returns: `200 { options: { id: int, articleId: int, sku: str, name: str, count: int, sort: int, mandated: bool }[] }`
|
||||||
#### Toggle parent mode for an article — `POST /article/{sku}/parent`
|
#### Toggle parent mode for an article — `POST /article/{sku}/parent`
|
||||||
- Params: `sku: str, body: { isParent: bool, attributeNameId?: int }`
|
- Params: `sku: str, body: { isParent: bool, attributeNameId?: int }`
|
||||||
- Returns: `200 T31`
|
- Returns: `200 T30`
|
||||||
#### Replace POS prices by SKU (net > gross; price=net, tax=taxRate %) — `PUT /article/{sku}/prices`
|
#### Replace POS prices by SKU (net > gross; price=net, tax=taxRate %) — `PUT /article/{sku}/prices`
|
||||||
- Params: `sku: str, body: { prices: { net?: num, gross?: num, price?: num, taxRate?: num, tax?: num, minmultiplier?: num }[] }`
|
- Params: `sku: str, body: { prices: { net?: num, gross?: num, price?: num, taxRate?: num, tax?: num, minmultiplier?: num }[] }`
|
||||||
- Returns: `200 T1`
|
- Returns: `200 T1`
|
||||||
@@ -203,22 +203,22 @@ _none_
|
|||||||
- Returns: `200 { attributevalue: T38 }`
|
- Returns: `200 { attributevalue: T38 }`
|
||||||
#### Login with Google ID token — `POST /auth/login`
|
#### Login with Google ID token — `POST /auth/login`
|
||||||
- Params: `body: { idToken: str }`
|
- Params: `body: { idToken: str }`
|
||||||
- Returns: `200 { message: str, user: T35 }`
|
- Returns: `200 { message: str, user: T34 }`
|
||||||
#### Logout — `POST /auth/logout`
|
#### Logout — `POST /auth/logout`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { message: str }`
|
- Returns: `200 { message: str }`
|
||||||
#### Current user — `GET /auth/me`
|
#### Current user — `GET /auth/me`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { user: T35, googleClientId: str }`
|
- Returns: `200 { user: T34, googleClientId: str }`
|
||||||
#### Set selected company — `PUT /auth/selected-company`
|
#### Set selected company — `PUT /auth/selected-company`
|
||||||
- Params: `body: { companyId: int }`
|
- Params: `body: { companyId: int }`
|
||||||
- Returns: `200 { user: T35 }`
|
- Returns: `200 { user: T34 }`
|
||||||
#### List brands — `GET /brand`
|
#### List brands — `GET /brand`
|
||||||
_none_
|
- Params: `query: offset?: int, limit?: int`
|
||||||
- Returns: `200 { brands: { id: int, name: str, pics: T30[], gsprpinfo?: str|null }[] }`
|
- Returns: `200 { brands: { id: int, name: str, pics: T36[], gsprpinfo?: str|null }[], total: int, offset: int, limit: int }`
|
||||||
#### Create brand — `POST /brand`
|
#### Create brand — `POST /brand`
|
||||||
- Params: `body: { name: str, gsprpinfo?: str }`
|
- Params: `body: { name: str, gsprpinfo?: str }`
|
||||||
- Returns: `201 { brand: { id: int, name: str, pics: T30[], gsprpinfo?: str|null } }`
|
- Returns: `201 { brand: { id: int, name: str, pics: T36[], gsprpinfo?: str|null } }`
|
||||||
#### Delete brand — `DELETE /brand/{id}`
|
#### Delete brand — `DELETE /brand/{id}`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
@@ -227,10 +227,10 @@ _none_
|
|||||||
- Returns: `200 { brand: { id: int, name: str, touchedArticleCount: int, gsprpinfo?: str|null } }`
|
- Returns: `200 { brand: { id: int, name: str, touchedArticleCount: int, gsprpinfo?: str|null } }`
|
||||||
#### Delete brand image — `DELETE /brand/{id}/image`
|
#### Delete brand image — `DELETE /brand/{id}/image`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { brand: { id: int, thumbW: int|null, thumbH: int|null, thumbHash: str|null, pics: T30[] } }`
|
- Returns: `200 { brand: { id: int, thumbW: int|null, thumbH: int|null, thumbHash: str|null, pics: T36[] } }`
|
||||||
#### Add or replace brand image — `POST /brand/{id}/image`
|
#### Add or replace brand image — `POST /brand/{id}/image`
|
||||||
- Params: `id: int, image/avif`
|
- Params: `id: int, image/avif`
|
||||||
- Returns: `201 { brand: { id: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str, pics: T30[] } }`
|
- Returns: `201 { brand: { id: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str, pics: T36[] } }`
|
||||||
#### Create category — `POST /category`
|
#### Create category — `POST /category`
|
||||||
- Params: `body: { parentId: int, name: str }`
|
- Params: `body: { parentId: int, name: str }`
|
||||||
- Returns: `201 { category: { id: int, parentId: int|null, sort: int, name: str } }`
|
- Returns: `201 { category: { id: int, parentId: int|null, sort: int, name: str } }`
|
||||||
@@ -275,10 +275,10 @@ _none_
|
|||||||
- Returns: `200 { ok: bool }`
|
- Returns: `200 { ok: bool }`
|
||||||
#### List companies — `GET /company`
|
#### List companies — `GET /company`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { companies: T33[] }`
|
- Returns: `200 { companies: T32[] }`
|
||||||
#### Create company — `POST /company`
|
#### Create company — `POST /company`
|
||||||
- Params: `body: { iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
- Params: `body: { iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
||||||
- Returns: `201 { company: T33, user: T35 }`
|
- Returns: `201 { company: T32, user: T34 }`
|
||||||
#### Get company history — `GET /company/history`
|
#### Get company history — `GET /company/history`
|
||||||
- Params: `query: limit?: int`
|
- Params: `query: limit?: int`
|
||||||
- Returns: `200 { history: { id: int, date: str, text: str, companyuserId?: int|null }[], truncated: bool }`
|
- Returns: `200 { history: { id: int, date: str, text: str, companyuserId?: int|null }[], truncated: bool }`
|
||||||
@@ -302,7 +302,7 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Update company — `PUT /company/{id}`
|
#### Update company — `PUT /company/{id}`
|
||||||
- Params: `id: int, body: { iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
- Params: `id: int, body: { iso639: str, name: str, taxrate: num, reducedtaxrate: num }`
|
||||||
- Returns: `200 { company: T33 }`
|
- Returns: `200 { company: T32 }`
|
||||||
#### List customer groups — `GET /customergroup`
|
#### List customer groups — `GET /customergroup`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { customergroups: { id: int, name: str, sort: int, editable: bool }[] }`
|
- Returns: `200 { customergroups: { id: int, name: str, sort: int, editable: bool }[] }`
|
||||||
@@ -611,10 +611,10 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### List units — `GET /unit`
|
#### List units — `GET /unit`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { units: T32[] }`
|
- Returns: `200 { units: T31[] }`
|
||||||
#### Upsert unit — `PUT /unit`
|
#### Upsert unit — `PUT /unit`
|
||||||
- Params: `body: { si: str, basesi: str, basesifactor: num, symbol: str, name: str }`
|
- Params: `body: { si: str, basesi: str, basesifactor: num, symbol: str, name: str }`
|
||||||
- Returns: `200 { unit: T32 }`
|
- Returns: `200 { unit: T31 }`
|
||||||
#### JTL-POS category synchronization — `GET /v1/category`
|
#### JTL-POS category synchronization — `GET /v1/category`
|
||||||
- Params: `query: lastChangedCategory?: str, limit?: int`
|
- Params: `query: lastChangedCategory?: str, limit?: int`
|
||||||
- Returns: `200 {}[]`
|
- Returns: `200 {}[]`
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
### Reusable types
|
### Reusable types
|
||||||
|
|
||||||
- `T1` = `{ article: T2 }`
|
- `T1` = `{ article: T2 }`
|
||||||
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T30, brand: T27|null, categoryIds: int[], photos: T25[], eans: str[], prices: T32[], suppliers: T11[] }`
|
- `T2` = `{ id: int, sku: str, name: str, slug: str, desc: str|null, seo: str|null, track_stock: bool, unitamount: num|null, weight: num|null, unit: T29, brand: T27|null, categoryIds: int[], photos: T25[], eans: str[], prices: T31[], suppliers: T11[] }`
|
||||||
- `T3` = `{ delivery: T4 }`
|
- `T3` = `{ delivery: T4 }`
|
||||||
- `T4` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T19[], files: T9[], externalNumber?: str|null, createdAt?: str, ledger?: T36 }`
|
- `T4` = `{ id: int, number: str, type: str, supplierId: int|null, date: str, lines: T19[], files: T9[], externalNumber?: str|null, createdAt?: str, ledger?: T36 }`
|
||||||
- `T5` = `{ labeltemplate: T6 }`
|
- `T5` = `{ labeltemplate: T6 }`
|
||||||
@@ -36,11 +36,11 @@ Params: path values first, then `query:` and `body:` (`body?` = optional body).
|
|||||||
- `T25` = `{ sort: int, fullHash: str, fullW: int, fullH: int, fullSize: int, thumbW: int, thumbH: int, thumbHash: str }`
|
- `T25` = `{ sort: int, fullHash: str, fullW: int, fullH: int, fullSize: int, thumbW: int, thumbH: int, thumbHash: str }`
|
||||||
- `T26` = `{ id: int, customergroupId: int, firstName: str|null, name: str, number: str|null, createdAt: str, updatedAt: str }`
|
- `T26` = `{ id: int, customergroupId: int, firstName: str|null, name: str, number: str|null, createdAt: str, updatedAt: str }`
|
||||||
- `T27` = `{ name: str, id?: int|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null }`
|
- `T27` = `{ name: str, id?: int|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null }`
|
||||||
- `T28` = `{ id: int, sort: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str }`
|
- `T28` = `{ article: T30 }`
|
||||||
- `T29` = `{ article: T31 }`
|
- `T29` = `{ si: str, basesi: str, basesifactor: num, symbol?: str|null, name?: str|null }`
|
||||||
- `T30` = `{ si: str, basesi: str, basesifactor: num, symbol?: str|null, name?: str|null }`
|
- `T30` = `{ id: int, categoryId: int, name: str, sku: str, track_stock: bool }`
|
||||||
- `T31` = `{ id: int, categoryId: int, name: str, sku: str, track_stock: bool }`
|
- `T31` = `{ minmultiplier: num, net: num, taxRate: num, customergroupId: int }`
|
||||||
- `T32` = `{ minmultiplier: num, net: num, taxRate: num, customergroupId: int }`
|
- `T32` = `{ fullHash: str, thumbW: int, thumbH: int, thumbHash: str }`
|
||||||
- `T33` = `{ id: int, entityId: int, contactType: str, contact: str }`
|
- `T33` = `{ id: int, entityId: int, contactType: str, contact: str }`
|
||||||
- `T34` = `{ id: int, attributeId: int, value: str, sort: int }`
|
- `T34` = `{ id: int, attributeId: int, value: str, sort: int }`
|
||||||
- `T35` = `{ id: int, name: str, createdAt: str, updatedAt: str }`
|
- `T35` = `{ id: int, name: str, createdAt: str, updatedAt: str }`
|
||||||
@@ -63,7 +63,7 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### Create article in category — `POST /article`
|
#### Create article in category — `POST /article`
|
||||||
- Params: `body: { categoryId: int, name: str, desc?: str, seo?: str, track_stock?: bool }`
|
- Params: `body: { categoryId: int, name: str, desc?: str, seo?: str, track_stock?: bool }`
|
||||||
- Returns: `201 T29`
|
- Returns: `201 T28`
|
||||||
#### Delete article by SKU — `DELETE /article/{sku}`
|
#### Delete article by SKU — `DELETE /article/{sku}`
|
||||||
- Params: `sku: str, query: cascade?: bool`
|
- Params: `sku: str, query: cascade?: bool`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
@@ -96,10 +96,10 @@ _none_
|
|||||||
- Returns: `200 { children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
- Returns: `200 { children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
||||||
#### Create and attach a new child article to a parent article — `POST /article/{sku}/children`
|
#### Create and attach a new child article to a parent article — `POST /article/{sku}/children`
|
||||||
- Params: `sku: str, body: { attributeValueId?: int, value?: str, name?: str }`
|
- Params: `sku: str, body: { attributeValueId?: int, value?: str, name?: str }`
|
||||||
- Returns: `201 T29`
|
- Returns: `201 T28`
|
||||||
#### Attach an existing article as a child to a parent article — `PUT /article/{sku}/children`
|
#### Attach an existing article as a child to a parent article — `PUT /article/{sku}/children`
|
||||||
- Params: `sku: str, body: { sku: str, attributeValueId?: int, value?: str, reparent?: bool }`
|
- Params: `sku: str, body: { sku: str, attributeValueId?: int, value?: str, reparent?: bool }`
|
||||||
- Returns: `200 { article: T31, children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
- Returns: `200 { article: T30, children: { id: int, sku: str, name: str, parentsort: int, attributeValueId: int, attributeValue: str }[] }`
|
||||||
#### Remove a child article from a parent article — `DELETE /article/{sku}/children/{childSku}`
|
#### Remove a child article from a parent article — `DELETE /article/{sku}/children/{childSku}`
|
||||||
- Params: `sku: str, childSku: str, query: deleteArticle?: bool`
|
- Params: `sku: str, childSku: str, query: deleteArticle?: bool`
|
||||||
- Returns: `200 { success: bool, deleted: bool }`
|
- Returns: `200 { success: bool, deleted: bool }`
|
||||||
@@ -123,7 +123,7 @@ _none_
|
|||||||
- Returns: `200 { options: { id: int, articleId: int, sku: str, name: str, count: int, sort: int, mandated: bool }[] }`
|
- Returns: `200 { options: { id: int, articleId: int, sku: str, name: str, count: int, sort: int, mandated: bool }[] }`
|
||||||
#### Toggle parent mode for an article — `POST /article/{sku}/parent`
|
#### Toggle parent mode for an article — `POST /article/{sku}/parent`
|
||||||
- Params: `sku: str, body: { isParent: bool, attributeNameId?: int }`
|
- Params: `sku: str, body: { isParent: bool, attributeNameId?: int }`
|
||||||
- Returns: `200 T29`
|
- Returns: `200 T28`
|
||||||
#### Replace POS prices by SKU (net > gross; price=net, tax=taxRate %) — `PUT /article/{sku}/prices`
|
#### Replace POS prices by SKU (net > gross; price=net, tax=taxRate %) — `PUT /article/{sku}/prices`
|
||||||
- Params: `sku: str, body: { prices: { net?: num, gross?: num, price?: num, taxRate?: num, tax?: num, minmultiplier?: num }[] }`
|
- Params: `sku: str, body: { prices: { net?: num, gross?: num, price?: num, taxRate?: num, tax?: num, minmultiplier?: num }[] }`
|
||||||
- Returns: `200 T1`
|
- Returns: `200 T1`
|
||||||
@@ -197,11 +197,11 @@ _none_
|
|||||||
_none_
|
_none_
|
||||||
- Returns: `200 { message: str }`
|
- Returns: `200 { message: str }`
|
||||||
#### List brands — `GET /brand`
|
#### List brands — `GET /brand`
|
||||||
_none_
|
- Params: `query: offset?: int, limit?: int`
|
||||||
- Returns: `200 { brands: { id: int, name: str, pics: T28[], gsprpinfo?: str|null }[] }`
|
- Returns: `200 { brands: { id: int, name: str, pics: T32[], gsprpinfo?: str|null }[], total: int, offset: int, limit: int }`
|
||||||
#### Create brand — `POST /brand`
|
#### Create brand — `POST /brand`
|
||||||
- Params: `body: { name: str, gsprpinfo?: str }`
|
- Params: `body: { name: str, gsprpinfo?: str }`
|
||||||
- Returns: `201 { brand: { id: int, name: str, pics: T28[], gsprpinfo?: str|null } }`
|
- Returns: `201 { brand: { id: int, name: str, pics: T32[], gsprpinfo?: str|null } }`
|
||||||
#### Delete brand — `DELETE /brand/{id}`
|
#### Delete brand — `DELETE /brand/{id}`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
@@ -210,10 +210,10 @@ _none_
|
|||||||
- Returns: `200 { brand: { id: int, name: str, touchedArticleCount: int, gsprpinfo?: str|null } }`
|
- Returns: `200 { brand: { id: int, name: str, touchedArticleCount: int, gsprpinfo?: str|null } }`
|
||||||
#### Delete brand image — `DELETE /brand/{id}/image`
|
#### Delete brand image — `DELETE /brand/{id}/image`
|
||||||
- Params: `id: int`
|
- Params: `id: int`
|
||||||
- Returns: `200 { brand: { id: int, thumbW: int|null, thumbH: int|null, thumbHash: str|null, pics: T28[] } }`
|
- Returns: `200 { brand: { id: int, thumbW: int|null, thumbH: int|null, thumbHash: str|null, pics: T32[] } }`
|
||||||
#### Add or replace brand image — `POST /brand/{id}/image`
|
#### Add or replace brand image — `POST /brand/{id}/image`
|
||||||
- Params: `id: int, image/avif`
|
- Params: `id: int, image/avif`
|
||||||
- Returns: `201 { brand: { id: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str, pics: T28[] } }`
|
- Returns: `201 { brand: { id: int, fullHash: str, thumbW: int, thumbH: int, thumbHash: str, pics: T32[] } }`
|
||||||
#### Create category — `POST /category`
|
#### Create category — `POST /category`
|
||||||
- Params: `body: { parentId: int, name: str }`
|
- Params: `body: { parentId: int, name: str }`
|
||||||
- Returns: `201 { category: { id: int, parentId: int|null, sort: int, name: str } }`
|
- Returns: `201 { category: { id: int, parentId: int|null, sort: int, name: str } }`
|
||||||
@@ -504,10 +504,10 @@ _none_
|
|||||||
- Returns: `204 void`
|
- Returns: `204 void`
|
||||||
#### List units — `GET /unit`
|
#### List units — `GET /unit`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { units: T30[] }`
|
- Returns: `200 { units: T29[] }`
|
||||||
#### Upsert unit — `PUT /unit`
|
#### Upsert unit — `PUT /unit`
|
||||||
- Params: `body: { si: str, basesi: str, basesifactor: num, symbol: str, name: str }`
|
- Params: `body: { si: str, basesi: str, basesifactor: num, symbol: str, name: str }`
|
||||||
- Returns: `200 { unit: T30 }`
|
- Returns: `200 { unit: T29 }`
|
||||||
#### List warehouses — `GET /warehouse`
|
#### List warehouses — `GET /warehouse`
|
||||||
_none_
|
_none_
|
||||||
- Returns: `200 { warehouses: T40[] }`
|
- Returns: `200 { warehouses: T40[] }`
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ Image removed
|
|||||||
"thumbHash": "…",
|
"thumbHash": "…",
|
||||||
"pics": [
|
"pics": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
|
||||||
"sort": 1,
|
|
||||||
"fullHash": "…",
|
"fullHash": "…",
|
||||||
"thumbW": 1,
|
"thumbW": 1,
|
||||||
"thumbH": 1,
|
"thumbH": 1,
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ Image stored and linked
|
|||||||
"thumbHash": "…",
|
"thumbHash": "…",
|
||||||
"pics": [
|
"pics": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
|
||||||
"sort": 1,
|
|
||||||
"fullHash": "…",
|
"fullHash": "…",
|
||||||
"thumbW": 1,
|
"thumbW": 1,
|
||||||
"thumbH": 1,
|
"thumbH": 1,
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ Created brand
|
|||||||
"gsprpinfo": "…",
|
"gsprpinfo": "…",
|
||||||
"pics": [
|
"pics": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
|
||||||
"sort": 1,
|
|
||||||
"fullHash": "…",
|
"fullHash": "…",
|
||||||
"thumbW": 1,
|
"thumbW": 1,
|
||||||
"thumbH": 1,
|
"thumbH": 1,
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ Protected. Requires a valid session cookie (`credentials: 'include'`).
|
|||||||
|
|
||||||
List brands
|
List brands
|
||||||
|
|
||||||
Lists brands for the authenticated user's selected company, sorted by name.
|
Lists brands for the authenticated user's selected company, sorted by name. Paged; `total` is the unpaged count.
|
||||||
|
|
||||||
|
## Query parameters
|
||||||
|
|
||||||
|
| Param | Required | Type | Description |
|
||||||
|
|-------|----------|------|-------------|
|
||||||
|
| `offset` | no | integer | Number of brands to skip |
|
||||||
|
| `limit` | no | integer | Number of brands to return |
|
||||||
|
|
||||||
## Response `200`
|
## Response `200`
|
||||||
|
|
||||||
@@ -19,8 +26,6 @@ Brand list
|
|||||||
"gsprpinfo": "…",
|
"gsprpinfo": "…",
|
||||||
"pics": [
|
"pics": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
|
||||||
"sort": 1,
|
|
||||||
"fullHash": "…",
|
"fullHash": "…",
|
||||||
"thumbW": 1,
|
"thumbW": 1,
|
||||||
"thumbH": 1,
|
"thumbH": 1,
|
||||||
@@ -28,7 +33,10 @@ Brand list
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"total": 1,
|
||||||
|
"offset": 1,
|
||||||
|
"limit": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -36,7 +44,7 @@ Brand list
|
|||||||
|
|
||||||
| Status | Description |
|
| Status | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| 400 | No company selected — `{"error":"…"}` |
|
| 400 | Invalid offset, invalid limit, or no company selected — `{"error":"…"}` |
|
||||||
| 401 | Unauthorized — `{"error":"…"}` |
|
| 401 | Unauthorized — `{"error":"…"}` |
|
||||||
| 403 | Not authorized — `{"error":"…"}` |
|
| 403 | Not authorized — `{"error":"…"}` |
|
||||||
| 404 | Company not found — `{"error":"…"}` |
|
| 404 | Company not found — `{"error":"…"}` |
|
||||||
|
|||||||
@@ -343,12 +343,8 @@
|
|||||||
* $ref: '#/components/schemas/SupplierArticleInfo'
|
* $ref: '#/components/schemas/SupplierArticleInfo'
|
||||||
* BrandPic:
|
* BrandPic:
|
||||||
* type: object
|
* type: object
|
||||||
* required: [id, sort, fullHash, thumbW, thumbH, thumbHash]
|
* required: [fullHash, thumbW, thumbH, thumbHash]
|
||||||
* properties:
|
* properties:
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* sort:
|
|
||||||
* type: integer
|
|
||||||
* fullHash:
|
* fullHash:
|
||||||
* type: string
|
* type: string
|
||||||
* thumbW:
|
* thumbW:
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ function brandErrorStatus(error) {
|
|||||||
if (error.message === 'Company not found') return 404;
|
if (error.message === 'Company not found') return 404;
|
||||||
if (error.message === 'Brand not found') return 404;
|
if (error.message === 'Brand not found') return 404;
|
||||||
if (error.message === 'Invalid brand') return 400;
|
if (error.message === 'Invalid brand') return 400;
|
||||||
|
if (error.message === 'Invalid offset') return 400;
|
||||||
|
if (error.message === 'Invalid limit') return 400;
|
||||||
if (error.message === 'Brand already exists') return 409;
|
if (error.message === 'Brand already exists') return 409;
|
||||||
if (error.message === 'Brand in use') return 409;
|
if (error.message === 'Brand in use') return 409;
|
||||||
if (error.message === 'Image not found') return 404;
|
if (error.message === 'Image not found') return 404;
|
||||||
@@ -45,9 +47,25 @@ export function register(app, basePath = '') {
|
|||||||
* get:
|
* get:
|
||||||
* tags: [Brand]
|
* tags: [Brand]
|
||||||
* summary: List brands
|
* summary: List brands
|
||||||
* description: Lists brands for the authenticated user's selected company, sorted by name.
|
* description: Lists brands for the authenticated user's selected company, sorted by name. Paged; `total` is the unpaged count.
|
||||||
* security:
|
* security:
|
||||||
* - cookieAuth: []
|
* - cookieAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: offset
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* default: 0
|
||||||
|
* minimum: 0
|
||||||
|
* description: Number of brands to skip
|
||||||
|
* - in: query
|
||||||
|
* name: limit
|
||||||
|
* schema:
|
||||||
|
* type: integer
|
||||||
|
* default: 10
|
||||||
|
* minimum: 1
|
||||||
|
* maximum: 100
|
||||||
|
* description: Number of brands to return
|
||||||
* x-markdown: brand/list.md
|
* x-markdown: brand/list.md
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
@@ -56,13 +74,23 @@ export function register(app, basePath = '') {
|
|||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* type: object
|
* type: object
|
||||||
|
* required: [brands, total, offset, limit]
|
||||||
* properties:
|
* properties:
|
||||||
* brands:
|
* brands:
|
||||||
* type: array
|
* type: array
|
||||||
* items:
|
* items:
|
||||||
* $ref: '#/components/schemas/Brand'
|
* $ref: '#/components/schemas/Brand'
|
||||||
|
* total:
|
||||||
|
* type: integer
|
||||||
|
* description: Total number of unpaged brands
|
||||||
|
* offset:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of brands skipped
|
||||||
|
* limit:
|
||||||
|
* type: integer
|
||||||
|
* description: Number of brands returned
|
||||||
* 400:
|
* 400:
|
||||||
* description: No company selected
|
* description: Invalid offset, invalid limit, or no company selected
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
@@ -92,9 +120,29 @@ export function register(app, basePath = '') {
|
|||||||
return res.status(400).json({ error: selected.error });
|
return res.status(400).json({ error: selected.error });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rawOffset = req.query.offset;
|
||||||
|
const rawLimit = req.query.limit;
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
let limit = 10;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
limit = parseInt(rawLimit, 10);
|
||||||
|
if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
|
||||||
|
return res.status(400).json({ error: 'limit must be an integer between 1 and 100' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const brands = await db.list(req.user.id);
|
const result = await db.list(req.user.id, { offset, limit });
|
||||||
res.status(200).json({ brands });
|
res.status(200).json(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const status = brandErrorStatus(error);
|
const status = brandErrorStatus(error);
|
||||||
if (status === 500) console.error('List brands failed:', error);
|
if (status === 500) console.error('List brands failed:', error);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { getStore } from './store.js';
|
import { getStore } from './store.js';
|
||||||
|
|
||||||
export async function list(googleAuthId) {
|
export async function list(googleAuthId, opts) {
|
||||||
const store = await getStore();
|
const store = await getStore();
|
||||||
return store.brand.list(googleAuthId);
|
return store.brand.list(googleAuthId, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(googleAuthId, data) {
|
export async function create(googleAuthId, data) {
|
||||||
|
|||||||
@@ -360,9 +360,9 @@ export async function executeCompanyImport({
|
|||||||
log.info(`Processing ${brandEntries.length} brands (Hersteller)...`);
|
log.info(`Processing ${brandEntries.length} brands (Hersteller)...`);
|
||||||
|
|
||||||
// Fetch existing brands to accurately track new vs existing
|
// Fetch existing brands to accurately track new vs existing
|
||||||
const existingBrands = await store.brand.list(googleAuthId);
|
const { brands: existingBrandRows } = await store.brand.list(googleAuthId, { offset: 0, limit: 100 });
|
||||||
const existingBrandNames = new Set(
|
const existingBrandNames = new Set(
|
||||||
existingBrands.map((b) => (b.name || '').trim().toLowerCase()).filter(Boolean)
|
existingBrandRows.map((b) => (b.name || '').trim().toLowerCase()).filter(Boolean)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (let i = 0; i < brandEntries.length; i++) {
|
for (let i = 0; i < brandEntries.length; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user