This endpoint performs a full product update inside a single database transaction. All fields in the request body are optional — any field you omit is preserved usingDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/MateoNavarroMN/Balsamoa-Backend/llms.txt
Use this file to discover all available pages before exploring further.
COALESCE in the SQL UPDATE statement, so you can safely send only the fields you want to change without clearing the others. Image replacement uses a delete-and-reinsert strategy: if you include the imagenes array, all existing images are deleted and the new list is inserted in their place. Files that were removed from the list are also deleted from disk. Variants are synchronized using an upsert: new combinations are inserted and existing ones are updated in place.
Request
Method:PUTPath:
/api/v1/admin/productos/:idContent-Type:
application/json
Path Parameter
The numeric ID of the product to update. Must match an existing product row.
Body Parameters
All fields are optional. Omitted fields retain their current database values.New display name for the product.
New product description. Pass
null explicitly to clear an existing description.New price in ARS. Must be a non-negative number if provided.
New category ID. Must reference an existing row in the
categorias table.Whether the product should be marked as featured.
Whether the product should be visible in the public store. Prefer the dedicated
/activar and /desactivar endpoints for toggling visibility alone.Complete replacement image list. When this field is present, all current images are deleted from the database and from disk (except those whose URL also appears in the new list), and the new list is inserted. When this field is omitted, existing images are left untouched.
Variant synchronization list. Uses
ON CONFLICT (producto_id, talle_id, color_id) DO UPDATE — existing combinations have their stock and activo updated; new combinations are inserted. Omitting this field leaves all existing variants unchanged.Variant Upsert Behavior
The variant sync uses PostgreSQL’sON CONFLICT clause targeting the unique constraint on (producto_id, talle_id, color_id):
- If the combination does not exist, a new row is inserted.
- If the combination already exists, only
stockandactivoare updated — theproducto_id,talle_id, andcolor_idremain unchanged. - Variants that exist in the database but are not included in the new
variantesarray are left untouched. To remove a variant, set itsstockto0andactivotofalse.
Image Update Behavior
When theimagenes field is provided:
- The controller first fetches all current image records for the product.
- Any image whose
urldoes not appear in the newimagenesarray is added to a deletion queue. - The model deletes all existing
producto_imagenesrows for the product and inserts the new list. - After the database transaction commits, the controller deletes the queued image files from disk using
fs.unlinkSync.
imagenes is omitted entirely, no images are touched.
Response
200 — Updated
Returns amensaje string and a producto object. The producto is the raw row from the productos table as returned by RETURNING * — not the enriched view object. Use GET /api/v1/admin/productos/:id to retrieve the full denormalized record after updating.
Human-readable confirmation string.
The updated raw row from the
productos table, returned by RETURNING *.Error Cases
| Status | Condition | Response body |
|---|---|---|
400 | id path parameter is not a valid number | {"mensaje": "El ID del producto debe ser un número válido"} |
400 | precio is provided but is negative or non-numeric | {"mensaje": "El precio debe ser un número positivo"} |
400 | imagenes is provided but is not an array | {"mensaje": "El campo \"imagenes\" debe ser un arreglo"} |
400 | An image object is missing its url | {"mensaje": "Cada imagen debe tener un campo \"url\" válido"} |
400 | variantes is provided but is not an array | {"mensaje": "El campo \"variantes\" debe ser un arreglo"} |
400 | A variant is missing talle_id or color_id | {"mensaje": "Cada variante debe tener \"talle_id\" y \"color_id\""} |
400 | A variant’s stock is negative | {"mensaje": "El stock de cada variante debe ser un número no negativo"} |
404 | No product exists with the given id | {"mensaje": "Producto no encontrado"} |
500 | Unexpected database or server error | {"mensaje": "Error al actualizar el producto"} |