Flags industriais
As seis flags industrial.* — default OFF, override por tenant, o que cada uma muda no fluxo e o que permanece igual no catálogo comercial.
Nenhuma flag industrial deve ser ligada no global de produção. O global vale para todos os tenants. Use override por empresa.
Caminho no ERP: /apps/feature-flags → aba de overrides por tenant. A tela é de administração da plataforma (saas-admin). Pela API, o mesmo efeito é POST /feature-flags/tenant-override.
Contrato do override
| Campo | Obrigatório | Função |
|---|---|---|
companyId | sim | Empresa alvo (Hashid). Não é a filial. |
key | sim | Chave exata da tabela abaixo |
enabled | sim | true liga, false desliga neste tenant |
reason | recomendado | Auditoria; o histórico é append-only |
expiresAt | não | ISO-8601; depois disso o override deixa de valer |
Revogar não apaga a linha: o sistema grava um override novo com o valor inverso (enabled: false). Listagem: GET /feature-flags/tenant-overrides (só ativos).
As seis chaves
Todas existem no seed da API com enabled: false.
industrial.lot-enforcement
Fases 2–3. Confirmação e importação de NF de entrada: se o produto tem lotControl, o item precisa de lote; se tem expirationControl, precisa de validade. Saídas passam a escolher lote (FEFO ou lote informado). Reserva da OP pode gravar lot_id.
Desligada: o catálogo comercial (SKU sem lotControl) permanece no path antigo. SKU com lotControl ainda pode gravar lote na NF se o usuário preencher; a flag só obriga.
industrial.production-lot-consumption
Fase 5. Apontamento da OP (POST /production-order/report/:id) exige breakdown por lote (consumptions[].lotId), cria o lote do produto acabado e grava genealogia (FALOT02).
Desligada: consumo proporcional legado (divide o BOM pelo produzido, sem lote).
industrial.mass-balance.enforce
Fase 6. POST /production-order/complete/:id recusa se o rendimento ou o consumo vs previsto sair da yieldTolerancePercent do BOM (padrão 5%). Perda exige motivo. Não gera movimento ADJUSTMENT.
Desligada: complete não bloqueia por tolerância. O painel de balanço na OP continua visível.
industrial.quality.inbound-quarantine
Fase 8. NF com lotControl cria o lote já em QUARANTINE. O saldo existe no razão, mas some do ATP e do FEFO até POST /product-lot/:id/release.
Desligada: lote da NF nasce ACTIVE. Quarentena continua disponível pelo POST manual.
industrial.recall.enabled
Fase 9. POST /lot-recall/:filialId abre campanha, congela a genealogia em RECALLED. Simulação GET /lot-recall/impact/:lotId funciona com a flag OFF.
Encerrar a campanha não libera o lote.
industrial.donation.enabled
Fase 10. POST /lot-donation/:filialId baixa estoque com origem DONATION. Listagem GET funciona com a flag OFF. Não use ajuste FAAJ01 para doar lote.
Ordem recomendada no tenant da padaria
1. Cadastro
Só os SKUs da linha com lotControl (e validade se houver prazo). O restante do catálogo fica de fora.
2. Enforcement
Ligar industrial.lot-enforcement. Conferir uma NF de entrada e uma saída FEFO.
3. Consumo da OP
Ligar industrial.production-lot-consumption. Apontar uma OP com breakdown real.
4. Balanço
Calibrar a tolerância do BOM. Só então industrial.mass-balance.enforce.
5. Recall e doação
Quando o processo existir. Simular o impacto do recall antes de ligar a campanha.
6. Quarentena na entrada
Por último, depois de treinar QA. É a que mais assusta o estoque.
Headers em toda chamada
GET /feature-flags devolve o global. O que vale na operação é isEnabled(key, companyId) = override do tenant se existir e não tiver expirado; senão o global.
Desligar o laboratório
Repita para as seis chaves. Os lotes e NFs já gravados permanecem; só o enforcement para de aplicar.
