This page lists the product routes of the client-facing gateway (apps/gateway), their access requirements, and how each one behaves in catalog mode.
Router: apps/gateway/src/routes/products.ts. Controller: ProductController from @ims/inventory (modules/inventory/src/products/infrastructure/controllers/Product.ts).
Authentication
| Item | Value |
|---|
| Header | Authorization: Bearer <token> (apps/gateway/src/middleware/authJWT.ts) |
| Token source | POST /org/token with an organization code (oc3.…) |
| Access type | standard or extended, carried in the token (req.auth.accessType) |
| Organization | organization_id claim (req.auth.orgId) |
| Missing or invalid token | 401 |
Routes
| Method and path | Controller method | Access | Catalog mode |
|---|
GET /products | getAllApi | any token | — |
GET /products/:id | getById | any token | — |
POST /products | createMany | extended | Applied (see below) |
PUT /products/:id | updateApi | any token; fields depend on access type | Never applied |
DELETE /products/:id | delete | extended | — |
extended is enforced by requireExtendedAccess (apps/gateway/src/middleware/requireExtendedAccess.ts):
| Status | Body |
|---|
403 | { "error": "This endpoint requires extended access" } |
GET /products
| Query | Default | Range |
|---|
page | 1 | ≥ 1 |
limit | 50 | 1–1000 |
PUT /products/:id
| Access type | Fields saved | Missing SKU |
|---|
standard | sku only; every other body key is ignored | 400 { "error": "Sin acceso extendido solo se puede actualizar el SKU" } |
extended | Every field in the body | Allowed |
| Rule | Value |
|---|
| Catalog mode | Not resolved. UpdateProductUseCase receives catalogMode: false |
| Name | Saved as sent; never generated |
| Required catalog fields | Not validated |
| SKU format | 400-class error when it contains / (InvalidSkuFormatError) |
| SKU taken | SkuConflictError when the SKU changes to one already in use; 409 on Prisma P2002 |
| Product not found | 404 (NotFoundError) |
| Success | 200 with the updated product |
"SKU missing" means sku is absent, not a string, or blank after trimming.
POST /products
Body: non-empty array of products. Handled by createMany → CreateProductsManyUseCase.
| Check | Response |
|---|
| Body not a non-empty array | 400 El cuerpo de la solicitud debe ser un arreglo no vacío de productos. |
| Duplicate first barcode in the batch | 400 La lista de productos contiene códigos de barras duplicados. |
| Barcode already used | 409 Los siguientes códigos de barras ya están asociados a otros productos: <values>. |
SKU contains / | 400 |
| Duplicate SKUs in the batch, or SKUs in use | Error from DuplicateSkuError |
| Success | 201 with the created products |
Catalog mode on POST /products
Catalog mode is resolved for the token organization (with partner inheritance for vendors).
| Product type | Catalog ON |
|---|
STOCK (or no type) | presentation, content (≥ 1), unit, categoryId, model are required; the name is always generated |
| KIT | Name generated only when name is empty |
Missing fields on any STOCK row fail the whole batch with 422 and a bulk MissingCatalogFieldsError message. See Product name generation.
DELETE /products/:id
Build dependency
The gateway imports @ims/inventory through its package entry point (modules/inventory/package.json: "main": "dist/index.js"). The gateway runs the compiled dist output of the module, not its TypeScript sources.