Regras de Negócio — Core (Conta Digital)
Documentação do produto (não dos testes). O Core hoje não tem documentação funcional própria — este arquivo existe pra ir preenchendo esse vazio a partir do que a suíte Cypress vai descobrindo sobre como o sistema realmente se comporta. É um documento vivo: toda vez que um teste novo revelar uma regra, um campo obrigatório, um status ou uma dependência entre telas, o registro entra aqui — não só no código do teste.
Cada seção tem uma linha Fonte, indicando de onde a informação veio (spec/fluxo de Cypress), pra rastrear e revalidar se o comportamento mudar.
Índice
- Visão geral do domínio
- Mapa do menu do produto
- Credenciamento (Administradoras e Condomínios)
- Subconta
- Inativação de Conta Digital
- Contas Geradoras
- Configuração de Boleto (Condomínio/Administradora)
- Contas Correntes
- Aplicações
- Boletos
- Relatórios
- Autenticação e permissões
- Como manter este documento
Visão geral do domínio
O Core organiza os dados em uma hierarquia de 3 níveis:
Administradora
└── Condomínio (é uma "conta digital")
├── Conta Geradora (por qual banco os boletos são emitidos)
└── Boletos (cobranças geradas para os moradores/clientes)
- Administradora: a empresa que administra um ou mais condomínios (ex.: uma administradora de condomínios real, cliente do Core).
- Condomínio: cadastrado sob uma Administradora (
parentId); é ele quem efetivamente gera boletos. - Conta Geradora: o banco/conta que assina os boletos de um condomínio (Bradesco, Sicoob, Itaú, Santander, etc.). Cada condomínio usa uma só por vez, mas pode ser trocada.
Fonte: fluxo de criação de boleto via API (Administradora → Condomínio → Conta Geradora → Boleto).
Mapa do menu do produto
Levantado navegando manualmente por toda opção do menu lateral (não só as já automatizadas
em specs pontuais), em 20/08/2026 — é o que embasa cypress/e2e/smoke/smoke.cy.js. Menu é Ant
Design, com 2 modos (recolhido = só ícone; expandido = com texto, precisa clicar no botão de
menu pra alternar) e comportamento tipo "accordion" nos grupos (abrir um grupo recolhe o que
estava aberto antes).
| Item de topo | Sub-itens | URL |
|---|---|---|
| Dashboards | — | /app/dashboard/inicio (mesma tela do pós-login) |
| Unidade Organizacional | — | /app/unidade-organizacional/cadastro |
| Aplicações | — | /app/aplicacao/listar |
| Usuários | Listar, Perfil | /app/usuario/listar, /app/usuario/perfil |
| Contas Digitais Boleto | — | /app/conta-digital/listar |
| Contas Correntes | — | /app/conta-corrente/listar |
| Contas Geradoras | Cadastro, Distribuição Percentual, Alteração em Lote | /app/conta-geradora/percentual, /app/alteracao-conta-geradora (+ Cadastro, URL não fixada — sempre navegado via menu) |
| Boletos | — | /app/boleto/listar |
| Remessa | — | /app/remessa/listar |
| Termos Aceite | — | /app/termo-aceite/listar |
| Conta Condominial | Geral, Dashboard › Geral, Despesas, Webhook | /app/conta-condominial/listar, /app/conta-condominial/dashboard-conta-digital/geral, /app/conta-condominial/despesas/listar, /app/conta-condominial/webhook/listar |
| Relatórios | — | /app/relatorio/listar |
| Integrador | — | /app/integrador/listar |
| Notificações | Cadastros, Boletos (Geral, Bolepix) | /app/notificador/listar, /app/notificador/boleto/geral, /app/notificador/boleto/pix |
| DDA | Aplicações, Empresas, Boletos, Consumo | /app/dda/listar, /app/dda/empresa, /app/dda/boleto, /app/dda/consumo |
Atualizado em 21/08/2026 — 2 das 3 particularidades abaixo, confirmadas em 20/08/2026,
DEIXARAM DE SER VERDADE de um dia pro outro (confirmado de novo inspecionando o DOM real, não no
chute — foi um teste de regressão que capturou a mudança sozinho, ver
docs/historico-de-falhas.md). Produto mudou, não foi engano da investigação original.
"DDA > Aplicações" é a MESMA tela que "Aplicações" solta no topo"— não é mais verdade. "DDA > Aplicações" agora é uma tela PRÓPRIA (/app/dda/listar, título "Cadastro de Aplicações": filtros Status/Guid/Nome da Aplicação, colunas Nome/Ativa/Data Cadastro/Data Descredenciamento, ações Ativar/Inativar) — diferente da "Aplicações" solta no topo (/app/aplicacao/listar, título "Aplicações", botão "Nova Aplicação", coluna "Conta Geradora"). Continuam sendo 2 itens de menu distintos, mas agora também são 2 TELAS distintas."Notificações > Boletos" é um item morto— não é mais verdade. Agora é um submenu de verdade, com 2 filhos reais: Geral (/app/notificador/boleto/geral, "Notificações de Boletos") e Bolepix (/app/notificador/boleto/pix, "Notificações de Bolepix") — os dois telas de consulta funcionais, com filtro e tabela de resultado.Duas telas do menu têm controle real com efeito colateral sério, fora do escopo de qualquer automação de teste (esta particularidade continua valendo):
- Contas Geradoras > Distribuição Percentual: mostra o percentual de roteamento de boleto entre bancos (campo editável, com botão de salvar de verdade).
- Integrador: mostra se a rota SQS do integrador está ativa, com um botão "Parar" que desativa uma integração de verdade em homologação.
smoke.cy.jsnavega até as duas só pra confirmar que abrem — nunca interage com os controles.
Fonte: navegação manual por todo o menu lateral, 20/08/2026 (mapa original) + reconfirmação
pontual em 21/08/2026 (particularidades #1 e #2, depois que um teste de regressão pegou a
divergência). Ver também docs/historico-de-falhas.md pra erros de API reais encontrados de
passagem nessa navegação.
Credenciamento (Administradoras e Condomínios)
Cadastrar uma Administradora ou um Condomínio segue a mesma estrutura de dados nos dois casos:
| Bloco | Campos |
|---|---|
| Pessoa Jurídica | CNPJ, razão social, CEP, endereço, número, bairro, complemento, cidade, estado, telefone, e-mail, e-mail financeiro |
| Credenciais de acesso | usuário e senha próprios da entidade |
| Configuração de boleto | taxa de serviço, taxa de boleto, forma de cobrança da tarifa, versão do "Cond21" |
Condomínio tem, além disso, parentId (a Administradora dona dele) e pode ter contas correntes
associadas.
Regras
- CNPJ é validado e precisa ser único — tanto na Administradora quanto no Condomínio. Uma tentativa de credenciar com CNPJ já usado (ou com dígito verificador inválido) é rejeitada.
- Cada entidade credenciada ganha login próprio (usuário/senha definidos no momento do cadastro) — não existe uma credencial "genérica" pra Administradora/Condomínio; é gerada uma por entidade. Isso é o que permite autenticar como aquela entidade especificamente depois (ver Autenticação e permissões).
- A conta do Condomínio não fica ativa instantaneamente — a ativação é assíncrona; operações que dependem da conta estar ativa (gerar boleto, por exemplo) podem ser rejeitadas nos primeiros instantes depois do cadastro.
Fonte: collection Postman "CORE HOMOL V1" (Credenciamento) + fluxo de criação de boleto via API.
Subconta
Um Condomínio pode virar uma espécie de "Administradora de segundo nível": uma vez habilitado, outros Condomínios podem ser cadastrados como subconta dele, em vez de soltos direto na Administradora original.
Regras
- A tela é "Contas Digitais Boleto" (
/app/conta-digital) — mesma tela usada tanto pra Administradora quanto pra Condomínio. Cada registro tem 5 abas: Cadastro, Subcontas, Contas, Configurações, Boletos. - Habilitar exige a conta ativa. O botão "Habilitar Subconta" (aba Cadastro) chama
PATCH /adm/contas-digitais/{guid}/habilitar-subcontas. Numa conta ainda não ativa (ativação é assíncrona, ver seção "Credenciamento" acima), a resposta é 400:
Confirmado batendo na API real (interceptando a chamada, não só o toast) — o mesmo envelope{"code":400,"domain":"Validação","description":"Conta Digital '{guid}' não está ativa."}{code, domain, description}já visto em outros 400/404 deste projeto. - É irreversível. Clicar em "Habilitar Subconta" abre um modal de confirmação real: "Esta operação não pode ser desfeita! Deseja habilitar a funcionalidade de subconta para este condomínio?". Depois de confirmado com sucesso: o checkbox "Permite cadastro de subcontas" fica marcado, e o próprio botão "Habilitar Subconta" fica desabilitado (continua na tela, só não clicável) — não existe ação de desfazer isso na UI.
- O botão só aparece com mais condições do que só "não estar inativa" (achado lendo o
código-fonte real do front, 09/09/2026,
ContaDigital/Servico/Cadastro/Dados.js): além de!isContaInativa, precisa ser uma subconta (parentId !== null) e não sercontaPoole não sersubcontaDaSubconta. Os specs de hoje (subconta.cy.js) sempre rodam contra um Condomínio comum, então nunca bateram nessas 2 últimas exceções — não é bug do teste, é só um cenário (conta pool / subconta da subconta) que ele ainda não cobre. - CNPJ duplicado se comporta diferente conforme a flag. Cadastrar um Condomínio com um CNPJ que
já existe, na mesma Administradora:
- Se o Condomínio dono desse CNPJ não tem permissão de subconta habilitada → rejeitado, 400,
mensagem
"O CNPJ {cnpj} já está cadastrado no sistema para a aplicação: {aplicação}". - Se tem → aceito, e o novo registro entra como subconta daquele Condomínio (não solto direto na Administradora).
- Se o Condomínio dono desse CNPJ não tem permissão de subconta habilitada → rejeitado, 400,
mensagem
- A listagem de subcontas de uma Administradora fica na aba "Subcontas" dela (
/app/conta-digital/{guid}/subcontas), carregada viaGET /adm/contas-digitais?...&guidContaMatriz={guid}— lista todo Condomínio cujo "Conta Matriz" é aquela Administradora, subconta ou não.
Fonte: tela real (core-homol2-contadigital.contagroup.com.br), sessão logada, 25/08/2026 —
botão, modal, checkbox e corpo da resposta de erro confirmados ao vivo (interceptando
fetch/XHR); ver ContaDigitalBoletoPage.js e o spec
subconta.cy.js.
Validação do formulário de Cadastro (aba Cadastro — edição de Pessoa Jurídica)
Achado lendo o código-fonte real dos 2 lados (09/09/2026 — front, repositório backoffice,
ContaDigital/Servico/Cadastro/Dados.js; back, core-api, services/dto/PessoaJuridicaDTO.java):
o front é mais restritivo que o backend em pelo menos 3 campos.
| Campo | Front (Yup) | Backend (Bean Validation) |
|---|---|---|
estado |
Obrigatório — "Estado obrigatório" | Opcional |
email |
Obrigatório — "Campo obrigatório" | Opcional |
codigoCliente |
Regex ^[a-zA-Z0-9-]*$ — "Código do cliente deve conter apenas letras, números e hífen" |
Sem regex, só limite de tamanho (máx. 50) |
Consequência prática: um teste feito só contra a API (cy.request) pode mandar estado/email
vazios ou codigoCliente com caractere especial e o backend aceita — isso nunca aconteceria
passando pela tela de verdade, o front barra antes de qualquer chamada. Spec novo
cadastroContaDigitalValidacao.cy.js
cobre estado/email (validação de front pura, sem depender do backend responder nada — o
trigger() do react-hook-form barra o envio antes de qualquer rede). razaoSocial, cep,
endereco, bairro, cidade são obrigatórios nos 2 lados (sem divergência).
Inativação de Conta Digital
Tanto Administradora quanto Condomínio (mesma tela "Contas Digitais Boleto", aba Cadastro) têm um botão "INATIVAR" (vermelho, rodapé do formulário, ao lado de "Habilitar Subconta"/"Editar CNPJ Adm", "Histórico", "Forçar reendereçamento", "Editar").
Regras
- Não pode inativar uma Administradora com Condomínio ativo vinculado. Chama
DELETE /adm/contas-digitais/{guid}; se a Administradora tiver ao menos 1 Condomínio ainda ativo, a resposta é um erro (não-2xx) com:
Precisa inativar o(s) Condomínio(s) vinculado(s) primeiro.{"description": "A Conta Digital '{guid}' não pode ser inativada porque ainda possui subcontas ativas"} - Mesmo endpoint pros 2 tipos de registro — inativar um Condomínio (sem essa restrição) ou uma
Administradora sem Condomínio ativo chama o mesmo
DELETE /adm/contas-digitais/{guid}, e retorna sucesso (2xx) com toast verde "Conta Digital inativada com sucesso". - O botão nasce desabilitado por um instante ao carregar a tela (não só "Inativar" — vários botões do rodapé) e habilita sozinho logo em seguida, sem precisar de reload — é só a tela ainda buscando dados, não uma regra de negócio. Confirmado ao vivo, 09/09/2026.
- Depois de inativado, o registro aparece na listagem de Subcontas da Administradora
(
/app/conta-digital/{guid}/subcontas) com a coluna Status mostrando "INATIVA". - CNPJ na listagem de Subcontas — havia um bug antigo trocando o
-porxno CNPJ exibido ali; já corrigido no produto (confirmado 09/09/2026, formato real vemNN.NNN.NNN/NNNN-NN, igual ao resto do sistema).
Fonte: tela real (core-homol2-contadigital.contagroup.com.br), sessão logada, 09/09/2026 —
botão, endpoint e mensagem de bloqueio confirmados ao vivo (interceptando fetch/XHR); ver
ContaDigitalBoletoPage.js (método inativar()), o
spec de regra de negócio contaDigitalInativacao.cy.js
e o spec de trava de bug do CNPJ contaDigitalCnpjSubcontasRegressao.cy.js.
Contas Geradoras
Cadastro dos bancos/contas que efetivamente emitem os boletos em nome de um condomínio. Já existem várias pré-cadastradas no ambiente (Bradesco, Sicoob, Itaú, Santander, Sicoob Goiânia, Bradesco Bolepix, Santander Bolepix, Conta Digital Balde (Itaú), entre outras).
Campos obrigatórios do cadastro
| Campo | Descrição |
|---|---|
nome |
Nome de exibição da conta geradora |
codigoExterno |
Identificador externo |
banco |
Banco |
agencia / digitoAgencia |
Agência e dígito |
conta / digitoConta |
Conta e dígito |
Regras
- Um condomínio usa exatamente uma Conta Geradora por vez — é ela que determina por qual banco os boletos daquele condomínio saem (aparece na tela como "Código Banco Gerador" e na linha digitável do boleto).
- Se nenhuma Conta Geradora for definida explicitamente, o condomínio fica com uma conta padrão do ambiente (hoje, Sicoob) — não fica "sem banco".
- Existe alteração em lote: dá pra trocar a Conta Geradora de vários condomínios de uma vez
(endpoint dedicado —
PUT /adm/organizacoes/conta-geradora/lote), sem precisar editar condomínio por condomínio. - Trocar a Conta Geradora de um condomínio é uma operação de back-office, distinta do cadastro/edição feitos pela própria entidade (ver Autenticação e permissões).
Cadastro de uma Conta Geradora nova (tela "Contas Geradoras > Cadastro")
Confirmado testando manualmente antes de automatizar (contaGeradora.cy.js, descreve "salva de
verdade"):
- Salvar dispara
POST .../adm/contas-geradoras(201no sucesso) — um registro só do Core. Não encontrei nenhuma chamada acontecendo junto pra um banco de verdade (diferente de Boletos via API, que depende de um banco real do outro lado da criação) — mas é dado real mesmo assim, sem endpoint de exclusão usado neste projeto (ver Cuidado com dados reais). - A listagem (
/app/conta-geradora/listar) NÃO atualiza sozinha depois do modal fechar — precisa recarregar a página pra ver o registro novo. - O registro novo aparece sempre no FIM da lista (última página da paginação), não no início.
- Uma Conta Geradora
Ativa: Simaparece no combo real que qualquer pessoa vê ao configurar o boleto de um condomínio de verdade — por isso os registros criados pela suíte usamAtiva: Nãode propósito, pra não poluir esse combo pra usuários reais. - A listagem não tem busca nem visualização de detalhe/edição — nem a seta de expandir a linha, nem clicar na linha, abrem algo (confirmado testando). Por isso o teste automatizado valida "salvou certo" pela resposta HTTP do próprio Salvar, não conferindo a listagem depois.
Fonte: tela "Configuração Boleto" do condomínio + tela "Contas Geradoras › Cadastro".
Configuração de Boleto (Condomínio/Administradora)
Tela "Contas Digitais Boleto › {registro} › Configurações", card "Configuração
Boleto" (PUT /adm/contas-digitais/{guid}/configuracoes/boleto). A mesma página tem um 2º card
independente, "Configuração Plano" (Plano, percentuais, Dias de compensação) — fora do escopo
desta seção. Campos confirmados na tela real (sessão logada, 03/09/2026):
| Campo | Tipo | Editável? |
|---|---|---|
| Conta Geradora | combo | Sim — até "Conta geradora fixa" ser habilitada (ver Regras) |
| Conta geradora fixa | combo Sim/Não | Só Não→Sim (ver Regras) |
| Taxa Serviço | número | Sim |
| Taxa Boleto | número | Sim — precisa ser ≥ taxa boleto da Administradora |
| Comissão Bruta | número | Não — sempre somente-leitura |
| Tipo de geração de boleto | combo | Não — sempre somente-leitura, mostra "Arquivo" |
| Decurso personalizado | combo Sim/Não | Sim — mas só persiste com "Dias para decurso de prazo" preenchido (ver Regras) |
| Dias para decurso de prazo | número | Só aparece/habilita quando "Decurso personalizado" = Sim |
| Replicar decurso em subcontas | combo Sim/Não | Sim — só persiste com pelo menos 1 subconta (ver Regras) 🔶 validação de ponta a ponta ainda pendente (ambiente) |
Regras
- O botão "Editar" funciona como "Salvar" — não existe modo de edição separado; os campos já são interativos direto na tela, e clicar em "Editar" dispara na hora o PUT com o que estiver no formulário (mesmo sem mudar nada, mostra o toast "Dados atualizados com sucesso").
- "Conta geradora fixa" parece irreversível: Não → Sim é aceito, habilita um banner "CONTA GERADORA FIXA HABILITADA", e a partir daí "Conta Geradora" fica permanentemente desabilitado (caminho contrário, Sim → Não, não testado).
- Não dá pra trocar "Conta Geradora" e habilitar "Conta geradora fixa" na MESMA edição — a API
rejeita com 400,
"Contas geradoras fixas não podem ser alteradas.". Trocar só um dos dois por vez funciona normalmente. - "Decurso personalizado": Bug #26954 corrigido pelo dev (03/09/2026) — o campo "Dias para
decurso de prazo" não estava liberando/aparecendo na tela quando esse combo ia pra "Sim"; já
corrigido. Comportamento correto confirmado ao vivo pós-correção: escolher "Sim" revela o campo
"Dias para decurso de prazo" (
diasDecursoPrazo, número). Salvar "Sim" sem preencher esse campo é rejeitado silenciosamente pelo backend — volta "Não" ao recarregar, sem erro na tela (200, toast de sucesso normal); isso é validação esperada, não bug. Preenchendo os dias, "Sim" persiste normalmente, junto com o valor digitado. Confirmado ao vivo isolando o campo (pra não confundir com "Conta geradora fixa" acima, que bloqueia a edição inteira quando combinado com troca de Conta Geradora). - "Replicar decurso em subcontas" é campo da ADMINISTRADORA, não do Condomínio — regra
descrita pelo usuário (03/09/2026): é a Administradora replicando SEU decurso pros Condomínios
(subcontas) dela, não um Condomínio pra outro. Só mantém "Sim" se a Administradora tiver pelo
menos 1 subconta de verdade.
condominioConfiguracaoBoleto.cy.jstesta esse campo na Configuração da ADMINISTRADORA (guidAdministradora), depois de criar uma subconta de verdade nobefore()(mesmo fluxo desubconta.cy.js: habilitar subconta + 2º Condomínio com o mesmo CNPJ) — diferente de todos os outros campos desta tabela, testados no Condomínio. Validação de ponta a ponta ainda pendente: mesmo com a subconta criada e confirmada (subcontaDaSubconta: truevia API), o campo continuou revertendo "Não" — causa provável é o mesmo problema de ambiente já documentado acima ("Conta digital não está ativa": subconta nasce emAVALIACAO, nãoATIVA, e só o VS aprovando ou reinício da aplicação em HML resolve, não é algo que o teste force sozinho). Não foi possível confirmar se "ter uma subconta" já é suficiente mesmo em avaliação, ou se precisa estarATIVA. Ainda sem work item aberto (confirmado pelo usuário, 03/09/2026: o Bug #26951 trata só "Decurso personalizado" — este campo não foi nem será tratado ali, apesar da Obs do work item citar "subconta"). Travado emcondominioConfiguracaoBoleto.cy.js, que documenta o comportamento atual (decisão do usuário: deixar vermelho por enquanto) até essa validação ser concluída.
Fonte: tela real (core-homol2-contadigital.contagroup.com.br), sessão logada, 03/09/2026 —
confirmado criando Administradora + Condomínio reais e editando campo por campo, com reload real
entre cada edição e a checagem (nunca no chute).
Contas Correntes
Cadastro das contas correntes bancárias vinculadas a uma Administradora/Condomínio — cada uma tem
banco, agência, número da conta, e passa por um fluxo de aprovação próprio (distinto do cadastro
em si). Tela só encontrada via menu lateral "Contas Correntes" (/app/conta-corrente/listar).
Ciclo de vida (Status x Status Aprovação — dois campos independentes)
| Campo | Valores possíveis |
|---|---|
Status |
Criada, Avaliação, Ativa, Erro de Cadastro, Inativa, Descredenciada |
Status Aprovação |
Pendente, Bloqueado, Aprovado, Rejeitado |
São dois campos independentes — uma conta pode estar Status: ATIVA e Status Aprovação: REJEITADO ao mesmo tempo (confirmado: é o estado mais comum nos dados reais do ambiente de
homologação). Existe uma tela separada de aprovação (expandindo uma linha da listagem → aba
"Aprovação", ou direto em /app/conta-corrente/{guid}/aprovar) com um histórico de aprovação
próprio — nem toda conta tem uma entrada nesse histórico, mesmo já tendo um Status Aprovação
diferente de "Pendente" (confirmado num registro real: Status Aprovação "Rejeitado", histórico de
aprovação vazio).
Filtros da listagem
17 campos de filtro ao todo — 11 de valor único e 3 pares de intervalo de data:
| Filtro | Tipo |
|---|---|
| Guid, Razão Social, CNPJ, Código Banco, Agência, Conta Corrente | Texto livre |
| Status, Status Aprovação, Aplicação, Principal, Conta Geradora | Combo (lista fixa) |
| Data Última Aprovação, Data Cadastro, Data Modificação | Intervalo (Início/Fim) |
Combo "Conta Geradora" neste filtro não é a mesma coisa que a Conta Geradora do boleto de um condomínio (ver Contas Geradoras) — aqui é só mais um critério de busca sobre a conta corrente, com a mesma lista de bancos pré-cadastrados (Bradesco, Sicoob, Itaú, Santander, etc., incluindo as variantes "Bolepix").
Agência e Conta Corrente: o filtro não aceita o dígito verificador que a tela mostra. A coluna da listagem exibe "111-1" (Agência) e "22378320-1" (Conta Corrente), mas buscar com esse valor completo devolve 0 resultados — o filtro só reconhece a parte antes do traço ("111", "22378320"). Confirmado testando os dois formatos direto na tela.
Botão "Limpar Seleção" (liberado pra homologação em 20/08/2026): zera todos os campos de filtro preenchidos (texto, data e combo, sem exceção) e já atualiza a listagem sozinho — volta a mostrar todos os registros sem precisar clicar em "Pesquisar" de novo.
Fonte: tela "Contas Correntes" (/app/conta-corrente/listar), inspecionada em 20/08/2026 —
ver cypress/e2e/regressao/contaCorrente/contaCorrente.cy.js.
Aplicações
Cadastro simples que identifica o sistema/integração de origem de um condomínio (ex.: "Aplicação V1", "Aplicação V2", "Group Condomínios - HOMOL", "Acolweb Software para gestão de condomínios") — é esse valor que aparece na coluna "Aplicação" da listagem de Boletos.
Campos
| Campo | Obrigatório? |
|---|---|
nome |
Sim — único campo obrigatório do cadastro |
ativa |
Não — combo Sim/Não, vem com "Sim" por padrão |
A listagem de Aplicações também mostra "Data Cadastro" e "Conta Geradora" por linha, mas nenhum dos dois é preenchido no cadastro em si (a Conta Geradora aparente aqui parece vir de outro lugar — ainda não investigado).
Ligação com a autenticação de POST /credenciamento
Cada Aplicação cadastrada tem uma tela de detalhe com 2 abas — "Cadastro" (nome, guid, ativa,
Conta Geradora) e "Chaves" — confirmado ao vivo em 26/08/2026 (tela
/app/aplicacao/{guid}/cadastro, exemplo real: Aplicação "Group Financeiro"). A aba "Chaves" é a
candidata forte pra onde vive a Api-Key usada nos headers Api-Key/Application de
POST /credenciamento (ver seção "Credenciamento" abaixo) — ainda não confirmado com certeza
se o header Application espera o nome ou o guid da Aplicação (o teste de investigação usou
um valor inventado, que a API rejeitou com "Aplicação '<valor>' não encontrada" — confirma que
existe uma busca real contra esse cadastro, não qual dos 2 campos é usado pra buscar).
O que fica confirmado: Application identifica qual sistema/integração parceira está
chamando a API (o mesmo conceito da coluna "Aplicação" na listagem de Boletos, acima); Api-Key é
o segredo que prova que a chamada é de fato dessa Aplicação. Diferente de AuthCG (token de
sessão, por usuário, expira), esses 2 valores são fixos/estáticos — não mudam a cada chamada,
presumivelmente cadastrados uma vez quando uma integração parceira nova é provisionada.
Ainda em aberto (não investigado, provavelmente precisa de alguém com acesso ao backend/à
gestão de Aplicações do Core, não só teste de caixa-preta): quem cadastra uma Aplicação nova e
onde exatamente a Api-Key é gerada/rotacionada; se existe 1 Api-Key por Aplicação ou uma
compartilhada; se há expiração ou limite de uso.
Fonte: tela "Aplicações" (/app/aplicacao/listar) › "Nova Aplicação"; tela de detalhe
de uma Aplicação (abas "Cadastro"/"Chaves"); investigação de POST /credenciamento sem
autenticação em cypress/e2e/seguranca/autenticacaoObrigatoria.cy.js (ver
docs/historico-de-falhas.md, entrada de 26/08/2026).
Boletos
Um Condomínio gera boletos em lote — cada lote é uma Remessa. Cada boleto dentro da remessa tem um cliente (o morador/pagador) e um valor.
Estrutura de um boleto
| Bloco | Campos |
|---|---|
| Cliente (pagador) | nome, CPF/CNPJ, e-mail, telefone, endereço |
| Cobrança | valor total, data de vencimento, multa (%), juros ao dia (%), até 3 faixas de desconto (valor + prazo cada) |
| Identificação | codigoExterno (controlado por quem gera o boleto), guid (identificador do sistema) |
Ciclo de vida (status)
| Status | Significado |
|---|---|
RECEIVED |
Boleto recebido pra processamento — resposta imediata da chamada de geração |
REGISTRO_CRIADO |
Estado intermediário do processamento (visto entre RECEIVED e GERADO) |
GERADO |
Processado com sucesso, pronto (linha digitável, PIX, etc. disponíveis) |
ERRO_VALIDACAO |
Falhou no processamento (dado inválido, por exemplo) |
PEDIDO_CANCELAMENTO |
Cancelamento solicitado — estado intermediário, não terminal (ver "Cancelamento", abaixo) |
CANCELADO |
Cancelamento confirmado — terminal de verdade, mas só alcançado bem depois da janela de um teste (ver "Cancelamento") |
A transição de RECEIVED para GERADO/ERRO_VALIDACAO é assíncrona — não acontece na
mesma chamada que solicita a criação, e passa por pelo menos um estado intermediário
(REGISTRO_CRIADO) no meio do caminho; um teste/integração que espera o resultado final não deve
assumir que "diferente de RECEIVED" já significa terminado. O motivo de um ERRO_VALIDACAO não
aparece em nenhuma resposta de API (nem a de gerar, nem a de consultar em lista,
GET .../boletos) — só no modal de Detalhes da tela (campo validacoes), que evidentemente busca
de um endpoint mais detalhado do que o que a listagem usa. O texto exato dessa mensagem não é
fixo entre execuções, mesmo pro mesmo cenário — testando "data de vencimento retroativa"
repetidas vezes, às vezes sai "Erro: Boleto não pode ser gerado com data de vencimento anterior a
hoje.", às vezes "Erro: O prazo de desconto deve ser superior a data de hoje." (confirmado
rodando várias vezes seguidas). Provavelmente por causa de como o teste monta o payload: uma
mesma data retroativa é usada em 4 campos ao mesmo tempo (dataVencimento, prazoDesconto,
dataCarenciaMulta, dataCarenciaJuros), então mais de uma validação falha ao mesmo tempo, e
qual delas "vence" pra virar a mensagem reportada parece não ser garantido. Testes que conferem
esse campo devem checar um padrão (ex.: /anterior a hoje|superior a data de hoje/), não o texto
exato — ver boletoViaApi.cy.js.
Regras
- Um boleto tem dois identificadores diferentes, e os dois são distintos do
codigoExternoque quem gera controla:- o
guiddevolvido na hora da criação é provisório; - o
guid"de verdade" (o que a tela usa pra busca/filtro,identificadorContaGroup) só existe depois, consultando a lista de boletos do condomínio.
- o
- O boleto sai pelo banco configurado como Conta Geradora do condomínio naquele momento — trocar a Conta Geradora depois de gerar um boleto não altera boletos já criados.
- Boletos podem ser cancelados (endpoint dedicado) — não existe edição de um boleto já
gerado, só cancelamento. O cancelamento também é assíncrono: a chamada responde
RECEIVEDna hora, o status muda depois (ver o parágrafoPEDIDO_CANCELAMENTO/CANCELADOlogo abaixo — o destino observável em teste éPEDIDO_CANCELAMENTO, nãoCANCELADO). O cancelamento é feito pelocodigoExternodo boleto, não peloguid"de verdade" (identificadorContaGroup, o que a tela usa pra busca) — usar o guid real nessa chamada é rejeitado com 404 "Boleto não encontrado". Só pode cancelar um boleto que já chegou emGERADO— tentar cancelar antes disso (aindaRECEIVED/REGISTRO_CRIADO, pendente de envio pro banco) é rejeitado com 400: "Cancelamento não pode ser efetuado, pois boleto está pendente de envio para o banco." (confirmado testando). O status que o cancelamento alcança dentro de um tempo observável em teste éPEDIDO_CANCELAMENTO— nãoCANCELADO. Confirmado esperando bem mais que o timeout de um teste (minutos, não segundos) dentro da execução: o status não avança sozinho depois dePEDIDO_CANCELAMENTOnesse intervalo controlado. MasPEDIDO_CANCELAMENTOnão é terminal de verdade, só terminal-pra-teste: confirmado (31/08/2026, olhando a tela real de "Boletos" poucos minutos depois da execução) que um boleto de teste (cliente: "Cypress QA Cancelamento", cenário deboletoViaApi.cy.js) avançou sozinho praCANCELADO— processamento fora do alcance de um teste (provável arquivo de retorno do banco, como o resto do fluxo de boleto), mas rápido (poucos minutos, não horas). Prazo exato ainda não medido com precisão. Os testes que travamPEDIDO_CANCELAMENTOcomo resultado continuam corretos (é o que dá pra observar dentro do tempo de um teste) — só a ideia de que seria o estado final de verdade que estava errada. - ⚠️ Falha de segurança CONFIRMADA (28-31/08/2026, múltiplas execuções reais):
POST .../boleto/{codigo}/cancelamento(Cancelar Boleto) não valida posse — uma Administradora sem relação nenhuma com o Condomínio/boleto consegue cancelar usando o próprio token, desde que aponte a URL pro guid real da vítima. Confirmado repetidas vezes, com sinais variados: efeito colateral real (status virouPEDIDO_CANCELAMENTOouCANCELAMENTO_SOLICITADO, dependendo da execução — nome ainda não esclarecido, verdocs/historico-de-falhas.md), resposta HTTP aceitando direto (200, sem nem parecer rejeitar), e — confirmado 31/08/2026 olhando a tela real — o cancelamento não fica só no status intermediário: completa mesmo, o boleto da vítima chega emCANCELADOde verdade, minutos depois, do mesmo jeito que um cancelamento legítimo chegaria. Ou seja, não é uma falha "cosmética" (aceitar a chamada sem executar) — é um cancelamento real e completo de um recurso alheio. Mesmo tipo de falha já confirmada emPOST /contaDigital/remessa(ver "Autenticação e permissões", abaixo) — os 2 juntos sugerem que a checagem de posse pode faltar de forma sistemática na API de Entidade, não só nesses 2 endpoints. Trava travada emboletoCancelamentoCrossTenant.cy.js. Detalhe completo emdocs/historico-de-falhas.md. - Multa, juros e desconto são configuráveis por boleto, não fixos por condomínio — cada boleto de uma mesma remessa pode ter valores diferentes. Na tela, os percentuais (multa e juros ao dia) são exibidos arredondados pro número inteiro mais próximo, sem casa decimal (ex.: um juros de 0,3333% ao dia aparece como "0%" no Detalhes) — o valor exato só existe no dado enviado/armazenado, não no que a tela mostra.
- Data de vencimento no passado NÃO é rejeitada na hora de gerar o boleto — a chamada de
geração aceita normalmente (200,
RECEIVED); o boleto só falha depois, de forma assíncrona, terminando emERRO_VALIDACAO(ver "Ciclo de vida", acima) em vez deGERADO. Isso vale também pros prazos derivados da data de vencimento (carência de multa, carência de juros, prazo de desconto), que usam a mesma data. - Uma remessa pode conter mais de um boleto (array no pedido de geração) — a resposta da
chamada é uma só para a remessa inteira (
{ guid, status }), mas cada boleto dentro dela é processado e resolve de forma independente: cada um ganha seu próprioguidreal (identificadorContaGroup) e seu próprio status final — um boleto da remessa pode terminarGERADOe outroERRO_VALIDACAO, por exemplo. - A seção de "dados de emissão" do boleto (Nosso Número, Seu Número, Linha Digitável, PIX,
Código Banco, Conta Geradora, Tipo de Emissão) só existe no modal de Detalhes depois que o
boleto chega em
GERADO— num boleto aindaRECEIVED/REGISTRO_CRIADOou que terminou emERRO_VALIDACAO, esses campos nem aparecem no DOM (não é só valor vazio; nunca chegou a ser processado por um banco de verdade). Dentro dessa seção, PIX é a exceção: mesmo com o boletoGERADO, só vem preenchido em contas geradoras do tipo "Bolepix" — nas contas geradoras normais (ex.: Bradesco padrão) o campo existe, mas fica vazio.
O que acontece quando "Gerar Boleto" recebe um erro
Testado direto na API REAL de homologação (não mock) — ver
boletoSimulaErroEmissao.cy.js. Uma tentativa
anterior usava um mock do Postman no lugar da chamada real e concluía, errado, que "nenhum erro
cria boleto" — o mock nunca chegava a bater no Core de verdade, então nada mesmo era persistido;
essa conclusão não valia nada sobre o produto real. Reescrito batendo em entradas propositalmente
inválidas contra a API real:
| Entrada inválida | O que a API real devolve | Cria boleto? |
|---|---|---|
Token (AuthCG) inválido/expirado |
403 "Acesso negado" (não 401) | Não — rejeitado antes de qualquer processamento |
| Guid de Condomínio inexistente | 404 "Conta Digital não encontrada" | Não |
| Cliente sem CPF/CNPJ (campo obrigatório faltando) | 500 — erro de banco (Hibernate ConstraintViolationException) vazado cru |
Não — e é um bug real de validação: deveria devolver 400 com mensagem clara, não estourar exceção de SQL pro cliente |
| Código Externo do boleto repetido na mesma Conta Digital | 400 "A conta digital [...] possui códigos externos duplicados: [...]" | Não — o boleto original continua existindo normal, sem duplicar |
| Data de vencimento retroativa (já documentado acima) | 200 aceito | Sim — só esse caso resulta em boleto criado com o erro visível nele (ERRO_VALIDACAO + campo validacoes) |
Em 4 dos 5 casos testados, a rejeição é síncrona — a própria chamada já responde com o erro, e nenhum boleto chega a existir. O único caso confirmado onde "o boleto é criado e aparece com o erro" é o de data retroativa: ali a chamada é aceita (200, RECEIVED) e o processamento assíncrono seguinte é que rejeita, já com um registro persistido. Não é o comportamento padrão de qualquer erro — é específico de validações que o Core aceita primeiro e processa depois. Erros de autenticação, condomínio errado, payload malformado e duplicidade são todos rejeitados antes de qualquer coisa ser persistida.
Bug real encontrado: o cenário de campo obrigatório faltando (cliente.cpfCnpj ausente)
deveria ser uma validação de entrada (400, mensagem clara) e hoje é uma exceção de banco vazada
(500, com texto de ConstraintViolationException/SQL na resposta) — informação de implementação
interna exposta ao cliente da API. Vale reportar pra quem mantém o backend.
Duas validações de duplicidade diferentes, não uma só: o exemplo da tabela é duplicar o
codigoExterno de um BOLETO (dentro do array boletos). Duplicar o codigoExterno da REMESSA
em si (o campo no nível raiz do payload, um por chamada) é uma validação diferente, com mensagem
diferente: "Código Externo [...] da remessa já cadastrado para a Conta Digital informada"
(confirmado testando à parte, reaproveitando o corpo inteiro da chamada anterior sem gerar um
codigoExterno de remessa novo).
Os status 500 "Erro interno do banco" e 503 "Banco indisponível" (cenários que representam o banco emissor em si falhando/fora do ar) não foram incluídos — não são reproduzíveis de forma confiável num teste de caixa-preta, sem acesso à infraestrutura real.
Existe uma 2ª chamada, interna, entre o Core e o banco (fora do alcance desta suíte)
Depois que o boleto já foi aceito e criado (POST .../contaDigital/remessa respondeu 200/201, o
registro já existe), o próprio Core faz uma chamada separada, servidor-a-servidor, direto pra
API do banco emissor (ex.: Sicoob) pra efetivamente registrar/emitir o boleto lá — usando
credenciais do Core com o banco, não relacionadas a nenhum token que a gente controla. Essa
chamada pode falhar (confirmado com um caso real de produção: o banco recusou com 401 "Invalid
client id or secret" — credencial do Core com o banco inválida/expirada, não um problema do
boleto em si).
Por que isso está fora do alcance desta suíte: essa chamada roda inteira dentro do backend do
Core — nunca passa pela API pública que os testes usam, nunca passa pelo navegador. Não tem
endpoint/URL configurável em nenhum cadastro que a gente acessa (o cadastro de Conta Geradora
só guarda dados da conta bancária — nome, código externo, agência, conta — não o endereço da API
do banco), então não tem como redirecionar essa chamada pra um servidor de teste nem interceptá-la
de fora. Simular esse cenário exigiria acesso direto à infraestrutura/configuração de backend do
Core, fora do escopo de um teste de caixa-preta via API/tela.
O que fica sem resposta, por essa limitação: não sabemos, testando por fora, se/como o
registro do boleto muda quando esse tipo de erro acontece (mantém GERADO? vira algum status
novo que a suíte nunca viu? o motivo do banco fica visível em algum campo, como o validacoes do
ERRO_VALIDACAO?). Se isso vier a ser investigado, precisa ser por quem tem acesso ao backend/à
integração Core↔banco, não por testes de fora.
Fonte: boletoSimulaErroEmissao.cy.js, testado direto contra a API real de homologação;
mecanismo Core↔banco confirmado a partir de um caso real de produção (arquivos de log
compartilhados pelo usuário, não versionados neste projeto por conter dado sensível de cliente).
Relatórios
O módulo de Relatórios tem 11 tipos disponíveis:
| Tipo |
|---|
| Boletos Gerados |
| Boletos Pagos Mensal |
| Cadastro Condomínios |
| DIMP Clientes |
| DIMP Transações |
| Financeiro |
| Indicação de Churn |
| Projeção de MRR |
| Transferências Pagas |
| Zoho Boletos Pagos Core |
| Zoho Boletos Pagos VS |
"Indicação de Churn" confirmado em 26/08/2026 (achado pelo usuário direto na tela) — não estava
mapeado antes; ver docs/historico-de-falhas.md.
Regras
- Cada tipo de relatório pede um conjunto diferente de filtros de data — 0, 1 ou 2 intervalos, com nomes diferentes conforme o tipo (ex.: "Boletos Gerados" pede "Data de Vencimento" e "Data Cadastro Conta Digital"; "Boletos Pagos Mensal" pede só "Período").
- "Transferências Pagas" pede 2 campos a mais que nenhum outro tipo tem: "Guid Administradora" e "Guid Condominio" (texto livre, não é um combo de seleção). Sem os dois preenchidos, o clique em "Gerar Relatório" não faz nada — nenhuma mensagem de campo obrigatório aparece, nenhuma requisição é disparada (confirmado testando: rede zerada até preencher os dois). O conteúdo não precisa ser um guid real de uma Administradora/Condomínio que exista — qualquer valor preenchido já desbloqueia a chamada (confirmado testando com um guid aleatório: aceito normalmente, 200).
- O mesmo tipo, com os mesmos filtros, não pode ser solicitado 2 vezes em menos de 15 minutos — a segunda tentativa é rejeitada com uma mensagem específica de bloqueio. É uma regra anti-duplicidade, não um limite técnico.
- Relatórios gerados ficam disponíveis pra consulta numa aba separada ("Visualizar Relatório") — a geração e a consulta são fluxos distintos na mesma tela.
Fonte: tela de Relatórios (abas "Gerar Relatório" / "Visualizar Relatório").
Autenticação e permissões
O Core tem dois níveis de autenticação, com escopos diferentes:
| Nível | Quem | Como loga | Pra quê serve |
|---|---|---|---|
| Entidade | Administradora ou Condomínio | usuário/senha próprios (definidos no credenciamento) | Operações no próprio escopo: criar um condomínio (se for Administradora), gerar boleto |
| Back-office | Usuário staff (funcionário) | usuário/senha + segundo fator (TOTP) pela tela de login | Operações administrativas que atravessam entidades: ex. trocar a Conta Geradora de um condomínio |
Regras
- Um token de Entidade não tem permissão nas rotas de back-office — usar o token de uma Administradora recém-criada numa operação administrativa (ex.: configurar Conta Geradora) resulta em acesso negado, mesmo autenticado.
- O login de back-office exige segundo fator (código do Microsoft Authenticator) — não existe atalho documentado pra obter um token de back-office só com usuário/senha, via API, sem passar por esse segundo fator.
- Isso implica uma ordem de dependência prática: pra fazer qualquer operação de back-office (como configurar o banco de um condomínio) logo depois de criar esse condomínio pela API de Entidade, precisa primeiro ter uma sessão de back-office logada — não dá pra fazer tudo só com a cadeia de credenciamento.
Fonte: comparação entre a API de credenciamento/boleto (/api/v1/...) e a API de back-office
(/adm/...) usada pela tela "Configuração Boleto".
- ⚠️ Falha de segurança CONFIRMADA (01/09/2026):
POST /job/contas-digitais/atualizar-flag-emissao(3ª categoria de rota,/job/*— não é Entidade nem Back-office) não exige autenticação nenhuma — chamada semAuthCGou comAuthCGinválido executa normalmente (204), disparando o recálculo da flag "Sem Emissão"/"Com Emissão" em TODAS as contas digitais ativas do ambiente. Contradiz um teste manual anterior (28/08/2026) que tinha confirmado 403 sem headers — pode ser regressão da migração Java 25/Spring Boot 3.5.7 em andamento, não confirmado. Travado emautenticacaoObrigatoria.cy.js. Detalhe completo emdocs/historico-de-falhas.md. - ⚠️ Falta de checagem de posse (cross-tenant) CONFIRMADA em 4 endpoints de Entidade — um token
de Entidade válido, mas de uma Administradora sem relação nenhuma com o Condomínio/dado alvo,
consegue agir sobre ele mesmo assim, só sabendo o guid: Gerar Boleto, Cancelar Boleto, Buscar
Boletos e Criar Condomínio (confirmado 02/09/2026 — este último chega a criar Condomínio de
verdade "dentro" da árvore de outra Administradora). Criar Conta Corrente ADM foi testado e
está protegido — rejeita corretamente, é o único confirmado seguro até agora dessa família.
Travado em
boletoGuidExistenteRegressao.cy.js,boletoCancelamentoCrossTenant.cy.jsecontaDigitalCrossTenant.cy.js. Gravidade real depende de uma pergunta ainda sem resposta: o Core é ferramenta interna da Partner (a tela de backoffice mostrar tudo é o design, não bug) — não confirmado se o tokenAuthCGde Entidade chega a ser usado por algum ERP externo do cliente final, ou se é estritamente interno. Detalhe completo emdocs/historico-de-falhas.md.
Como manter este documento
Ao construir ou revisar um teste no Cypress e descobrir algo que não estava aqui — um campo obrigatório, uma regra de bloqueio, um status novo, uma dependência entre telas — registre nesta página, na seção do módulo correspondente (ou crie uma seção nova, se for um módulo ainda não documentado). Prefira frases que descrevam o comportamento do produto, não o código do teste que o descobriu.