Retorno de step.step_requeriments_runtime_function

Introdução

O retorno da função step.step_requeriments_runtime_function é um array de objetos do tipo Requeriment que representam validações e bloqueios que impedem ou condicionam a movimentação de um card entre etapas. Cada requerimento indica um problema ou condição que deve ser satisfeita antes que o card possa avançar para a etapa de destino.

Os requerimentos são utilizados durante o processo de mudança de etapa para validar se todas as condições necessárias foram atendidas antes de permitir a movimentação do card.

Estrutura Básica

O retorno deve ser um array de objetos Requeriment:

[
  {
    code: ErrorCode,
    message: string,
    // campos adicionais dependendo do tipo de requerimento
  }
]

Retornando Requerimentos

Os requerimentos devem ser retornados como um array:

// Retornando um array de requerimentos
return [
  {
    code: 1, // ErrorCode.REQUIRED
    fieldName: 'approval_status',
    message: 'O campo de aprovação deve estar preenchido'
  },
  {
    code: 3, // ErrorCode.VALIDATE
    message: 'O documento deve estar aprovado antes de avançar'
  }
];

// Retornando array vazio (nenhum requerimento)
return [];

Referência de Requerimentos

Campos Base

Todos os requerimentos têm os seguintes campos base:

Parâmetro Tipo Obrigatório Descrição
key string Não Chave única do requerimento. Se não fornecido, o sistema gera automaticamente usando MD5 de ${code}-${message}
code ErrorCode Sim Código do tipo de erro/requerimento (número de 1 a 11)
message string Sim Mensagem descritiva do requerimento que será exibida ao usuário

Tipos de Requerimentos

1. Requerimento Genérico

Requerimento básico sem campos adicionais.

{
  code: ErrorCode,  // Qualquer código de ErrorCode
  message: string
}

Exemplo:

{
  code: 3, // ErrorCode.VALIDATE
  message: 'Validação customizada falhou'
}

2. Campo Obrigatório (REQUIRED)

Indica que um campo obrigatório não foi preenchido.

{
  code: ErrorCode.REQUIRED,  // 1
  fieldName: string,
  message: string
}

Parâmetros:

Parâmetro Tipo Obrigatório Descrição
code 1 Sim Deve ser ErrorCode.REQUIRED (1)
fieldName string Sim Nome do campo obrigatório que não foi preenchido
message string Sim Mensagem descritiva do requerimento

Exemplo:

{
  code: 1, // ErrorCode.REQUIRED
  fieldName: 'approval_status',
  message: 'O status de aprovação é obrigatório'
}

3. Campo Obrigatório em Etapa Específica (REQUIRED_ON_STEP)

Indica que um campo é obrigatório apenas em uma etapa específica.

{
  code: ErrorCode.REQUIRED_ON_STEP,  // 7
  fieldName: string,
  message: string
}

Parâmetros:

Parâmetro Tipo Obrigatório Descrição
code 7 Sim Deve ser ErrorCode.REQUIRED_ON_STEP (7)
fieldName string Sim Nome do campo obrigatório
message string Sim Mensagem descritiva do requerimento

Exemplo:

{
  code: 7, // ErrorCode.REQUIRED_ON_STEP
  fieldName: 'manager_signature',
  message: 'A assinatura do gerente é obrigatória nesta etapa'
}

4. Bloqueado por Automação (BLOCKED_BY_AUTOMATION)

Indica que o card está bloqueado por um processo de automação e não pode avançar até que o bloqueio seja resolvido.

{
  code: ErrorCode.BLOCKED_BY_AUTOMATION,  // 10
  message: string,
  linkToSolveStep: string
}

Parâmetros:

Parâmetro Tipo Obrigatório Descrição
code 10 Sim Deve ser ErrorCode.BLOCKED_BY_AUTOMATION (10)
message string Sim Mensagem explicando o bloqueio
linkToSolveStep string Sim PID da etapa que resolve o bloqueio. O sistema criará um link para esta etapa

Exemplo:

{
  code: 10, // ErrorCode.BLOCKED_BY_AUTOMATION
  message: 'Não é possível avançar: há automação pendente',
  linkToSolveStep: 'step-pid-que-resolve-automacao'
}

5. Link de Acesso (ACCESS_LINK)

Indica que é necessário acessar um link específico antes de avançar.

{
  code: ErrorCode.ACCESS_LINK,  // 11
  message: string,
  linkToSolveStep: string
}

Parâmetros:

Parâmetro Tipo Obrigatório Descrição
code 11 Sim Deve ser ErrorCode.ACCESS_LINK (11)
message string Sim Mensagem explicando o que precisa ser acessado
linkToSolveStep string Sim PID da etapa que contém o link de acesso necessário

Exemplo:

{
  code: 11, // ErrorCode.ACCESS_LINK
  message: 'É necessário acessar o link de aprovação antes de continuar',
  linkToSolveStep: 'step-pid-com-link-aprovacao'
}

Enum ErrorCode

O enum ErrorCode define todos os tipos de requerimentos disponíveis:

Código Nome Descrição
1 REQUIRED Campo obrigatório não preenchido
2 DEPENDENCY Dependência não satisfeita
3 VALIDATE Validação falhou
4 SUBCARD Subcard não satisfeito
5 STEP_REQUIRED Etapa obrigatória não completada
6 FORBIDDEN Acesso negado
7 REQUIRED_ON_STEP Campo obrigatório em etapa específica
8 STEP_BLOCKED Etapa bloqueada
9 PRIORITY_REQUIRED Prioridade obrigatória não definida
10 BLOCKED_BY_AUTOMATION Bloqueado por automação
11 ACCESS_LINK Link de acesso necessário

Geração Automática de key

Se um requerimento retornado não tiver o campo key, o sistema gera automaticamente uma chave usando MD5:

key = toMd5(`${code}-${message}`)

Isso garante que requerimentos com o mesmo código e mensagem tenham a mesma chave, evitando duplicatas.

Valores Padrão

Se a função retornar null, undefined ou lançar uma exceção, o sistema adiciona automaticamente um requerimento de erro:

{
  key: destinationStep.puca_pid,
  code: ErrorCode.VALIDATE,  // 3
  message: 'Erro ao chamar função de validação de requerimentos'
}

Exemplos de Uso

Exemplo 1: Validação Customizada (skip)

module.exports = async (req, comunicationService) => {
  const { card, entity, destinationStep } = req.data;
  
  const requeriments = [];
  
  // Validar se o campo "approval_status" está aprovado
  if (entity.approval_status !== 'approved') {
    requeriments.push({
      code: 3, // ErrorCode.VALIDATE
      message: 'O documento deve estar aprovado antes de avançar para esta etapa'
    });
  }
  
  // Validar se há saldo suficiente
  if (entity.balance < entity.minimum_balance) {
    requeriments.push({
      code: 1, // ErrorCode.REQUIRED
      fieldName: 'balance',
      message: `Saldo insuficiente. Mínimo requerido: ${entity.minimum_balance}`
    });
  }
  
  // Validar se o campo de assinatura está preenchido
  if (!entity.manager_signature) {
    requeriments.push({
      code: 7, // ErrorCode.REQUIRED_ON_STEP
      fieldName: 'manager_signature',
      message: 'A assinatura do gerente é obrigatória nesta etapa'
    });
  }
  
  return requeriments;
};

Exemplo 2: Adicionar Validações (override)

module.exports = async (req, comunicationService) => {
  const { entity, requeriments } = req.data;
  
  // Manter os requerimentos padrão do sistema
  const customRequeriments = [...requeriments];
  
  // Adicionar validação customizada
  if (entity.custom_field && entity.custom_field.length < 10) {
    customRequeriments.push({
      code: 3, // ErrorCode.VALIDATE
      message: 'O campo customizado deve ter pelo menos 10 caracteres'
    });
  }
  
  // Adicionar validação de formato
  if (entity.email && !entity.email.includes('@')) {
    customRequeriments.push({
      code: 3, // ErrorCode.VALIDATE
      message: 'O email deve ter um formato válido'
    });
  }
  
  return customRequeriments;
};

Exemplo 3: Bloqueio por Automação

module.exports = async (req, comunicationService) => {
  const { card, destinationStep } = req.data;
  
  const requeriments = [];
  
  // Verificar se há processo de automação pendente
  const hasPendingAutomation = await checkPendingAutomation(card.puca_pid);
  
  if (hasPendingAutomation) {
    requeriments.push({
      code: 10, // ErrorCode.BLOCKED_BY_AUTOMATION
      message: 'Não é possível avançar: há automação pendente',
      linkToSolveStep: 'step-pid-que-resolve-automacao'
    });
  }
  
  return requeriments;
};

Exemplo 4: Validação com Múltiplos Requerimentos

module.exports = async (req, comunicationService) => {
  const { card, entity, destinationStep, steps } = req.data;
  
  const requeriments = [];
  
  // Validar campos obrigatórios
  if (!entity.approval_status) {
    requeriments.push({
      code: 1, // ErrorCode.REQUIRED
      fieldName: 'approval_status',
      message: 'O status de aprovação é obrigatório'
    });
  }
  
  // Validar regra de negócio
  if (entity.total_amount > 10000 && !entity.manager_approval) {
    requeriments.push({
      code: 3, // ErrorCode.VALIDATE
      message: 'Valores acima de R$ 10.000 requerem aprovação do gerente'
    });
  }
  
  // Validar se etapa anterior foi completada
  const previousStepCompleted = await checkStepCompleted(card, steps);
  if (!previousStepCompleted) {
    requeriments.push({
      code: 5, // ErrorCode.STEP_REQUIRED
      message: 'A etapa anterior deve ser completada antes de avançar'
    });
  }
  
  // Validar acesso a link externo
  if (destinationStep === 'step-requiring-external-link') {
    requeriments.push({
      code: 11, // ErrorCode.ACCESS_LINK
      message: 'É necessário acessar o link de aprovação externa antes de continuar',
      linkToSolveStep: 'step-pid-com-link-externo'
    });
  }
  
  return requeriments;
};

Exemplo 5: Usar Key Customizada

module.exports = async (req, comunicationService) => {
  const { entity } = req.data;
  
  const requeriments = [];
  
  // Usar key customizada para garantir controle sobre duplicatas
  if (entity.balance < 0) {
    requeriments.push({
      key: 'negative-balance-validation',
      code: 3, // ErrorCode.VALIDATE
      message: 'O saldo não pode ser negativo'
    });
  }
  
  // Outro requerimento com key customizada
  if (!entity.required_document) {
    requeriments.push({
      key: 'missing-required-document',
      code: 1, // ErrorCode.REQUIRED
      fieldName: 'required_document',
      message: 'O documento obrigatório não foi anexado'
    });
  }
  
  return requeriments;
};

Exemplo 6: Retornar Array Vazio (Nenhum Requerimento)

module.exports = async (req, comunicationService) => {
  const { entity } = req.data;
  
  // Se todas as validações passaram, retornar array vazio
  if (entity.approval_status === 'approved' && 
      entity.balance >= entity.minimum_balance &&
      entity.manager_signature) {
    return []; // Nenhum requerimento, pode avançar
  }
  
  // Caso contrário, retornar requerimentos
  const requeriments = [];
  
  if (entity.approval_status !== 'approved') {
    requeriments.push({
      code: 3,
      message: 'O documento deve estar aprovado'
    });
  }
  
  return requeriments;
};

Comportamentos

Comportamento skip

Quando step.step_requeriments_function_behavior === 'skip':

  • O sistema não calcula requerimentos padrão
  • A função recebe requeriments: [] (array vazio) no request.body
  • Apenas os requerimentos retornados pela função são considerados
  • Útil quando você quer ter controle total sobre as validações

Comportamento override

Quando step.step_requeriments_function_behavior === 'override':

  • O sistema primeiro calcula os requerimentos padrão (campos obrigatórios, dependências, etc.)
  • A função recebe os requerimentos calculados no campo requeriments do request.body
  • A função pode adicionar novos requerimentos, modificar existentes ou remover alguns
  • Os requerimentos retornados são mesclados com os requerimentos padrão
  • Útil quando você quer adicionar validações customizadas além das padrão