API industrial

Prefixo /api, headers de tenant, rotas de lote, ATP, OP, recall, doação e Central — com query params e corpos.

Base: {API}/api (HML local típico: http://localhost:5001/api). Swagger na própria API autenticada.

Headers

HeaderQuando
Authorization: Bearersempre
x-company-idsempre na operação; obrigatório em POST de recall/doação se o JWT não tiver empresa
x-filial-idsempre na operação de estoque/OP/NF
Content-Type: application/jsonPOST/PATCH

IDs de filial, empresa e lote na URL são Hashids do ERP, não o inteiro interno — exceto onde a resposta FEFO devolve lotId numérico para o breakdown da OP.

Disponibilidade (ATP)

GET /inventory/availability/{productCode}?filialId={filialId}&locationCode=001
GET /inventory/availability/{productCode}/atp?filialId={filialId}&locationCode=001

A rota /atp está registrada antes de /:productCode para o Nest não tratar atp como código de produto.

DTO relevante:

CampoSignificado
physical_stockúltimo FAPOB
reserved_stockFARES01 ACTIVE
unavailable_lot_stockQUARANTINE / EXPIRED / BLOCKED / RECALLED
available_stockse há FALOT01: ACTIVE não vencidos − reserva; senão razão − reserva − indisponível
incoming_stockNF CREATED ainda não confirmada
atpavailable_stock + incoming_stock

POST /inventory/availability/bulk — { "filialId", "productCodes": [] } — mesma fórmula.

Lotes

GET    /product-lot/{filialId}?productCode=&status=&expiringSoon=true&page=1&limit=20
GET    /product-lot/{filialId}/by-code/{lotCode}
GET    /product-lot/detail/{id}
GET    /product-lot/{filialId}/fefo/{productCode}?quantity=986&locationCode=001
GET    /product-lot/{filialId}/summary/{productCode}
GET    /product-lot/{filialId}/qa
GET    /product-lot/{filialId}/expiring?days=30
POST   /product-lot/{filialId}/expire
POST   /product-lot/{id}/quarantine
POST   /product-lot/{id}/release
POST   /product-lot/{id}/block
GET    /product-lot/trace/{id}/backward?limit=&offset=
GET    /product-lot/trace/{id}/forward?limit=&offset=
PATCH  /product-lot/{id}          # validade/local — não status

FEFO preview não abate. quantity obrigatória e > 0. Sem lote ACTIVE suficiente → 400 Estoque insuficiente nos lotes do produto {code}. Faltam: N.

POST …/expire marca ACTIVE com expiration_date < hoje como EXPIRED. Não há cron ainda.

Ordem de produção

POST /production-order/{filialId}
POST /production-order/release/{id}
POST /production-order/start/{id}
POST /production-order/report/{id}
POST /production-order/complete/{id}
POST /production-order/cancel/{id}
GET  /production-order/{filialId}?status=&productCode=

Report com consumo por lote: ver Operação. consumptions[].reason obrigatório em LOSS.

BOM vigente: GET /bom/{filialId}/active/{productCode}.

Recall e doação

GET  /lot-recall/impact/{lotId}
GET  /lot-recall/{filialId}
GET  /lot-recall/detail/{id}
POST /lot-recall/{filialId}
POST /lot-recall/{id}/close

GET  /lot-donation/{filialId}
GET  /lot-donation/detail/{id}
POST /lot-donation/{filialId}
POST /lot-donation/{id}/cancel

Bodies em Qualidade. Flag OFF → 400 no POST de criação.

Central

GET /industrial/dashboard/{filialId}

Só leitura. omitted lista seções sem fonte (ex.: opsBlockedQa). Campos de produção/perda do dia só present quando há movimento no dia.

Flags

GET  /feature-flags
GET  /feature-flags/tenant-overrides
POST /feature-flags/tenant-override

Detalhe em Flags.

NF de entrada

O contrato de create/confirm é o de documento de entrada já existente. No item:

CampoUso industrial
lotCode / nLotecódigo do lote
expirationDate / dValvalidade
manufactureDate / dFabfabricação
storeLocationCodedepósito

Confirm é o que cria FALOT01 e o lot_id no FAPOB.

Exemplo curl (ATP)

curl -s -H "Authorization: Bearer $TOKEN" \
  -H "x-company-id: $COMPANY" \
  -H "x-filial-id: $FILIAL" \
  "$API/inventory/availability/HML-IND-PAO/atp?filialId=$FILIAL&locationCode=001"

Esperado com lote ACTIVE 180 UN: { "productCode": "HML-IND-PAO", "atp": 180 }.