From a7258abf3594ff82f7cd809e79c06b7c3839e561 Mon Sep 17 00:00:00 2001 From: seb Date: Fri, 30 Oct 2026 06:43:45 +0100 Subject: [PATCH] u --- docs/api/routes-all.md | 2 +- docs/api/routes.md | 2 +- docs/api/routes/category/articles.md | 8 +++++++- src/api/routes/category.js | 18 ++++++++++++++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/api/routes-all.md b/docs/api/routes-all.md index 25b159b..4003f82 100644 --- a/docs/api/routes-all.md +++ b/docs/api/routes-all.md @@ -315,7 +315,7 @@ _none_ - Params: `id: int, body: { name?: str, parentId?: int }` - Returns: `200 { category: { id: int, name: str, slug: str, parentId: int, sort: int } }` #### Articles in category — `GET /category/{id}/articles` -- Params: `id: int` +- Params: `id: int, query: includeChildren?: bool` - Returns: `200 { articles: { id: int, sku: str, name: str, slug: str, track_stock: bool, optionsCount: int, articleListCount: int, childCount: int, net?: num|null, taxRate?: num|null, parentArticleId?: int|null, parentSku?: str|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null, smallThumbW?: int|null, smallThumbH?: int|null, smallThumbBinary?: str|null, brand?: T25|null, articlewarehousesummary?: { id: int, articleId: int, warehouseId: int, stock: num, article_id?: int, warehouse_id?: int, warehouseName?: str|null }[], warehouses?: { id: int, name: str, stock: num }[] }[] }` #### List category attribute values — `GET /category/{id}/attributevalue` - Params: `id: int` diff --git a/docs/api/routes.md b/docs/api/routes.md index 39760fa..1bc678d 100644 --- a/docs/api/routes.md +++ b/docs/api/routes.md @@ -242,7 +242,7 @@ _none_ - Params: `id: int, body: { name?: str, parentId?: int }` - Returns: `200 { category: { id: int, name: str, slug: str, parentId: int, sort: int } }` #### Articles in category — `GET /category/{id}/articles` -- Params: `id: int` +- Params: `id: int, query: includeChildren?: bool` - Returns: `200 { articles: { id: int, sku: str, name: str, slug: str, track_stock: bool, optionsCount: int, articleListCount: int, childCount: int, net?: num|null, taxRate?: num|null, parentArticleId?: int|null, parentSku?: str|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null, smallThumbW?: int|null, smallThumbH?: int|null, smallThumbBinary?: str|null, brand?: { name: str, id?: int|null, fullHash?: str|null, thumbW?: int|null, thumbH?: int|null, thumbHash?: str|null }, articlewarehousesummary?: { id: int, articleId: int, warehouseId: int, stock: num, article_id?: int, warehouse_id?: int, warehouseName?: str|null }[], warehouses?: { id: int, name: str, stock: num }[] }[] }` #### List category attribute values — `GET /category/{id}/attributevalue` - Params: `id: int` diff --git a/docs/api/routes/category/articles.md b/docs/api/routes/category/articles.md index d2942bd..a853b62 100644 --- a/docs/api/routes/category/articles.md +++ b/docs/api/routes/category/articles.md @@ -4,7 +4,7 @@ Protected. Requires a valid session cookie (`credentials: 'include'`). Articles in category -Returns articles in a category the user is authorized for (omits child articles of a parent article), sorted alphabetically by name. Each article includes `childCount` (the number of its child articles) and small thumbnail fields (`smallThumbW`, `smallThumbH`, `smallThumbBinary`). +Returns articles in a category the user is authorized for, sorted alphabetically by name. By default includes child articles (variants); pass `includeChildren=false` to omit them. Each article includes `childCount` (the number of its child articles) and small thumbnail fields (`smallThumbW`, `smallThumbH`, `smallThumbBinary`). ## Path parameters @@ -12,6 +12,12 @@ Returns articles in a category the user is authorized for (omits child articles |-------|----------|------|-------------| | `id` | yes | integer | Category id | +## Query parameters + +| Param | Required | Type | Description | +|-------|----------|------|-------------| +| `includeChildren` | no | boolean | When true (default), includes child articles (variants) alongside parent articles. Set to false to omit child articles. | + ## Response `200` Articles list diff --git a/src/api/routes/category.js b/src/api/routes/category.js index dc272aa..c63a609 100644 --- a/src/api/routes/category.js +++ b/src/api/routes/category.js @@ -324,7 +324,7 @@ export function register(app, basePath = '') { * get: * tags: [Category] * summary: Articles in category - * description: Returns articles in a category the user is authorized for (omits child articles of a parent article), sorted alphabetically by name. Each article includes `childCount` (the number of its child articles) and small thumbnail fields (`smallThumbW`, `smallThumbH`, `smallThumbBinary`). + * description: Returns articles in a category the user is authorized for, sorted alphabetically by name. By default includes child articles (variants); pass `includeChildren=false` to omit them. Each article includes `childCount` (the number of its child articles) and small thumbnail fields (`smallThumbW`, `smallThumbH`, `smallThumbBinary`). * security: * - cookieAuth: [] * x-markdown: category/articles.md @@ -335,6 +335,13 @@ export function register(app, basePath = '') { * schema: * type: integer * description: Category id + * - in: query + * name: includeChildren + * required: false + * schema: + * type: boolean + * default: true + * description: When true (default), includes child articles (variants) alongside parent articles. Set to false to omit child articles. * responses: * 200: * description: Articles list @@ -374,10 +381,17 @@ export function register(app, basePath = '') { return res.status(400).json({ error: parsed.error }); } + let includeChildren = true; + if (req.query.includeChildren !== undefined) { + includeChildren = req.query.includeChildren !== 'false' && req.query.includeChildren !== '0'; + } else if (req.query.variants !== undefined) { + includeChildren = req.query.variants !== 'false' && req.query.variants !== '0'; + } + try { const allArticles = await db.getCategoryArticles(req.user.id, parsed.id); const articles = allArticles - .filter((a) => a.parentArticleId == null) + .filter((a) => includeChildren || a.parentArticleId == null) .map((a) => ({ ...a, childCount: Number(a.childCount ?? 0),