Nesta página

Regras de negócio · Pessoas

RN-PESSOAS-001 · Nome de exibição

Condição: a criação ou o PATCH resulta em pessoa sem name e sem companyName.

Resultado: a API recusa com 422 RULE_VIOLATION. Nome e razão social podem coexistir.


RN-PESSOAS-002 · CPF/CNPJ (regra R9)

Condição: cpfCnpj está presente.

Resultado: a API guarda somente dígitos e exige 11 dígitos para FISICA, 14 para JURIDICA e 11 ou 14 sem natureza informada. cpfCnpj junto de hasNoCpfCnpj: true é recusado com 400 VALIDATION_FAILED.

Exceção: a importação legada aceita documento inválido e marca identityStatus: pendente.


RN-PESSOAS-003 · CPF/CNPJ único

Condição: outro registro já possui o mesmo CPF/CNPJ.

Resultado: a API recusa com 409 CONFLICT.

Exceção: a importação legada registra skip_conflict.


RN-PESSOAS-004 · Núcleos existentes

Condição: nucleos é informado.

Resultado: as siglas são normalizadas em maiúsculas, sem repetição, e todas precisam existir no catálogo de núcleos; caso contrário, a API recusa com 422.

Exceção: a importação legada não valida a existência.


RN-PESSOAS-005 · Origem do cliente

Condição: o papel CLIENT está presente ao final da operação.

Resultado: originUoSigla é obrigatória (422) e não pode ser apagada de quem é cliente.

Exceção: importação legada.


RN-PESSOAS-006 · Formato da sigla de origem

originUoSigla é uma sigla livre, validada apenas por formato; não exige existência no catálogo de núcleos.

Condição: originUoSigla é informada.

Resultado: a sigla obedece a ^[A-Z0-9][A-Z0-9-]{1,39}$ e é diferente de LSA; caso contrário, a API recusa com 422.


RN-PESSOAS-007 · Tipo de originação derivado

Condição: a sigla de origem chega sem originationType.

Resultado: a API grava originationType: DECLARED_MANUAL e o registra na trilha junto da sigla.


RN-PESSOAS-008 · Originação pertence à presidência

Condição: o PATCH envia qualquer um dos sete campos de originação (originUoSigla, originDate, originationType, originCity, referredByPersonId, referralType, referralChannel).

Resultado: a API recusa com 403, salvo ator com acesso institucional ou PRES entre as siglas do seu alcance, mesmo quando o valor enviado é igual ao gravado.

Exceção: na criação, qualquer autor informa a originação.


RN-PESSOAS-009 · Indicação consistente

Condição: referralType é informado sem referredByPersonId.

Resultado: a API recusa com 422; referralType só existe junto de referredByPersonId.


RN-PESSOAS-010 · Indicador existe e não é a própria pessoa

Condição: referredByPersonId é informado.

Resultado: a pessoa indicadora precisa existir e ser diferente da própria pessoa; caso contrário, a API recusa com 422.

Exceção: importação legada.


RN-PESSOAS-011 · CLIENT nasce com carteira

Condição: o papel CLIENT é concedido, na criação ou no PATCH.

Resultado: a API exige portfolioId e portfolioEffectiveFrom em data civil até hoje (422), carteira existente (404) com dono em vigência aberta (422) e ator com gestão EXPINS (403); portfolioEffectiveTo não é aceito.


RN-PESSOAS-012 · Sem CLIENT, sem carteira

Condição: uma pessoa sem CLIENT recebe campos de carteira.

Resultado: a API recusa com 422.


RN-PESSOAS-013 · Encerrar CLIENT

Condição: o papel CLIENT é retirado.

Resultado: a API exige portfolioEffectiveTo igual a ontem no dia civil de America/Recife e não aceita novo início na mesma operação.


RN-PESSOAS-014 · Troca de carteira por rota própria

Condição: o PATCH envia campos de carteira sem transição do papel CLIENT.

Resultado: a API recusa com 422; a troca de carteira ocorre apenas por POST /v1/people/{personId}/portfolio-transfers.


RN-PESSOAS-015 · Alteração concorrente

Condição: a transição de CLIENT encontra updatedAt ou papel divergentes sob bloqueio.

Resultado: a API recusa com 409.


RN-PESSOAS-016 · Conta da Pessoa no cadastro

A conta é opcional e nasce apenas no cadastro conjunto (account) ou em POST /v1/users.

Condição: account é enviado em POST /v1/people.

Resultado: a API exige papel USER ou ASSOCIATE e personType: FISICA (422), ator com Acesso Global (403), integração Appwrite ligada (503) e e-mail livre (409). Se o Appwrite recusar a identidade, a API responde 502 e nada é persistido.


RN-PESSOAS-017 · Titular de conta permanece pessoa física

Condição: o PATCH altera personType de uma pessoa que possui conta.

Resultado: a API recusa com 422 (restrição do banco).


RN-PESSOAS-018 · Alcance de leitura e edição

Condição: qualquer leitura ou PATCH de pessoa.

Resultado: o acesso institucional alcança tudo; caso contrário, o ator alcança a pessoa quando é seu autor, compartilha um núcleo com ela ou ela é cliente de carteira de uma associação do ator. Pessoa inexistente e pessoa fora do alcance recebem o mesmo 404, para impedir enumeração.

Dependências de acesso: toda conta ativa precisa de personId; sem ele, a resolução do alcance efetivo responde 403 ("Conta da Pessoa sem mapa vigente"). A lotação vigente do ator — núcleo ou área e seus subnúcleos — define as siglas do alcance. Uma participação associativa vigente dá leitura dos clientes das carteiras da associação. A legibilidade de entrevistas, processos e atendimentos acompanha a legibilidade da Pessoa.


RN-PESSOAS-019 · Token de Sistema não escreve

Condição: o ator não é um usuário pessoal (kind !== 'user').

Resultado: a API recusa com 403 em criação, edição, transferência e escrita de Representados.

Exceção: a leitura é permitida.


RN-PESSOAS-020 · Filhos em lista inteira

Condição: o PATCH envia phones, emails, addresses, documents ou bankAccounts.

Resultado: a lista enviada substitui a lista inteira; omitir a lista a mantém; enviar [] a apaga.


RN-PESSOAS-021 · Trilha somente do que mudou

Condição: PATCH de pessoa.

Resultado: a API registra person.updated com os campos cujo valor difere do gravado; reenviar valores iguais não gera evento. A trilha nunca derruba a escrita e nunca carrega segredos.


RN-PESSOAS-022 · Busca e filtros só estreitam

Condição: GET /v1/people com busca ou filtros.

Resultado: um valor desconhecido devolve página vazia e nunca amplia o escopo do ator; termo de busca com menos de dois caracteres é ignorado.


RN-PESSOAS-023 · Aniversário civil

Condição: consulta de aniversariantes.

Resultado: a API usa o dia civil de America/Recife e compara apenas mês e dia; 29/02 só corresponde a 29/02.


RN-PESSOAS-024 · Relacionamento sem autorrelação

Condição: personId do corpo é igual à âncora.

Resultado: a API recusa com 422.


RN-PESSOAS-025 · Relacionamento em forma canônica única

Condição: a mesma dupla com o mesmo laço é registrada por qualquer ponta.

Resultado: a API recusa com 409; existe uma única linha por dupla e tipo, na forma canônica.


RN-PESSOAS-026 · Relacionamento sem contradição

Condição: o laço é incompatível com outro já registrado entre a mesma dupla.

Resultado: a API recusa com 409, nomeando o id e o tipo da relação existente.


RN-PESSOAS-027 · Relacionamento não concede acesso

Condição: listagem com expand=true.

Resultado: contraparte fora do alcance de leitura do ator sai com name: null.


RN-PESSOAS-028 · Checklist não bloqueante

Condição: PATCH /v1/people/{personId}/document-checklist/{kind}.

Resultado: upsert idempotente e reversível, exigindo Acesso de Núcleo ou superior; o checklist não bloqueia nenhuma operação.


RN-PESSOAS-029 · Derivados fora do contrato

Condição: toda escrita de pessoa.

Resultado: a API recalcula searchText (inclusive com a inscrição na OAB), nameSortKey e birthDayKey e nunca serializa os campos de linhagem.


RN-PESSOAS-030 · Sem exclusão

Condição: —

Resultado: nenhuma rota apaga pessoa. Também não há inativação nem indicador de vida; as chaves estrangeiras de outros domínios são majoritariamente RESTRICT.


RN-PESSOAS-031 · Conta para associado

Condição: account é enviado com roles contendo USER ou ASSOCIATE.

Resultado: a API aceita a conta, pois todo associado é usuário; sem um desses papéis, recusa com 422 ("papel USER ou ASSOCIATE").


