feat(F-108): completed feature

This commit is contained in:
chattie
2026-08-21 09:57:11 +02:00
parent dca7c3214f
commit 840c839f67
16 changed files with 470 additions and 1155 deletions

View File

@@ -378,6 +378,13 @@ export async function registerCatalogRoutes(
const input = parseJson(newProductSchema, request.body);
try {
const product = await createProduct.execute(input);
// Modelo sin variantes visibles: cada producto lleva una única variante
// interna autogenerada (SKU interno, nunca editable).
try {
await createVariant.execute(product.id, { sku: `SKU-MV-${product.id}` });
} catch (variantError) {
request.log.warn({ err: variantError, productId: product.id }, 'default_variant_create_failed');
}
return reply.code(201).send(serializeProduct(product));
} catch (error) {
throw mapProductError(error);
@@ -396,7 +403,20 @@ export async function registerCatalogRoutes(
};
app.get('/products/:id/variants', { schema: variantsSchema }, async (request, reply) => {
const { id } = parseJson(idParamSchema, request.params);
const items = await listVariants.execute(id);
let items = await listVariants.execute(id);
if (items.length === 0) {
// Lazy migration: productos legacy sin variante reciben la variante
// default solo si quien consulta tiene sesión admin.
try {
const user = await deps.authenticate(request);
if (user.role === 'admin') {
const created = await createVariant.execute(id, { sku: `SKU-MV-${id}` });
if (created) items = [created];
}
} catch {
// Sin sesión admin: se devuelve la lista vacía sin crear nada.
}
}
return reply.send({ items: items.map(serializeVariant) });
});