Products
PPE products, with their sizes and certificates — full CRUD.
List products
List products
Create a product
Creates a product, optionally with nested `sizes` and `certificates` (created in the same transaction). On success the `ETag` header carries the new record's version and `Location` points at the new resource.
Get a product by id
Get a product by id
Update a product
Partial update. Send the current version via the `If-Match` header (preferred; from the `ETag` of a prior read) or the body `_version`. Missing → `400`; stale → `409`. Nested `sizes`/`certificates` are upserted by their `id` (omit `id` to add a new one).
Delete a product
Soft-deletes the product and returns the deleted record. The product's sizes and certificates are removed in the same cascade. Send the current version via the `If-Match` header (preferred; from the `ETag` of a prior read) or the `_version` query param. Missing → `400`; stale → `409`.