RN-PESSOAS-032 · Associação nasce com o associado

Condição: association é enviado em POST /v1/people.

Resultado: a API exige papel ASSOCIATE (422), personType: FISICA (422), gestão de Associações EXPINS (403), effectiveFrom até effectiveTo (422), lamarckPercentage entre 50.0000 e 100.0000 com lamarckPercentage mais percentage igual a 100.0000 (422) e sigla única (409). Valores padrão: name igual a "Associação de" seguido do nome da pessoa, effectiveFrom igual a hoje em America/Recife, percentage igual a 100.0000 menos lamarckPercentage.

Autorização: Acesso Global ou Administração do Sistema sempre; Acesso de Área quando a área vigente é a do núcleo EXPINS; Acesso de Núcleo quando lotado em EXPINS. Caso contrário, 403.

Exceção: o bloco não existe no PATCH.


RN-PESSOAS-035 · Carteira própria do parceiro

Condição: o papel PARTNER está presente na criação ou é concedido no PATCH.

Resultado: a API cria uma Carteira vazia com ownerPersonId igual à pessoa; se já existe, reaproveita. A mudança entra na trilha como ownedPortfolioId.


RN-PESSOAS-036 · Perder PARTNER

Condição: o PATCH remove o papel PARTNER.

Resultado: a API apaga a Carteira própria somente se ela nunca teve cliente, vigente ou histórico; caso contrário, recusa com 422 ("transfira-os antes de remover o papel") e a pessoa continua parceira.


RN-PESSOAS-037 · Carteira de parceiro exige o papel

Condição: uma Carteira é criada com dono do tipo pessoa.

Resultado: pessoa inexistente responde 404; pessoa sem PARTNER responde 422; segunda Carteira do mesmo dono responde 409.


RN-PESSOAS-038 · Leitura da carteira do parceiro

Condição: GET /v1/portfolios ou GET /v1/portfolios/{id} alcança uma Carteira com dono pessoa.

Resultado: a Carteira é legível pelo acesso institucional ou por quem lê a Pessoa dona; nunca pelo eixo associativo. Fora do alcance, a API responde 404.


RN-PESSOAS-039 · Representados exigem advogado externo

Condição: representedPartyIds não vazio.

Resultado: a API exige o papel EXTERNAL_LAWYER no estado resultante (422).


RN-PESSOAS-040 · Representado existente

Condição: um id em representedPartyIds.

Resultado: id inexistente responde 422 (não 404), para o campo não revelar o catálogo; id repetido na lista responde 400.


RN-PESSOAS-041 · Retirar EXTERNAL_LAWYER

Condição: o PATCH remove o papel de uma pessoa com Representados gravados sem enviar a lista.

Resultado: a API recusa com 422.

Exceção: enviar representedPartyIds: [] junto resolve.


RN-PESSOAS-042 · Conjunto de Representados substitui

Condição: representedPartyIds no PATCH.

Resultado: a lista substitui o conjunto inteiro; a trilha registra a mudança apenas se o conjunto mudou, sem considerar a ordem.


RN-PESSOAS-043 · Representado único

Condição: POST ou PATCH em /v1/represented-parties.

Resultado: o par (lower(name), kind) é único; repetição responde 409.


RN-PESSOAS-044 · Representado vinculado não se apaga

Condição: DELETE /v1/represented-parties/{id}.

Resultado: Representado vinculado a alguma pessoa responde 409.


RN-PESSOAS-045 · OAB em par

Condição: o estado resultante tem oabNumber sem oabUf ou oabUf sem oabNumber.

Resultado: a API recusa com 422 ("informe os dois ou apague os dois").


RN-PESSOAS-046 · OAB de pessoa física ou jurídica, exigida do Advogado externo

Condição: a pessoa tem inscrição na OAB (oabNumber e oabUf) ou tem o papel EXTERNAL_LAWYER.

Resultado: a inscrição na OAB é aceita para pessoa física e para pessoa jurídica (sociedade de advogados), sempre com número e UF juntos (RN-PESSOAS-045). Todo Advogado externo, pessoa física ou jurídica, tem a inscrição informada no cadastro.

