This commit is contained in:
seb
2026-10-04 18:57:00 +02:00
parent c5cb76a66c
commit a8e51724f8
3 changed files with 118 additions and 6 deletions

View File

@@ -88,6 +88,11 @@ function articleErrorStatus(error) {
if (error.message === 'Attribute value is required for child article' || error.message === 'Attribute value is required') return 400;
if (error.message === 'Attribute value not found or does not match father attribute') return 400;
if (error.message === 'Child article does not belong to this father') return 400;
if (error.message === 'Article already belongs to another father') return 409;
if (error.message?.includes('sku is not allowed when creating a child article')) return 400;
if (error.message === 'sku is required' || error.message?.includes('sku is required')) return 400;
if (error.message === 'Article is already connected to a father article') return 400;
if (error.message === 'An article cannot be a child of itself') return 400;
if (error.message === 'Variant with this attribute value already exists') return 400;
if (error.message?.startsWith('Child article') && error.message?.includes('already exists')) return 400;
if (error.message?.toLowerCase().includes('duplicate variant')) return 400;
@@ -1930,8 +1935,8 @@ export function register(app, basePath = '') {
* @openapi
* /article/{sku}/children:
* post:
* summary: Add a child article to a father article
* description: Automatically generates SKU as fatherSku-nextFreeIndex (or accepts custom sku) and assigns the variant attribute.
* summary: Create and attach a new child article to a father article
* description: Automatically generates SKU as fatherSku-nextFreeIndex and name from father name + value. Rejects a caller-supplied sku.
* tags:
* - Article
* security:
@@ -1959,9 +1964,6 @@ export function register(app, basePath = '') {
* name:
* type: string
* description: Optional custom variant name
* sku:
* type: string
* description: Optional custom SKU for the child article
* responses:
* 201:
* description: Created child article
@@ -1973,12 +1975,73 @@ export function register(app, basePath = '') {
* article:
* $ref: '#/components/schemas/Article'
* 400:
* description: Father not configured as father, missing value, duplicate variant, or child SKU already exists
* description: Father not configured as father, missing value, duplicate variant, or sku was provided in body
* put:
* summary: Attach an existing article as a child to a father article
* description: Attaches an existing article to this father article. Idempotent if already a child. Returns 409 if the article already belongs to another father.
* tags:
* - Article
* security:
* - cookieAuth: []
* parameters:
* - in: path
* name: sku
* required: true
* schema:
* type: string
* description: Father article SKU
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - sku
* properties:
* sku:
* type: string
* description: SKU of the existing article to attach as child
* attributeValueId:
* type: integer
* description: ID of existing attribute value for the father's attribute
* value:
* type: string
* description: String value to find or create under the father's attribute
* reparent:
* type: boolean
* description: Whether to allow re-parenting if child already belongs to another father
* responses:
* 200:
* description: Attached child article and list of children
* content:
* application/json:
* schema:
* type: object
* properties:
* article:
* $ref: '#/components/schemas/Article'
* children:
* type: array
* items:
* type: object
* 400:
* description: Missing sku or attribute value, or invalid input
* 404:
* description: Father or child article not found
* 409:
* description: Article already belongs to another father, or variant value already exists
*/
app.post(`${basePath}/article/:sku/children`, async (req, res) => {
const parsed = parseSku(req.params.sku);
if (parsed.error) return res.status(400).json({ error: parsed.error });
if (req.body?.sku || req.body?.childSku) {
return res.status(400).json({
error: 'sku is not allowed when creating a child article; omit sku to auto-generate or use PUT to attach an existing article',
});
}
try {
const result = await db.addChild(req.user.id, parsed.sku, req.body || {});
emitArticleSignal(req, parsed.sku);
@@ -1994,6 +2057,30 @@ export function register(app, basePath = '') {
}
});
app.put(`${basePath}/article/:sku/children`, async (req, res) => {
const parsed = parseSku(req.params.sku);
if (parsed.error) return res.status(400).json({ error: parsed.error });
const childSku = typeof req.body?.sku === 'string' && req.body.sku.trim()
? req.body.sku.trim()
: (typeof req.body?.childSku === 'string' && req.body.childSku.trim() ? req.body.childSku.trim() : '');
if (!childSku) {
return res.status(400).json({ error: 'sku is required' });
}
try {
const result = await db.attachChild(req.user.id, parsed.sku, req.body || {});
emitArticleSignal(req, parsed.sku);
emitArticleSignal(req, childSku);
emitArticlesSignal(req);
res.status(200).json(result);
} catch (error) {
const status = articleErrorStatus(error);
if (status === 500) console.error('Attach child failed:', error);
res.status(status).json({ error: error.message });
}
});
/**
* @openapi
* /article/{sku}/children/{childSku}: