> ## Documentation Index
> Fetch the complete documentation index at: https://docs.domsoftware.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Catálogo de Produtos

> Gerenciamento de produtos, variações, kits e custos no OmniDom.

## Visão geral

O catálogo é o núcleo do OmniDom. Cada produto tem:

* **Tipo** (`SIMPLE`, `KIT`, `MANUFACTURED`) que define seu comportamento de estoque.
* **Variações** (cor, tamanho) com atributos e preços próprios.
* **Componentes** (apenas para `KIT`/`MANUFACTURED`) — lista de produtos simples que compõem o item.
* **Custo calculado** — para kits, o custo é a soma ponderada dos componentes.

<Tip>
  Use o tipo `KIT` para produtos compostos vendidos como um único item. O estoque é deduzido dos componentes individuais a cada venda confirmada.
</Tip>

***

## Tipos de produto

| Tipo           | Estoque próprio | Componentes | Uso típico                     |
| -------------- | --------------- | ----------- | ------------------------------ |
| `SIMPLE`       | ✅               | ❌           | Produto avulso                 |
| `KIT`          | ❌               | ✅           | Combo / bundle                 |
| `MANUFACTURED` | Opcional        | ✅           | Produto fabricado internamente |

***

## Endpoints de produtos

### Listar produtos

```http theme={null}
GET /products
```

**Query params:**

| Parâmetro    | Tipo    | Descrição                                          |
| ------------ | ------- | -------------------------------------------------- |
| `page`       | number  | Página (padrão: 1)                                 |
| `limit`      | number  | Registros por página (padrão: 20, max: 100)        |
| `search`     | string  | Busca em nome comercial e SKU                      |
| `type`       | string  | Filtrar por tipo (`SIMPLE`, `KIT`, `MANUFACTURED`) |
| `isActive`   | boolean | Filtrar por status ativo/inativo                   |
| `categoryId` | UUID    | Filtrar por categoria                              |

***

### Criar produto

```http theme={null}
POST /products
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "commercialName": "Camiseta Branca P",
  "sku": "CAM-BCO-P",
  "type": "SIMPLE",
  "price": 49.90,
  "costPrice": 18.00,
  "minStock": 5,
  "categoryId": "uuid-da-categoria",
  "description": "Camiseta 100% algodão"
}
```

| Campo            | Tipo   | Obrig. | Descrição                              |
| ---------------- | ------ | ------ | -------------------------------------- |
| `commercialName` | string | ✅      | Nome exibido nos anúncios              |
| `sku`            | string | ✅      | Código único por tenant                |
| `type`           | enum   | ✅      | `SIMPLE`, `KIT` ou `MANUFACTURED`      |
| `price`          | number | ✅      | Preço de venda                         |
| `costPrice`      | number |        | Custo unitário (relevante para SIMPLE) |
| `minStock`       | number |        | Estoque mínimo para alertas            |
| `categoryId`     | UUID   |        | Categoria do produto                   |

***

### Detalhar produto

```http theme={null}
GET /products/:id
```

Retorna o produto com variações e, se for kit, a lista de componentes inclusa.

***

### Atualizar produto

```http theme={null}
PATCH /products/:id
Content-Type: application/json
```

Aceita os mesmos campos do `POST /products`. Apenas os campos enviados são atualizados.

***

### Excluir produto

```http theme={null}
DELETE /products/:id
```

**Soft delete** — o produto é marcado como inativo. Não pode ser excluído se tiver estoque positivo ou anúncios ativos.

***

## Variações

Produtos do tipo `SIMPLE` podem ter variações (ex: cor + tamanho). Cada variação tem seu próprio SKU, preço e estoque.

### Listar variações

```http theme={null}
GET /products/:productId/variations
```

***

### Criar variação

```http theme={null}
POST /products/:productId/variations
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "sku": "CAM-BCO-M",
  "price": 49.90,
  "attributes": [
    { "name": "Cor", "value": "Branco" },
    { "name": "Tamanho", "value": "M" }
  ]
}
```

***

## Componentes (Kits)

Somente produtos `KIT` ou `MANUFACTURED` têm componentes. Um componente é sempre um produto `SIMPLE`.

<Warning>
  Kits aninhados não são permitidos — você não pode adicionar um `KIT` como componente de outro `KIT`.
</Warning>

### Listar componentes

```http theme={null}
GET /products/:productId/components
```

Retorna os componentes com paginação por cursor (keyset pagination). Máximo de 500 por requisição.

**Query params:**

| Parâmetro | Tipo   | Descrição                    |
| --------- | ------ | ---------------------------- |
| `cursor`  | string | Cursor base64 para paginação |
| `limit`   | number | Máximo: 500                  |

**Resposta:**

```json theme={null}
{
  "data": [
    {
      "id": "comp-uuid",
      "componentId": "product-uuid",
      "quantity": 2,
      "lossPercentage": 5,
      "isMainItem": true,
      "displayInDescription": true,
      "affectsPrice": true,
      "unitCostSnapshot": 10.50,
      "component": {
        "id": "product-uuid",
        "commercialName": "Resistor 10k",
        "sku": "RES-10K",
        "price": 5.25
      }
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTAxLTAxIiwiaWQiOiJ1dWlkIn0=",
  "hasMore": false
}
```

***

### Adicionar componente

```http theme={null}
POST /products/:productId/components
Content-Type: application/json
```

**Body:**

```json theme={null}
{
  "componentId": "uuid-do-produto-simples",
  "quantity": 2,
  "lossPercentage": 5,
  "isMainItem": true,
  "displayInDescription": true,
  "affectsPrice": true
}
```

| Campo                  | Tipo    | Descrição                                      |
| ---------------------- | ------- | ---------------------------------------------- |
| `componentId`          | UUID    | ID do produto `SIMPLE` a adicionar             |
| `quantity`             | number  | Quantidade usada por unidade do kit            |
| `lossPercentage`       | number  | Perda esperada em % (ex: `5` = 5%)             |
| `isMainItem`           | boolean | Indica se é o item principal do kit            |
| `displayInDescription` | boolean | Exibir componente na descrição do anúncio      |
| `affectsPrice`         | boolean | Inclui custo do componente no cálculo de preço |

***

### Atualizar componente

```http theme={null}
PUT /products/:productId/components/:componentId
Content-Type: application/json
```

***

### Remover componente

```http theme={null}
DELETE /products/:productId/components/:componentId
```

***

## Custo do produto

```http theme={null}
GET /products/:productId/cost-summary
```

Retorna um snapshot do custo calculado do produto. Para kits, o cálculo é recursivo com base nos componentes.

<Note>
  Este endpoint usa cache. Alterações em componentes ou estoque podem levar alguns segundos para refletir (Eventual Consistency).
</Note>

**Resposta:**

```json theme={null}
{
  "productId": "uuid",
  "type": "KIT",
  "totalCost": 32.50,
  "components": [
    {
      "componentId": "uuid",
      "name": "Resistor 10k",
      "sku": "RES-10K",
      "quantity": 2,
      "unitCost": 10.50,
      "totalCost": 21.00,
      "lossPercentage": 5
    }
  ]
}
```
