Fluxos End-to-End

Ciclo de aprovação genérico

Como funciona o engine de aprovações que governa toda decisão financeira da plataforma

→ Conceito de Aprovações — leia primeiro se ainda não.

Anatomia de uma aprovação

1. Origem cria approval_request
   - entity_type: ex 'cotacao_decisao'
   - entity_id: id da cotação
   - entity_value: valor para casar com policy
   - metadata: dados extras (ex: vencedores_por_item)

2. Engine resolve a policy aplicável
   - filtra por organization_id, entity_type, condition
   - escolhe maior priority cuja condição casa

3. Cria assignments para o step 1
   - resolve aprovadores (role / user / dinâmico)
   - notifica aprovadores

4. Aprovadores acessam Painel → Aprovações
   - aprovam (avança step) ou rejeitam (encerra request)
   - delegação por ausência roteia para delegatário

5. Step completo → próximo step
   - se requires_all=true: todos do step precisam aprovar
   - se requires_all=false (default): qualquer um aprova

6. Todos os steps OK → request status='aprovado'
   - Engine dispara callback registrado
   - Callback atualiza entidade subjacente automaticamente

7. Auditoria
   - approval_audit_log registra cada ação
   - imutável — correção é evento compensatório

Entity types cobertos

Cada entity_type tem callback que atualiza a entidade:

Entity typeCallback aprovação
requisicao_compraRC.status = aprovada
cotacao_decisaoCria PO automaticamente + RC pedido_emitido + cotação decidida
pedido_compraPO.status = confirmado
contrato_empreitadaContrato.status = aprovado
recebimento_divergenteRecebimento aprovado + dispara entrada estoque
aditivo_contratoAditivo.status = aprovado (depois aplica manualmente)
liberacao_retencaomedição.retencao_liberada = true
medicao_empreiteiromedição.status = aprovada
suprimento_fundosfundo.status = aprovado
pagamentoCAP.status = pendente (pronto para pagar)
viabilidadeEVS.is_aprovado = true
baselineorçamento.is_baseline = true
documentodoc.status = aprovado
contrato_vendacontrato venda → pending (vai para assinatura)
distratodistrato.status = aprovado
alteracao_orcamentoorçamento atualizado
chamado_assistenciachamado avança fase
projeto_revisaorevisão aceita

Políticas

Settings → Aprovações & Compras → Políticas de Aprovação

Estrutura:

  • entity_type — qual tipo
  • condition_field (ex: "valor"), condition_operator (gt/gte/eq), condition_value (ex: 10000)
  • priority — quando há várias policies que casam, ganha a de maior priority
  • steps (jsonb array):
    [
      {"step_order":1, "label":"Gerente", "approver_type":"role", "approver_role_slug":"gerente-projetos"},
      {"step_order":2, "label":"Diretor", "approver_type":"role", "approver_role_slug":"diretor"}
    ]

Tipos de aprovador

  • role — qualquer usuário com aquele role na organização
  • user — usuário específico (caso especial)
  • dynamic — regra (ex: "gerente do projeto" — busca em project_members)

Delegação

Settings → Aprovações → Delegações

Configurável por:

  • Período (start_at / end_at)
  • Escopo: todos os entity_types ou subset
  • Empreendimentos específicos
  • Razão (auditoria)

Quando delegado tem aprovação atribuída via delegação, sistema marca delegated_to no assignment.

Escalação automática

Cada policy pode ter SLA (default 24h úteis). Aprovador parado por mais que isso:

  1. Recebe lembrete por email
  2. Após threshold (default 48h), assignment é escalado automaticamente para o role do nível acima
  3. Notifica gerente original e novo aprovador

Settings → Aprovações → Regras de Escalação

Regra de ouro: solicitante ≠ aprovador

Engine bloqueia automaticamente que solicitante seja também aprovador da mesma request. Se a alçada cair em si mesmo, escala para o nível acima.

Idempotência dos callbacks

Callbacks são idempotentes — uma re-execução não duplica. Por exemplo:

  • cotacao_decisao verifica se já há PO criada para a cotação antes de criar
  • gerar_entrada_compra_recebimento verifica se já há movimentos para o recebimento antes de criar

Isso protege contra retentativas em caso de erro de rede.

Auditoria

Toda decisão fica em approval_audit_log:

  • created — quando request criada
  • approved / rejected — quando assignment resolvido
  • delegated — quando delegado
  • escalated — quando escalado
  • expired — quando passou o threshold sem ação

Imutável. Correção é via evento compensatório (não exclusão).

On this page