Formulários
Formulários são as telas de entrada de dados que a plataforma exibe dentro de uma tarefa, ou antes de iniciar uma instância. Cada tarefa de um processo pode ter um formulário diferente, com campos e regras específicos para aquela etapa.
Esta página cobre três coisas, nesta ordem: preencher um formulário, montar um no construtor visual e substituir o formulário da plataforma por um plugin próprio.
Como preencher um formulário (visão do usuário)
- Abra uma tarefa (em Tarefas, na barra lateral)
- O formulário da tarefa é exibido automaticamente dentro do painel da tarefa
- Preencha os campos conforme as instruções — campos obrigatórios estão marcados com
* - Clique em Enviar para concluir a tarefa; as respostas viram variáveis de processo automaticamente
TIP
A versão do formulário exibida é a que estava publicada no momento em que a tarefa foi criada. Atualizações posteriores no formulário não afetam tarefas já abertas.
Construtor visual de formulários (admin)
Administradores criam e editam formulários dentro da definição do processo, em Modelagem → Catálogo de Processos → o processo → aba Formulários, usando o construtor visual drag & drop. A barra lateral não traz um item Formulários: o formulário pertence ao processo que o usa.
Interface do construtor
O construtor tem três painéis:
| Painel | Função |
|---|---|
| Esquerda — Paleta | Tipos de campo agrupados por categoria; clique para adicionar ao formulário |
| Centro — Canvas / Pré-visualização | Lista de campos em ordem; arraste para reordenar; aba "Pré-visualização" mostra a renderização real |
| Direita — Propriedades | Configurações do campo selecionado |
Tipos de campo disponíveis
| Grupo | Tipo | Descrição |
|---|---|---|
| Texto | text | Texto curto livre |
| Texto | textarea | Texto longo multilinha |
| Texto | email | Endereço de e-mail (validação automática) |
| Texto | phone | Telefone |
| Texto | url | Endereço web (URL) |
| Texto | password | Credencial digitada na tarefa — ver Campo de senha, abaixo |
| Numérico | number | Valor numérico |
| Numérico | currency | Valor monetário (R$) |
| Numérico | percentage | Percentual (%) |
| Numérico | slider | Valor numérico escolhido numa régua |
| Data/Hora | date | Seletor de data |
| Data/Hora | datetime | Seletor de data e hora |
| Data/Hora | time | Seletor de horário |
| Data/Hora | date-range | Intervalo de datas (data inicial e final) |
| Documentos BR | cpf | CPF (máscara automática) |
| Documentos BR | cnpj | CNPJ (máscara automática) |
| Documentos BR | cep | CEP (máscara automática) |
| Escolha | select | Dropdown com opções fixas |
| Escolha | multiselect | Seleção múltipla |
| Escolha | radio | Opções únicas (radio buttons) |
| Escolha | checkbox | Múltiplos checkboxes |
| Escolha | boolean | Sim / Não |
| Escolha | switch | Liga/desliga em forma de interruptor |
| Busca | lookup | Busca paginada em API externa (digitação live) |
| Arquivo | file | Upload de arquivo (configurável: tipos aceitos, múltiplos) |
| Avaliação | rating | Avaliação por estrelas — 5 por padrão, configurável até 10 |
| Layout | heading | Título de seção (H2/H3/H4) |
| Layout | separator | Separador horizontal |
| Layout | md-viewer | Exibe conteúdo em Markdown — não coleta dado |
Campo de senha
O tipo Senha existe para credencial que a pessoa digita durante o processo. Ele muda quatro coisas em relação a um campo de texto comum:
- é exibido mascarado, e o navegador não guarda o valor em preenchimento automático;
- o valor não aparece nas telas que mostram variáveis do processo — nem na instância, nem nas variáveis da tarefa, nem na busca;
- o valor não chega à IA: um agente que leia aquele processo recebe o identificador do campo, não o conteúdo;
- o valor é gravado cifrado, deixa de existir entre as variáveis da instância quando ela termina, e é apagado do histórico sete dias depois.
O tipo é a marca
Um campo de texto chamado senha não ganha nada disso. A plataforma não adivinha pelo nome — adivinhar erra nos dois sentidos, deixando passar credencialErp e escondendo senhaDoWifiDaSala. Escolha o tipo Senha.
Como o valor é guardado
Em uma frase: a senha é gravada cifrada, deixa de existir entre as variáveis da instância quando ela termina, e é apagada do histórico sete dias depois — prazo que quem administra a instalação pode alterar. O passo seguinte do processo continua lendo o valor normalmente: um ${senhaErp} numa configuração de tarefa de serviço funciona como sempre funcionou; quem vê a senha em claro é só o motor, no momento em que ela é usada.
O que a cifra não resolve
A chave que cifra é a mesma chave da instalação (APP_ENCRYPTION_KEY). Ela protege contra um dump do banco, uma réplica ou um backup que vaze — não contra alguém que já tenha a chave da aplicação. Guarde essa chave com o mesmo cuidado que guardaria as senhas.
Uma senha só é gravada cifrada quando o campo é do tipo Senha. Se um passo do processo gravar aquela variável de novo por conta própria, o valor volta a ser texto comum — quem modela precisa saber disso.
O corpo do formulário não vai para o log
O registro de requisições da plataforma nunca escreve o corpo enviado por um formulário, em nenhuma rota, nem quando o envio falha. Um erro de validação continua aparecendo no log com método, caminho, status e a resposta que explica o problema — mas sem o que foi digitado.
Propriedades gerais de cada campo
| Propriedade | Descrição |
|---|---|
| Rótulo | Texto exibido acima do campo |
| Chave (key) | Identificador único — vira o nome da variável de processo ao submeter |
| Tipo | Tipo de campo (veja tabela acima) |
| Largura | 100% / ½ / ⅓ / ¼ — controla a coluna no grid responsivo |
| Obrigatório | Marca o campo como obrigatório na validação |
| Placeholder | Texto de exemplo dentro do input |
| Instrução / Ajuda | Texto descritivo exibido abaixo do rótulo |
Grid responsivo
O formulário usa CSS Grid com até 4 colunas. A propriedade Largura de cada campo define quantas colunas ele ocupa:
| Largura | Colunas | Visual |
|---|---|---|
full | linha inteira | Ocupa toda a largura |
half | 2/4 | Metade da linha |
third | 1/3 | Um terço da linha |
quarter | 1/4 | Um quarto da linha |
Em telas pequenas (mobile), todos os campos ocupam a largura total independentemente da configuração.
Regras condicionais
Cada campo pode ter uma ou mais regras condicionais configuradas no painel de propriedades. Uma regra define:
| Propriedade | Descrição |
|---|---|
| Ação | O que acontece quando a condição é verdadeira |
| Campo observado | Qual outro campo é monitorado |
| Operador | Como comparar o valor (=, ≠, contém, vazio, não vazio, >, <) |
| Valor | Valor a comparar (não necessário para vazio/não vazio) |
Ações disponíveis
| Ação | Efeito |
|---|---|
Mostrar este campo | Campo fica visível quando a condição for verdadeira (padrão: oculto) |
Ocultar este campo | Campo fica oculto quando a condição for verdadeira |
Habilitar este campo | Campo fica editável quando a condição for verdadeira |
Desabilitar este campo | Campo fica bloqueado quando a condição for verdadeira |
Tornar obrigatório | Campo vira obrigatório quando a condição for verdadeira |
Carregar opções de API | Disponível apenas para campos de escolha (select, multiselect, radio, checkbox). Carrega as opções a partir de uma URL, substituindo {value} pelo valor do campo observado |
WARNING
Se um campo tiver regra Tornar obrigatório, o checkbox estático "Obrigatório" fica desabilitado — quem controla a obrigatoriedade são as regras.
Validações
Além da obrigatoriedade, cada campo suporta validações específicas por tipo:
| Tipo do campo | Validações disponíveis |
|---|---|
Texto curto (text), Texto longo (textarea) | Regex personalizado com mensagem; Mínimo/máximo de caracteres |
E-mail (email), Telefone (phone), URL (url) | Mínimo/máximo de caracteres |
Número (number), Moeda (currency), Percentual (percentage) | Valor mínimo e máximo |
Data (date), Data e Hora (datetime), Horário (time), Intervalo de Datas (date-range) | Data mínima e máxima |
| CPF, CNPJ, CEP | — formato fixo, sem validações adicionais configuráveis |
| Seleção, Avaliação, Arquivo, Busca, etc. | — não possuem validações configuráveis |
TIP
Campos com formato fixo como CPF (000.000.000-00), CNPJ (00.000.000/0000-00) e CEP (00000-000) já aplicam a máscara automaticamente. Não é necessário configurar regex ou comprimento para eles.
Onde a obrigatoriedade é conferida
Ao concluir uma tarefa, os campos obrigatórios são conferidos também no servidor — não só na tela. Quem chama a API direto (integração, script, chave de API) recebe 400 e a tarefa continua aberta se faltar um obrigatório; antes, uma chamada direta com o corpo vazio concluía a tarefa e a etapa seguinte recebia as variáveis em branco.
A conferência usa a versão do formulário travada na criação da tarefa — a mesma que a pessoa viu — e segue as regras condicionais: um campo escondido por uma regra não é cobrado. Um campo que só existe para exibir (título, separador, visualizador markdown) também não.
O que a conferência cobra é presença: o campo obrigatório precisa ter valor. Um obrigatório enviado só com espaços conta como vazio.
O que ainda é só do navegador
As variáveis do formulário de início — tanto de um processo quanto de um caso — e as validações de formato, tamanho e faixa (regex, mínimo/máximo de caracteres, valor mínimo e máximo, datas) continuam sendo verificadas apenas na tela.
Salvar rascunho também não passa pela conferência, e isso é de propósito: um rascunho existe justamente para guardar o formulário pela metade.
Intervalo de Datas (date-range)
O campo date-range exibe dois seletores de data — inicial e final — em linha. O valor salvo é um objeto { start: "YYYY-MM-DD", end: "YYYY-MM-DD" }. Validação automática garante que a data inicial seja anterior ou igual à data final.
Datas preenchidas não mudam com o fuso horário
Uma data que você digita num formulário — vencimento, competência, emissão — é gravada exatamente como escrita e aparece igual para todo mundo, independentemente de onde a pessoa esteja. Um vencimento em 06/08 é 06/08 para quem acessa de Manaus, de Recife ou de Lisboa.
Isso vale também para os campos de data do CMS e para variáveis de processo do tipo Data.
É diferente dos horários de registro — quando algo foi criado, executado ou concluído. Esses marcam um instante real e são exibidos no fuso de quem está lendo, porque a pergunta ali é "que horas eram para mim quando isso aconteceu".
Gatilhos de campo (preenchimento automático)
Um campo pode ter gatilhos: ao sair (blur) ou ao entrar (focus) no campo, a plataforma chama uma URL e roda um pequeno script que distribui a resposta pelos outros campos. O caso clássico é o CEP: sai do campo, consulta o serviço de endereços, preenche rua, bairro e cidade.
O script recebe três coisas e nada mais:
| Nome | O que é |
|---|---|
response | O corpo JSON que a URL respondeu |
value | O valor atual do campo que disparou o gatilho |
set(chave, valor) | Preenche outro campo do formulário |
O script roda isolado — e isso limita o que ele pode fazer
O script é executado fora da página, num contexto próprio sem window, sem document, sem localStorage e sem rede. Ele não consegue fazer chamadas HTTP por conta própria: a única chamada é a da URL configurada no gatilho, feita pela plataforma antes do script rodar. Um script escrito para usar fetch, cookies ou qualquer API do navegador vai falhar.
Além disso:
- o script tem 2 segundos para terminar; passou disso, é interrompido — laço infinito não trava a aba;
- a URL do gatilho precisa ser
http://ouhttps://; - quando alguma coisa falha — a URL responde erro, a resposta não é JSON, o script quebra ou estoura o tempo — aparece "Não foi possível executar o preenchimento automático deste campo." logo abaixo do campo, e o detalhe vai para o console do navegador. Antes, a falha era silenciosa: o campo simplesmente não era preenchido e ninguém ficava sabendo.
Visualizador Markdown (md-viewer)
O campo ✨ Visualizador Markdown (grupo Layout & Display da paleta) exibe texto formatado em Markdown dentro do formulário. É o campo indicado para mostrar o parecer de um agente de IA na tarefa, já com títulos, listas, negrito e tabelas renderizados.
Ele não coleta dado nenhum — só exibe.
Como ligar ao parecer da IA
O campo lê a variável de processo de mesmo nome da sua chave. Se o agente grava o parecer na variável parecerIa:
- Adicione o campo Visualizador Markdown ao formulário
- Em Propriedades, defina a Chave (key) como
parecerIa - O Rótulo é o título exibido acima do quadro (ex.: "Parecer da IA")
Quando a tarefa abrir, o conteúdo da variável aparece renderizado. Se a variável ainda não existir, o campo mostra (vazio) em vez de ficar em branco — útil para perceber que o agente ainda não respondeu.
Campos de exibição não são enviados
Visualizador Markdown, Título de seção e Separador existem só para exibir, então não vão no envio da tarefa nem no salvamento de rascunho. Isso evita que o formulário regrave por cima da variável: se o agente atualizar o parecer enquanto a tarefa está aberta, a versão nova é preservada.
Busca paginada (Lookup)
O campo lookup faz requisições à medida que o usuário digita (mínimo de 2 caracteres). Configure:
| Propriedade | Descrição |
|---|---|
| URL | Endpoint com {search} que será substituído pelo texto digitado |
| Campo label | Propriedade do JSON de resposta a exibir como texto |
| Campo valor | Propriedade do JSON de resposta a usar como valor salvo |
Exemplo de URL: https://api.empresa.com/clientes?q={search}
Versionamento de formulários
Todo formulário é versionado automaticamente. A cada salvamento, uma nova versão imutável é criada.
Publicar uma versão
- Abra o formulário pela aba Formulários da definição do processo
- Clique na aba 🕑 Histórico
- Localize a versão desejada e clique em Publicar
- A versão publicada aparece com a etiqueta ✓ Publicada
O editor do formulário tem três abas — 🎨 Construtor visual, </> JSON e 🕑 Histórico — e o botão Salvar nova versão no alto. Cada salvamento cria uma versão nova; publicar é um passo à parte.
Comportamento de versão em tarefas
- Quando uma tarefa é criada em um processo, o sistema trava automaticamente a versão publicada do formulário naquela tarefa
- Se nenhuma versão foi publicada explicitamente, a versão mais recente é usada
- Publicações futuras não afetam tarefas já criadas — cada tarefa sempre exibe o formulário com o schema que tinha no momento de sua criação
- As respostas submetidas viram variáveis de processo
Restaurar uma versão no editor
Na aba 🕑 Histórico, clique em Restaurar para carregar uma versão antiga no construtor visual. Isso não altera o formulário — é preciso clicar em Salvar nova versão para que ela passe a existir.
Formulários standalone
Além de formulários vinculados a tarefas, o sistema pode ter formulários avulsos para coleta de dados ou início de processos. Eles ficam na mesma aba Formulários da definição.
O formulário de início é o que a tela de iniciar processo abre antes de criar a instância. Ele vem do Form Key do evento de início, em um processo BPMN, e do Form Key do plano do caso — o retângulo externo do desenho — em um caso CMMN. Nos dois, o formulário precisa existir na definição antes do deploy, senão o deploy é recusado com "Formulário referenciado não existe no ambiente do processo".
Micro-Frontend Plugins (Formulários Externos)
Para casos de uso muito complexos que a ferramenta Low-Code do construtor visual não atenda (ex: renderizações pesadas em 3D, drag and drop de arquivos avançado customizado, integrações de socket ao vivo), o Flow.IA suporta Remote Form Plugins.
Como Funciona: Você pode desenvolver um projeto React/Vite isolado, seguindo a nossa estrutura recomendada (custom-form-boilerplate), fazer o build do componente form e expor essa URL num servidor estático (S3, Vercel, Nginx).
Há um par de exemplos no repositório: samples/custom-form-boilerplate é o plugin, e samples/external-form é um processo BPMN mínimo que o usa — com o passo a passo de servir o bundle, publicar a definição e iniciar a instância. Rodar os dois juntos é o teste mais rápido de que o caminho inteiro está de pé.
Como Configurar:
- Abra o Modelador BPMN/CMMN.
- Acesse as propriedades do elemento: a tarefa de usuário (User Task) ou o evento de início (Start Event), no BPMN; a tarefa humana ou o plano do caso, no CMMN.
- No campo Form Key (ou Start Form Key), insira diretamente a URL do Plugin (ex:
http://localhost:3001/assets/plugin.js). - Quando o usuário abrir a Tarefa ou Processo que possua uma
formKeyiniciada comhttp://ouhttps://, o Flow.IA automaticamente reconhecerá como um plugin externo. Ele vai baixar assincronamente o bundle e injetar a interface diretamente na tela, passando variáveis de contexto via props. Não é necessário salvar um schema local no construtor de formulários.
O build do plugin precisa sair como UMD com React externo
O bundle é carregado por uma tag <script> e tem de publicar o componente em window.CustomFlowiForm. A plataforma expõe React, ReactDOM, MUI, EmotionReact e EmotionStyled como globais, e o projeto do plugin marca esses pacotes como external para usá-los — dois Reacts na mesma página quebram os hooks.
Uma armadilha específica, e o boilerplate já vem configurado para evitá-la: o runtime automático de JSX importa de react/jsx-runtime, que é um especificador diferente de react e por isso escapa da lista de external. Ele entra no bundle na forma CommonJS, começando por require("react"), e o script inteiro morre no navegador com require is not defined — sem mensagem na tela além de "Componente customizado não encontrado no script". Por isso o vite.config.ts do boilerplate usa jsxRuntime: 'classic' e externaliza react por expressão regular.
As variáveis chegam antes de o formulário montar
A plataforma só monta o plugin depois de ter as variáveis do processo em mãos, e mostra um indicador de carregamento nesse intervalo. Isso importa porque defaultValues do React Hook Form é lido uma única vez, na montagem: se as props mudassem depois, o formulário nasceria vazio e ignoraria os valores que chegaram atrasados.
Boilerplate e Validação (React Hook Form + Zod)
O projeto base recomendado (custom-form-boilerplate) já vem pré-configurado com as melhores práticas de mercado utilizando React Hook Form e Zod. Ele implementa a mesma arquitetura lógica do construtor visual nativo do Flow.IA, garantindo estabilidade na injeção e extração de dados:
- Injeção de variáveis (
defaultValues): O Flow.IA entrega as variáveis do processo atual através da propinitialVariables. O formulário injeta esses dados nativamente usando odefaultValuesdo React Hook Form. - Validação tipada (Schema Zod): Regras complexas de formulário são definidas via código (
z.object({...})), garantindo total Type Safety e bloqueando o envio se os dados estiverem inconsistentes. - Salvamento Parcial e Conclusão (
onSaveeonComplete): Ao salvar o rascunho (chamando a proponSaveinjetada), a validação rígida do Zod pode ser ignorada, capturando os dados atuais comgetValues(). Mas ao avançar a tarefa (onComplete), os dados são validados pelo schema e empacotados no exato formato esperado pelo motor de processos.