Skip to content

API — Fichas Técnicas (BOM)

Autenticação

Todos os endpoints requerem JWT com role admin ou superadmin e permissão manage_inventory.

Base: /t/:slug/bom


GET /t/:slug/bom

Lista todos os itens do cardápio com o custo atual (último snapshot).

Response 200:

json
[
  {
    "menuItemId": "...",
    "name": "Filé ao Molho",
    "sellingPrice": 8500,
    "latestSnapshot": {
      "totalDirectCost": 3200,
      "totalIndirectCost": 480,
      "totalCostPerUnit": 3680,
      "triggeredBy": "nfe_import",
      "createdAt": "2026-04-02T10:00:00.000Z"
    },
    "marginPercent": 56.7
  }
]

GET /t/:slug/bom/:menuItemId

Retorna o detalhe completo do BOM de um item: ingredientes, custos indiretos e último snapshot.

Response 200:

json
{
  "menuItem": { "_id": "...", "name": "Filé ao Molho", "price": 8500 },
  "ingredients": [
    {
      "inventoryItemId": "...",
      "inventoryItemName": "Filé Mignon",
      "quantityPerUnit": 0.3,
      "unit": "kg",
      "currentCostPrice": 12000,
      "lineCost": 3600
    }
  ],
  "indirectCosts": [
    { "_id": "...", "type": "packaging", "label": "Embalagem descartável", "valuePerUnit": 150, "unitType": "fixed" },
    { "_id": "...", "type": "labor", "label": "Mão de obra", "valuePerUnit": 0.12, "unitType": "percentage_of_direct" }
  ],
  "latestSnapshot": {
    "totalDirectCost": 3600,
    "totalIndirectCost": 582,
    "totalCostPerUnit": 4182,
    "suggestedSellingPrice": null,
    "triggeredBy": "nfe_import",
    "ingredientSnapshot": [...],
    "createdAt": "2026-04-02T10:00:00.000Z"
  }
}

POST /t/:slug/bom/:menuItemId/calculate

Recalcula o custo e gera um novo BomCostSnapshot.

Body:

json
{
  "targetMargin": 0.60
}
CampoTipoObrigatórioDescrição
targetMarginnumberNãoMargem desejada 0–0.99 (ex: 0.60 = 60%). Gera suggestedSellingPrice.

Response 201:

json
{
  "_id": "...",
  "menuItem": "...",
  "totalDirectCost": 3600,
  "totalIndirectCost": 582,
  "totalCostPerUnit": 4182,
  "suggestedSellingPrice": 10455,
  "targetMargin": 0.60,
  "triggeredBy": "manual",
  "ingredientSnapshot": [...],
  "indirectSnapshot": [...],
  "createdAt": "2026-04-02T11:00:00.000Z"
}

GET /t/:slug/bom/:menuItemId/history

Retorna o histórico de snapshots de custo (mais recentes primeiro).

Query params:

ParamTipoDescrição
limitnumberMáximo de snapshots (padrão 20)

Response 200:

json
[
  { "_id": "...", "totalCostPerUnit": 4182, "triggeredBy": "nfe_import", "createdAt": "2026-04-02T10:00:00.000Z" },
  { "_id": "...", "totalCostPerUnit": 3950, "triggeredBy": "manual", "createdAt": "2026-03-15T08:00:00.000Z" }
]

POST /t/:slug/bom/indirect-costs

Cria um custo indireto para um item do cardápio.

Body:

json
{
  "menuItemId": "...",
  "type": "packaging",
  "label": "Embalagem descartável",
  "valuePerUnit": 0.50,
  "unitType": "fixed"
}
CampoTipoObrigatórioDescrição
menuItemIdstringSimID do item do cardápio
typestringSimlabor | energy | packaging | other
labelstringSimDescrição
valuePerUnitnumberSimValor fixo (R$) ou fração (0.15 = 15%)
unitTypestringSimfixed | percentage_of_direct

Response 201: BomIndirectCost criado.


PUT /t/:slug/bom/indirect-costs/:id

Atualiza um custo indireto.

Body: Campos parciais do POST.

Response 200: Objeto atualizado.


DELETE /t/:slug/bom/indirect-costs/:id

Remove um custo indireto.

Response 200: { "deleted": true }


Relacionados

Lançado sob a licença MIT.