Pular para o conteúdo

Catálogo (catalog)

O recurso catalog oferece leitura e escrita dos quatro tipos de catálogo. Cada tipo tem seus próprios identificadores: informe também o tipo ao usar um componente em um combo.

Acesso Valor
Módulo catalogo
Leitura catalog:read
Escrita catalog:write, com plano que permita escrita

items, products, services, combos, categories e subcategories aceitam os mesmos métodos básicos:

Método Caminho Resultado
GET /v1/catalog/{recurso} Lista paginada
POST /v1/catalog/{recurso} Cria, com resposta 201
GET /v1/catalog/{recurso}/{id} Consulta um registro
PATCH /v1/catalog/{recurso}/{id} Atualiza campos informados
DELETE /v1/catalog/{recurso}/{id} Arquiva, com resposta 204

Itens, produtos, serviços e combos arquivados deixam de aparecer nas leituras e conservam as referências de vendas e composição. Categorias e subcategorias ficam com is_active: false e podem ser reativadas via PATCH. Os recursos products e services conservam seus contratos anteriores.

Os quatro tipos exigem name e selling_price. items também exige cost_price e unit. Imagem e fornecedor são opcionais. Campos da equipe, autoria, histórico, estoque atual e caminhos de arquivo são determinados pelo servidor.

{
"name": "Insumo A",
"unit": "un",
"cost_price": 8.5,
"selling_price": 15,
"manages_stock": true
}

Para preço variável, envie is_variable_price: true e selling_price: 0. Use min_price e max_price para a faixa, ou omita-os para preço sob consulta. O máximo não pode ser menor que o mínimo. Consumidores devem apresentar a faixa ou “sob consulta”; selling_price: 0 representa a convenção de armazenamento desse tipo de preço.

{
"name": "Serviço sob avaliação",
"selling_price": 0,
"is_variable_price": true,
"min_price": 80,
"max_price": 120,
"duration_minutes": 60
}

category_id e subcategory_id devem pertencer à equipe da chave. Uma subcategoria deve pertencer à categoria informada. Categorias inativas não podem ser usadas em novos vínculos.

Método Caminho
GET, PUT /v1/catalog/products/{id}/composition
GET, PUT /v1/catalog/combos/{id}/composition

PUT substitui a composição completa. Use composition: [] para removê-la. Produtos usam componentes de items, com quantidade positiva inclusive fracionária:

{
"composition": [
{ "item_id": "00000000-0000-4000-8000-000000000001", "quantity": 0.5, "is_removable": true }
]
}

Combos usam catalog_type (item, product ou service), catalog_item_id e quantidade inteira positiva. Não pode haver componente repetido. Os componentes devem estar ativos na mesma equipe. A criação de produto ou combo também aceita composition no corpo; tudo é salvo na mesma transação. is_composite é calculado a partir da composição.

/v1/catalog/items/{id}/suppliers aceita GET e POST; o caminho com o identificador da associação aceita GET, PATCH e DELETE. Para vincular, informe supplier_id. Campos opcionais incluem supplier_code, unit_cost, min_order_quantity, lead_time_days, is_preferred, priority e notes.

O fornecedor deve estar ativo na equipe. Definir um preferencial desmarca os outros na mesma transação. DELETE desativa a associação. A criação de um item também aceita um array suppliers; uma associação inválida cancela o cadastro inteiro.

Os quatro tipos aceitam GET e POST em /v1/catalog/{tipo}/{id}/images, e GET, PATCH, DELETE no caminho com o identificador da imagem. O envio aceita JPEG, PNG ou WebP, até 5 MiB, com conteúdo em base64:

{
"file_type": "image/png",
"content_base64": "<conteúdo do arquivo em base64>",
"is_primary": true,
"display_order": 0
}

O servidor verifica formato, cota e equipe, cria o caminho no Storage e atualiza a imagem principal. PATCH aceita apenas is_primary e display_order. Excluir a associação atualiza a imagem principal; os bytes permanecem armazenados para preservar referências existentes. Se o banco recusar o cadastro após o envio, o arquivo recém-enviado é removido. Se a confirmação do cadastro falhar por comunicação, a API responde 503 e preserva os bytes para conferência do resultado.

Todas as listas usam limit (1 a 100; padrão 50), ordenação fixa por UUID e after. A resposta informa pagination.after, has_more e limit. Enquanto has_more for true, repita a chamada com after=<pagination.after>. O catálogo usa esse cursor também nas listas de composição, fornecedores e imagens.

Campos e relacionamentos inválidos respondem 422; recurso ou pai ausente na equipe responde 404; falta de escopo ou autorização responde 403. A referência OpenAPI descreve os campos de cada tipo.