Vigência: a aceitação em pessoa jurídica depende de lamarck-nemesis/nead-hub-api#84; até a sua integração, a API recusa com 422 a OAB em pessoa diferente de FISICA. A mesma alteração passa a exigir a inscrição do EXTERNAL_LAWYER na API (422 RULE_VIOLATION): no cadastro, sempre; na edição, só quando ela cria a falta (acrescentar o papel sem OAB ou apagar a OAB de quem tem o papel), de modo que cadastros antigos sem OAB continuam editáveis. O formulário do Hub aplica a mesma exigência (lamarck-nemesis/nead-hub#225).


RN-PESSOAS-047 · OAB na busca

Condição: GET /v1/people com search ou oabNumber.

Resultado: oabNumber compara por igualdade exata; a busca livre também encontra pela inscrição.


RN-PESSOAS-048 · Uma conta bancária principal

Condição: bankAccounts com mais de um item isPrimary: true.

Resultado: a API recusa com 422.


RN-PESSOAS-049 · Pix pareado

Condição: pixKey sem pixKeyType ou pixKeyType sem pixKey.

Resultado: a API recusa com 422.


RN-PESSOAS-050 · Listagem sem listas pesadas

Condição: GET /v1/people.

Resultado: os itens vêm sem emails, documents e bankAccounts.

Exceção: a ficha e as respostas de escrita trazem as três listas.


RN-PESSOAS-051 · Importação ignora contas bancárias e OAB

Condição: bun run people:import.

Resultado: a pessoa importada nasce com bankAccounts vazia e sem OAB.


RN-PESSOAS-052 · Credencial única (Identidade)

Condição: a conta é criada por account.

Resultado: a conta guarda passwordHash nulo e appwriteSubject aleatório; a senha fica apenas no Appwrite; a troca de senha local responde 403.

Exceção: contas locais legadas mantêm o hash.


RN-PESSOAS-053 · Inscrição na OAB única por advogado

Condição: uma pessoa recebe uma inscrição na OAB (número e UF) que já pertence a outra pessoa, ou uma segunda inscrição.

Resultado: cada pessoa tem uma única inscrição, e uma inscrição não se repete entre pessoas. A implementação vigente ainda não aplica a unicidade; a resposta da API nesse caso aguarda implementação.


RN-PESSOAS-054 · Cada dono tem a sua Carteira

Condição: uma Carteira é criada para uma Pessoa Parceira, uma Associação ou uma Unidade de Negócio.

Resultado: cada dono tem a sua própria Carteira, com exatamente um dono por Carteira. Não existe entidade separada de vínculo do parceiro.


RN-PESSOAS-055 · Nome livre e cadastro rápido exclusivos de Juiz e Perito

Condição: o usuário informa o Juiz ou o Perito na Ficha da Pessoa.

Estado: fluxo previsto.

Resultado: o nome pode ser informado sem cadastro obrigatório. Quando a pessoa não estiver cadastrada, o fluxo oferece cadastro rápido com matrícula do servidor localizada publicamente por busca e leitura de páginas com auxílio de IA. Para peritos médicos, a consulta utiliza o conselho de classe nacional ou local. Essa mudança não se aplica aos demais papéis.


RN-PESSOAS-056 · Unidade de atendimento habitual

Condição: o cadastro informa onde a pessoa costuma ser atendida.

Resultado: serviceUnitId registra o escritório físico em que a pessoa costuma ser atendida. O campo é opcional; quando enviado, precisa identificar uma unidade cadastrada, senão a API responde 422.


RN-PESSOAS-057 · Foto vinculada a um Documento

Condição: o cadastro informa a foto da pessoa.

Resultado: avatarDocumentId aponta para um Documento existente; a foto não é guardada como arquivo próprio da Pessoa. O campo é opcional; Documento inexistente responde 422.


RN-PESSOAS-058 · Conta bancária com operação, observações e Benefício

Condição: o cadastro informa uma conta bancária.

Resultado: a conta aceita operation e notes, ambos opcionais, e o tipo BENEFIT para conta destinada ao recebimento de benefício.


RN-PESSOAS-059 · URL opcional na credencial de serviço

Condição: o usuário registra ou altera uma credencial de serviço da pessoa.

Resultado: a credencial aceita url opcional, com protocolo http ou https explícito; outros protocolos são recusados.


RN-PESSOAS-060 · Campos novos sem preenchimento retroativo

Condição: pessoas cadastradas antes da unidade de atendimento habitual, da foto, da operação, das observações bancárias e da URL de credencial.

Resultado: esses campos permanecem vazios até serem informados; o sistema não os preenche retroativamente.


RN-PESSOAS-061 · Registro de relacionamento tipado

Condição: o usuário registra Expectativa, Preferência, Afinidade ou Atenção na ficha.

Resultado: o registro entra numa coleção única da Pessoa, tipado por type (EXPECTATION, PREFERENCE, AFFINITY ou ATTENTION), com autoria e data gravadas pela API. Criação, alteração e exclusão entram no histórico da Pessoa.


RN-PESSOAS-062 · Relacionamento segue a permissão de editar a pessoa

Condição: o usuário cria, altera ou exclui um registro de relacionamento.

Resultado: exige-se a mesma autorização de edição da Pessoa; não existe permissão própria para o Relacionamento. A leitura dos registros acompanha o alcance de leitura da Pessoa (RN-PESSOAS-018).


RN-PESSOAS-063 · Campos próprios de cada tipo de relacionamento

Condição: o usuário cria ou altera um registro de relacionamento.

Estado: em implementação na API.

Resultado: preferenceCategory vale só para PREFERENCE; attentionKind vale só para ATTENTION e é obrigatório nele; caseId vale só para EXPECTATION; detail vale só para AFFINITY e ATTENTION. Campo enviado a tipo que não o aceita, ou ATTENTION sem attentionKind, responde 422.


RN-PESSOAS-064 · Expectativa ligada a processo da própria pessoa

Condição: a Expectativa informa caseId.

Estado: em implementação na API.

Resultado: o processo precisa ter a pessoa como cliente; caso contrário, a API responde 422.


RN-PESSOAS-065 · Histórico do relacionamento com o registro

Condição: um registro de relacionamento é criado, alterado ou excluído.

Estado: em implementação na API.

Resultado: o histórico da Pessoa guarda o registro como ficou ou, na exclusão, como estava. A linha do tempo desses registros é lida filtrando o histórico da Pessoa por resourceType=person-relationship-record.


RN-PESSOAS-066 · Nota de atendimento separada do Registro de Atendimento

Condição: o usuário registra um atendimento simplificado na Ficha da Pessoa.

Estado: em implementação na API.

Resultado: a nota guarda texto, forma, quem iniciou, finalidade, satisfação, autor e data, com os vocabulários do Registro de Atendimento. A forma é obrigatória: Presencial (mode = PRESENCIAL, sem canal) ou um canal remoto (mode = REMOTO com channel em WHATSAPP, TELEFONE, VIDEOCONFERENCIA, EMAIL ou REDE_SOCIAL). Quem iniciou é obrigatório: INBOUND (Recebido) ou OUTBOUND (Realizado). A finalidade é opcional e tem um único valor do vocabulário de finalidade do assunto do Registro de Atendimento. A satisfação é opcional. O texto segue o formato do relato da entrevista: o HTML do editor da ficha, com parágrafos, negrito, itálico, listas e menções a pessoa, entrevista e processo, até 20.000 caracteres; marcação sem texto é recusada. Notas registradas antes da forma e de quem iniciou continuam legíveis, com esses campos vazios. A nota não é um Registro de Atendimento: não tem unidade, núcleo, assuntos nem ciclo de vida. Ler a nota exige ler a Pessoa; registrá-la exige a autorização de edição da Pessoa.


RN-PESSOAS-068 · Textos gerados acompanham a mudança do contexto

Condição: os dados de origem de um texto gerado da Ficha da Pessoa mudam — Resumo do Relacionamento, Sugestão de atendimento do processo ou Explicação da movimentação.

Estado: em implementação na API.

Resultado: o texto é gerado de novo quando o contexto muda de forma material. A leitura (GET) nunca gera e informa upToDate. O pedido de atualização (POST …/refresh) só age se a impressão dos dados de origem mudou; o Jev avalia se a mudança é material e, se não for, o texto atual é mantido como atualizado. Diferença muito extensa ou avaliação de baixa confiança contam como material; sem o Jev disponível, a mudança fica pendente e o texto anterior permanece com upToDate: false. Cada impressão é avaliada no máximo uma vez por intervalo de nova tentativa. Falha da avaliação ou da geração mantém o texto anterior com upToDate: false.

Pendência: cliente sem Carteira

Não há decisão sobre deixar sem Carteira uma pessoa que continua com o papel CLIENT. Até essa decisão, valem RN-PESSOAS-011 e RN-PESSOAS-013.

Camadas do domínio