Skip to content

Fluxo completo de COTAÇÃO no Portal Legado (CCT e PME ≠ CCT)

Projeto: API Nova
Documento: fluxo-cotacao-portal-legado.md
Timezone de referência: America/Sao_Paulo
Data de geração: 2026-02-24

Objetivo

Gerar um único documento que descreve, de ponta a ponta, o fluxo completo de Cotação Express no Portal Legado, cobrindo dois caminhos:

1) Fluxo A — CCT (Convenção Coletiva de Trabalho)
2) Fluxo B — PME ≠ CCT (produto PME “normal”, sem seleção de sindicatos)

O foco é integrar:

  • Ordem das telas (UI)endpoints chamados
  • O que cada endpoint retorna (principais campos)
  • Como os dados retornados alimentam os próximos passos
  • Como o payload final do POST /api/Proposta/Novo é montado no front e normalizado/alterado no back (código legado)
  • Divergências Swagger × código e implicações para a API Nova (MVP Parceiros)

Fontes de verdade usadas (obrigatórias)

Regra do projeto: não assumir nada fora dos arquivos/trace/código/SQL fornecidos. Quando faltar evidência: marcar [A CONFIRMAR] e listar no checklist final.

  • Sequência UI → endpoints: MVP_Cotacao_Fluxo_Portal_Legado.md【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L1-L12】【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L24-L36】
  • Contrato: swagger.json (prevalece como contrato)【78:10†swagger.json†L1-L4】
  • Fichas do legado por endpoint: arquivos LEGADO_*.md e LEGADO__*.md (ex.: CCT, PME, Proposta/Novo, etc.)【177:3†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L16-L49】【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L24】
  • Riscos de autenticação no legado: Autenticação - Detalhes.md【120:3†Autenticação - Detalhes.md†L8-L31】
  • Guardrails MVP/Parceiros (API Nova): Matriz_Politicas_API_Nova_PASI.md【116:0†Matriz_Politicas_API_Nova_PASI.md†L12-L24】【123:0†Matriz_Politicas_API_Nova_PASI.md†L55-L68】

Glossário rápido (termos e entidades)

  • Portal Legado / Portal do Corretor: Frontend atual que consome a PASI API (Legado).
  • PASI API (Legado): API atual (controllers C# chamando regras VB + SQL Server).
  • Cotação Express: fluxo acelerado de cotação, que culmina em POST /api/Proposta/Novo.
  • CCT: fluxo que depende de entidade patronal + entidade laboral (sindicatos) + abrangência territorial.
  • PME ≠ CCT: fluxo por produto + condição comercial (sem sindicatos).
  • COD_USUARIO / codCorretor / cod_corretor: no legado aparecem em vários lugares; ownership não é garantido pelo código em todos os endpoints (risco de “spoofing”)【177:6†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L27-L33】.
  • COD_OPCOES_COMISSAO: chave central do fluxo; a escolha de comissão determina capital, módulos e fatura mínima ao gravar a cotação (via Entidade.fncRetornaOpcoesComissao)【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】.

Visão geral do fluxo (alto nível)

Ponto comum aos 2 fluxos (CCT e PME)

1) Abrir “Cotação Express” → listar produtos elegíveis
2) Selecionar produto → carregar UFs e (no caso PME) condições comerciais
3) Selecionar UF/cidade → carregar cidades (e no caso CCT também atividades/entidades)
4) Escolher parâmetros do risco (CCT: sindicatos; PME: condição comercial)
5) Selecionar comissão → COD_OPCOES_COMISSAO
6) Identificar empresa (CNPJ) → validações/consulta Receita
7) Finalizar → POST /api/Proposta/Novo → retorna NUM_COTACAO, NUM_ADESAO, Bloqueio, etc.【173:2†LEGADO_PropostaController_POST_Proposta-Novo.md†L63-L76】

Onde os fluxos divergem

  • CCT: inclui seleção de atividade, sindicato patronal, sindicato laboral e consulta de abrangência territorial【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L15-L22】
  • PME ≠ CCT: inclui seleção de condição comercial e consulta de coberturas antes de escolher comissão【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L24-L36】

Fluxo A — Cotação Express (CCT)

A.1 Pré-requisitos específicos

  • Corretor logado no portal legado (Bearer token) — endpoints do fluxo usam [Authorize] (com exceções)【177:3†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L16-L23】【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L33-L41】
  • Corretor elegível para “Loja CCT” (checado por GET /api/Validar/CorretorLojaCCT)【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L16-L18】【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L1-L36】
  • Seleção de UF e Cidade
  • Seleção de atividade (categoria CCT)
  • Seleção de Sindicato Patronal e Sindicato Laboral
  • Seleção de opção de comissão (gera COD_OPCOES_COMISSAO)
  • Identificação de empresa via CNPJ (Consulta Receita) antes do POST /api/Proposta/Novo【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L8-L12】

A.2 Sequência UI → endpoints (CCT)

A tabela abaixo consolida a ordem observada no documento de fluxo do portal.
Observação: alguns passos na UI disparam mais de 1 endpoint (linhas repetidas no mesmo passo).

Passo na UI Endpoint Request (params) Principais campos do response Como é usado depois
Abrir Cotação Express GET /api/Proposta/ProdutosPME/Lista/{codCorretor} codCorretor (path) Produtos[], Resultado, Mensagem Popula a lista de produtos a serem selecionados【131:1†LEGADO__PropostaController__ListaProdutosPME__api-Proposta-ProdutosPME-Lista-codCorretor.md†L28-L48】
Selecionar produto GET /api/Corretor/ListaUFCotacao/Lista/{corretor} corretor (path) ListaUFCotacaoCorretor[] Popula dropdown de UFs de cotação【177:4†LEGADO__CorretorController__ListaUFCotacao__api-Corretor-ListaUFCotacao-Lista-corretor.md†L15-L27】
Selecionar produto GET /api/Validar/CorretorLojaCCT?COD_CORRETOR=... COD_CORRETOR (query) boolean Habilita/nega experiência “Loja CCT” para o corretor【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L13-L36】
Selecionar UF e cidade GET /api/Localidade/Cidade/{estado} estado (path, UF) Cidades[] (com COD_CIDADE, NOM_CIDADE) Popula dropdown de cidades; COD_CIDADE vai para próximos passos e para o POST final【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L45-L72】
Selecionar UF e cidade GET /api/Combo/Atividade/{CodigoCorretor}/{Estado}?Cidade=... CodigoCorretor (path), Estado (path), Cidade (query) Atividades[] (inclui COD_CATEGORIA_CCT) Popula lista de atividades/categoria CCT; o COD_CATEGORIA_CCT entra nas chamadas de sindicatos【92:1†LEGADO_AtividadeController_DetalhesDaAtividade_api-Combo-Atividade-codigoCorretor-Estado.md†L37-L54】
Selecionar atividade GET /api/Entidade/Combo/Patronal/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT} path params EntidadesPatronais[] (COD_ENTIDADE, NOM_ENTIDADE, …) Popula combo de sindicato patronal【153:1†LEGADO_EntidadeController_ListarSindicatosPatronais_api-Entidade-Comvo-Patronal-CodigoCorretor-Estado-CodCategoriaCCT.md†L24-L47】
Selecionar entidade patronal GET /api/Entidade/Combo/Laboral/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT}?COD_ENTIDADE_PATRONAL=...&Cidade=...&NOM_SINDICATO_LABORAL=... path + query EntidadesLaborais[] Popula combo de sindicato laboral (filtrado por patronal/cidade/nome parcial)【153:0†LEGADO_EntidadeController_ListarSindicatosLaborais_api-Entidade-Combo-Laboral-CodigoCorretor-Estado-CodCategoriaCCT.md†L24-L45】
Selecionar entidade laboral GET /api/Entidade/Combo/AbrangenciaTerritorial/{laboral}/{patronal}?NOM_CIDADE=...&cod_categoria_cct=... path + query DSC_TERRITORIAL, COD_CONVENCAO_COLETIVA (quando presente) Exibe abrangência territorial (lista de municípios) e alimenta payload do POST (DSC_TERRITORIAL) + possíveis validações【95:3†LEGADO__EntidadeController__AbrangenciaTerritorial__api-Entidade-Combo-AbrangenciaTerritorial-laboral-patronal.md†L36-L60】
“Próximo Passo” (pré-check) GET /api/Proposta/comparaUfCorretorCotacao/{codCorretor}/{ufCotacao} codCorretor, ufCotacao BaseViewModel (Resultado, Mensagem) Bloqueio/alerta antecipado se UF da cotação difere da UF do corretor【177:15†LEGADO__PropostaController__ComparaUfCorretorCotacao__api-Proposta-comparaUfCorretorCotacao-codCorretor-ufCotacao.md†L1-L17】
“Próximo Passo” (comissão) GET /api/Corretor/Comissao/{patronal}/{laboral}?cod_corretor=...&NOM_CIDADE=... path + query Comissao[] (inclui COD_OPCOES_COMISSAO, %) Exibe opções de comissão; seleção define COD_OPCOES_COMISSAO do POST final【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L21-L35】
Identificar empresa GET /api/ConsultaCNPJReceita?... query (CNPJ + corretor + flags) Dados da empresa na Receita (situação, nome, etc.) Prefill/validações antes de submeter o POST final【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L8-L10】【95:4†LEGADO_ConfiguracoesController_GET_ConsultaCNPJReceita.md†L25-L39】
Finalizar POST /api/Proposta/Novo body PropostaNovoPayload PropostaNovoViewModel (NUM_COTACAO, Bloqueio, …) Grava cotação (e possivelmente adesão) e retorna números para a UI avançar【78:10†swagger.json†L1-L4】【173:2†LEGADO_PropostaController_POST_Proposta-Novo.md†L63-L76】

Sequência acima conforme o documento do fluxo do Portal Legado【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L15-L22】【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L5-L12】.


A.3 Detalhamento por etapa (CCT)

A seguir, o detalhamento “passo a passo”, com:

  • objetivo do passo
  • request (com exemplo quando há)
  • response (principais campos)
  • como os dados alimentam o estado do front e os próximos endpoints/payload final

A3.1 Abrir Cotação Express → listar produtos

Endpoint
GET /api/Proposta/ProdutosPME/Lista/{codCorretor}【131:1†LEGADO__PropostaController__ListaProdutosPME__api-Proposta-ProdutosPME-Lista-codCorretor.md†L28-L48】

Request
- Path: codCorretor (int)

Response (principais campos)
- Envelope: Resultado, Mensagem
- Lista: Produtos[] com campos como: - COD_PRODUTO, NOM_PRODUTO - flags: IND_CONTRATACAO_PORTAL, IND_COTACAO_EXPRESS, IND_CONTRATACAO_IMEDIATA, IND_CONDICOES_ESPECIAIS【131:0†LEGADO__PropostaController__ListaProdutosPME__api-Proposta-ProdutosPME-Lista-codCorretor.md†L52-L67】

Exemplo de response (real, fornecido)

{
  "Resultado": true,
  "Mensagem": "Produtos listados com sucesso.",
  "Produtos": [
    {
      "COD_PRODUTO": 25,
      "NOM_PRODUTO": "PME",
      "IND_CONTRATACAO_PORTAL": "S",
      "IND_COTACAO_EXPRESS": "S",
      "IND_CONTRATACAO_IMEDIATA": "S",
      "IND_CONDICOES_ESPECIAIS": "N"
    }
  ]
}
Fonte: exemplo real na ficha do endpoint【131:1†LEGADO__PropostaController__ListaProdutosPME__api-Proposta-ProdutosPME-Lista-codCorretor.md†L28-L48】.

Como é usado depois (front)
- A UI usa Produtos[] para montar a lista/tiles de produtos.
- O valor selecionado (COD_PRODUTO) é carregado no estado do fluxo e reaparece depois no GET /api/ConsultaCNPJReceita e/ou no POST /api/Proposta/Novo (campo COD_PRODUTO)【111:19†MVP_Cotacao_Fluxo_Portal_Legado.md†L39-L45】【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L24】.
- [A CONFIRMAR]: no exemplo real retornou apenas produto “PME”; precisamos de 1 response real contendo o produto/flag que dispara o fluxo CCT (se é o mesmo endpoint, ou se CCT entra por outro mecanismo).


A3.2 Selecionar produto → carregar UFs + validar “Loja CCT”

A3.2.1 UFs disponíveis

Endpoint
GET /api/Corretor/ListaUFCotacao/Lista/{corretor}【177:4†LEGADO__CorretorController__ListaUFCotacao__api-Corretor-ListaUFCotacao-Lista-corretor.md†L6-L27】

Response (principais campos)
- ListaUFCotacaoCorretor[] com COD_ESTADO (sigla UF)【177:4†LEGADO__CorretorController__ListaUFCotacao__api-Corretor-ListaUFCotacao-Lista-corretor.md†L23-L27】

Divergência Swagger × código (importante)
- A ficha registra que o código observado não filtra por corretor, retornando UFs de forma genérica (27 UFs)【177:11†LEGADO__CorretorController__ListaUFCotacao__api-Corretor-ListaUFCotacao-Lista-corretor.md†L11-L17】.

Como é usado depois (front)
- Popula a lista de UFs para seleção. - ufCotacao é usado: - para buscar cidades (/Localidade/Cidade/{estado}), - para buscar atividades (/Combo/Atividade/{CodigoCorretor}/{Estado}), - e no pré-check /Proposta/comparaUfCorretorCotacao/{codCorretor}/{ufCotacao}【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L18-L20】【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L5-L7】.

A3.2.2 Validar corretor “Loja CCT”

Endpoint
GET /api/Validar/CorretorLojaCCT?COD_CORRETOR=...【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L8-L23】

Response
- boolean (root) — true quando o corretor está presente em um parâmetro (LISTACORRETORLOJACCT-PORTAL)【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L25-L36】.

Regras/observações de implementação (legado)
- Se COD_CORRETOR == 0false
- Exceções são silenciadas e retornam false【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L50-L60】

Como é usado depois (front)
- Habilita UI/rota “Loja CCT” quando retorna true.
- [A CONFIRMAR]: qual é o comportamento exato do front quando retorna false (bloqueia fluxo CCT? redireciona para PME?).


A3.3 Selecionar UF/cidade → carregar cidades + atividades

A3.3.1 Cidades

Endpoint
GET /api/Localidade/Cidade/{estado}【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L11-L18】

Autenticação (divergência)
- O controller está marcado como [AllowAnonymous] (não exige token)【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L33-L41】.
- Swagger não documenta 401/403; mas, por ser anônimo, isso faz sentido no legado. Na API Nova, avaliar se continuará público ou se ficará protegido.

Response (principais campos)
- Cidades[] com COD_CIDADE, NOM_CIDADE + Resultado, Mensagem【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L45-L72】

Como é usado depois (front)
- Usuário escolhe cidade; o front mantém: - COD_CIDADE → usado no POST /api/Proposta/Novo (payload) - NOM_CIDADE → aparece em várias queries no fluxo CCT: - Combo/Atividade?Cidade=... - Entidade/Combo/Laboral?...&Cidade=... - AbrangenciaTerritorial?...&NOM_CIDADE=... - Corretor/Comissao?...&NOM_CIDADE=...【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L18-L22】【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L31-L37】

A3.3.2 Atividades (categoria CCT)

Endpoint
GET /api/Combo/Atividade/{CodigoCorretor}/{Estado}?Cidade=...【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L18-L20】

Response (principais campos)
- Lista de atividades; a ficha indica uso de COD_CATEGORIA_CCT para os próximos passos【92:1†LEGADO_AtividadeController_DetalhesDaAtividade_api-Combo-Atividade-codigoCorretor-Estado.md†L37-L54】.

Como é usado depois (front)
- Usuário seleciona uma atividade/categoria CCT. - O COD_CATEGORIA_CCT vira um path param para buscar sindicatos patronais e laborais【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L20-L22】.


A3.4 Selecionar sindicatos (patronal → laboral) + abrangência territorial

A3.4.1 Sindicato Patronal

Endpoint
GET /api/Entidade/Combo/Patronal/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT}【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L20-L21】

Response (principais campos)
- Lista EntidadesPatronais[] com: - COD_ENTIDADE - NOM_ENTIDADE - NOM_ABREVIADO (quando presente)【153:1†LEGADO_EntidadeController_ListarSindicatosPatronais_api-Entidade-Comvo-Patronal-CodigoCorretor-Estado-CodCategoriaCCT.md†L24-L47】

Como é usado depois (front)
- Usuário seleciona COD_ENTIDADE_PATRONAL. - Esse código: - Filtra a busca do sindicato laboral, - Entra no endpoint de comissão (path), - Entra no POST /api/Proposta/Novo (payload CCT).

A3.4.2 Sindicato Laboral

Endpoint
GET /api/Entidade/Combo/Laboral/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT}?COD_ENTIDADE_PATRONAL=...&Cidade=...&NOM_SINDICATO_LABORAL=...【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L21-L22】

Response (principais campos)
- Lista EntidadesLaborais[] (campos similares ao patronal: COD_ENTIDADE, NOM_ENTIDADE, etc.)【153:0†LEGADO_EntidadeController_ListarSindicatosLaborais_api-Entidade-Combo-Laboral-CodigoCorretor-Estado-CodCategoriaCCT.md†L24-L45】

Como é usado depois (front)
- Usuário seleciona COD_ENTIDADE_LABORAL. - Esse código: - Entra na consulta de abrangência territorial, - Entra no endpoint de comissão (path), - Entra no POST /api/Proposta/Novo (payload CCT).

A3.4.3 Abrangência territorial

Endpoint
GET /api/Entidade/Combo/AbrangenciaTerritorial/{laboral}/{patronal}?NOM_CIDADE=...&cod_categoria_cct=...【105:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L21-L22】

Response (principais campos)
A ficha registra retorno com campos como:

  • DSC_TERRITORIAL (texto com municípios)
  • COD_CONVENCAO_COLETIVA (quando aplicável)
  • campos adicionais de UI: DSC_CLAUSULA, DSC_VIGENCIA, NOM_SORTEIO, VAL_SORTEIO【95:3†LEGADO__EntidadeController__AbrangenciaTerritorial__api-Entidade-Combo-AbrangenciaTerritorial-laboral-patronal.md†L36-L60】

Como é usado depois (front)
- Exibição ao usuário (confirmar se está “dentro da abrangência”). - Armazenar DSC_TERRITORIAL para enviar no POST /api/Proposta/Novo (payload).

Ponto crítico (código legado do POST): o backend calcula IND_DENTRO_ABRANGENCIA verificando se DSC_TERRITORIAL contém COD_CIDADE (convertido para string)【86:10†LEGADO_PropostaController_POST_Proposta-Novo.md†L120-L126】.
- [A CONFIRMAR]: isso parece incoerente (territorial é lista de nomes, COD_CIDADE é numérico). Precisamos confirmar como o portal preenche esses campos (ver checklist).


A3.5 Pré-check de UF (antes da comissão)

Endpoint
GET /api/Proposta/comparaUfCorretorCotacao/{codCorretor}/{ufCotacao}【177:15†LEGADO__PropostaController__ComparaUfCorretorCotacao__api-Proposta-comparaUfCorretorCotacao-codCorretor-ufCotacao.md†L8-L17】

Objetivo
Validar se UF informada na cotação é a mesma do corretor (via cadastro) — usado como pré-check no portal【177:15†LEGADO__PropostaController__ComparaUfCorretorCotacao__api-Proposta-comparaUfCorretorCotacao-codCorretor-ufCotacao.md†L1-L3】.

Como é usado depois (front)
- Se retornar Resultado=false/mensagem de divergência, a UI pode bloquear/alertar antes de buscar comissões.
- Independente do pré-check, o POST /api/Proposta/Novo também aplica regra de bloqueio por UF e retorna Bloqueio=true/false (detalhado mais abaixo)【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L79-L96】.


A3.6 Selecionar comissão (CCT)

Endpoint
GET /api/Corretor/Comissao/{cod_entidade_patronal}/{cod_entidade_laboral}?cod_corretor=...&NOM_CIDADE=...【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L15-L35】

Request
- Path: cod_entidade_patronal, cod_entidade_laboral
- Query: - cod_corretor (na prática obrigatório, apesar do Swagger)
- NOM_CIDADE (na prática obrigatório, apesar do Swagger)【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L52-L63】

Response
- Comissao[] com: - COD_OPCOES_COMISSAO - VAL_PERCENTUAL_COMISSAO - VAL_ASSOCIADO
- + Resultado, Mensagem【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L23-L48】

Como é usado depois (front)
- Usuário escolhe uma opção → o front guarda COD_OPCOES_COMISSAO.
- Esse campo vira entrada principal do POST /api/Proposta/Novo.
- No backend, COD_OPCOES_COMISSAO é usado para derivar: - COD_MODULO, COD_MODULO_ADICIONAL - IND_TIPO_CAPITAL, VAL_CAPITAL_SEGURADO, QTD_VAL_COBERTURA - VAL_FATURA_MINIMA, VAL_ASSOCIADO, VAL_NAO_ASSOCIADO【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】.

Regras técnicas relevantes (legado)
- Determina “CCT candidata” usando MAX(COD_CONVENCAO_COLETIVA) e verifica cidade ∈ DSC_TERRITORIAL (LIKE), com riscos de SQL injection/performance【177:2†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L28-L38】【177:9†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L8-L12】.
- Filtra condições comerciais por IND_STATUS='A' e IND_COTACAO_EXPRESS='S' e aplica regra de exclusividade por corretor【177:2†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L35-L49】【177:10†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L3-L12】.


A3.7 Identificar empresa (Consulta Receita)

Endpoint
GET /api/ConsultaCNPJReceita?...【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L8-L10】

Propósito
“Guarda-chuva” de validações/consultas de empresa no fluxo do portal【111:25†MVP_Cotacao_Fluxo_Portal_Legado.md†L60-L63】.

Request (parâmetros observados no fluxo)
No fluxo CCT, o MVP registra query com:
- NumIdentificacao (CNPJ)
- COD_CORRETOR
- ContratacaoImediata=false
- COD_CCT=...
- COD_PRODUTO=...【107:0†MVP_Cotacao_Fluxo_Portal_Legado.md†L8-L10】

Response (principais campos)
A ficha do endpoint registra retorno com dados da Receita (situação cadastral, razão social, etc.)【95:4†LEGADO_ConfiguracoesController_GET_ConsultaCNPJReceita.md†L25-L39】.

Como é usado depois (front)
- Preencher NOM_EMPRESA e campos auxiliares. - Confirmar se empresa está apta (situação cadastral).
- Campos de Receita podem ser enviados ao POST /api/Proposta/Novo (ex.: DSC_SITUACAO_RECEITA, DAT_SITUACAO_RECEITA) — [A CONFIRMAR] quais são realmente enviados no front.


A.4 Finalização do Fluxo A: POST /api/Proposta/Novo (CCT)

A4.1 Contrato (Swagger)

  • Endpoint: POST /api/Proposta/Novo
  • Body: PropostaNovoPayload
  • Response 200: PropostaNovoViewModel【78:10†swagger.json†L1-L4】

Observação importante: o contrato do Swagger lista muitas propriedades no payload, mas o código do legado sobrescreve vários campos (ver A4.3).


A4.2 Exemplo real de request (CCT)

Request real fornecido (CCT):【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L24】

POST {{base_url}}/api/Proposta/Novo
Authorization: Bearer {{token}}
Content-Type: application/json
{
  "COD_USUARIO": 50174,
  "COD_CIDADE": 9151,
  "NUM_SEGURADOS": 3,
  "NUM_IDENTIFICACAO": "31425495000199",
  "NOM_EMPRESA": "EMPRESA TESTE",
  "COD_OPCOES_COMISSAO": 2502,
  "COD_ENTIDADE_PATRONAL": 108,
  "COD_ENTIDADE_LABORAL": 2012,
  "DSC_TERRITORIAL": "ABAETÉ\nBIQUINHAS\nBOM DESPACHO\n...",
  "DSC_GEOLOCALIZACAO_ACEITE_CORRETOR": "lat=-19.9;lng=-43.9",
  "DSC_ENDERECO_IP_ACEITE_CORRETOR": "189.0.0.1",
  "DSC_EMAIL_ACEITE_CORRETOR": "corretor@exemplo.com",
  "NOM_CONTATO_SOLICITANTE": "Fulano",
  "NOM_EMAIL_SOLICITANTE": "fulano@exemplo.com",
  "NUM_TELEFONE_SOLICITANTE": "31999999999"
}

Nota: o exemplo real foi truncado no arquivo (lista territorial completa). Para o fluxo, o importante é: COD_OPCOES_COMISSAO, entidades, cidade, CNPJ, empresa e dados de aceite.


A4.3 O que o backend realmente usa/sobrescreve no POST /api/Proposta/Novo

O PropostaService.Novo (legado) faz:

1) Monta objetos (UsoNegocios, Cotacao, CotacaoCapital, OpcoesComissao, Corretor, Cidade)
2) Força vários campos e normaliza o payload
3) Decide status/bloqueio por UF e por “Cotação PME”
4) Deriva dados de capital/fatura/módulos a partir de COD_OPCOES_COMISSAO
5) Persiste via objCotacao.fncGravarCotacaoExpress(...) e retorna NUM_COTACAO etc.【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L101-L136】

Campos explicitamente sobrescritos/forçados no legado

  • COD_USUARIO e COD_SOL_CORRETOR são forçados para o mesmo valor (o corretor)【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L101-L107】
  • Campos “fixos” hard-coded:
  • IND_TIPO_SOLICITANTE = "C"
  • IND_CANAL_VENDA = "P"
  • IND_CONHECEU_PASI = "N"
  • IND_ACOMPANHAMENTO_SITUACAO = "P"
  • COD_RESPONSAVEL = "173"【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L108-L116】
  • DAT_ACEITE_CORRETOR_DATETIME é sobrescrito para DateTime.Now (ignora valor do payload)【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L116-L118】
  • IND_DENTRO_ABRANGENCIA é calculado a partir de DSC_TERRITORIAL vs COD_CIDADE (ver discussão [A CONFIRMAR])【86:10†LEGADO_PropostaController_POST_Proposta-Novo.md†L120-L126】.

Regra de bloqueio por UF (status E/B + Bloqueio)

O legado decide:

  • Se a cotação é “PME” (função FncCotacaoPME) → IND_STATUS_ATUAL = "E"
  • Senão, se COD_USUARIO estiver em uma lista hard-coded de exceções → IND_STATUS_ATUAL="E"
  • Senão, se UF corretor != UF cidade:
  • IND_STATUS_ATUAL="B"
  • viewModel.Bloqueio=true e mensagem de link bloqueado
  • Caso contrário:
  • IND_STATUS_ATUAL="E"
  • viewModel.Bloqueio=false【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L79-L96】

Status/transições além de E/B: não há evidência suficiente neste material. [A CONFIRMAR] semântica completa e transições.

Derivação de capital/módulos/fatura mínima por COD_OPCOES_COMISSAO

O legado chama Entidade.fncRetornaOpcoesComissao(COD_OPCOES_COMISSAO) e extrai:

  • IND_TIPO_CAPITAL
  • VAL_CAPITAL_SEGURADO
  • QTD_VAL_COBERTURA
  • VAL_FATURA_MINIMA
  • COD_MODULO
  • COD_MODULO_ADICIONAL
  • VAL_ASSOCIADO
  • VAL_NAO_ASSOCIADO【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】

E popula CotacaoCapital:

  • IND_TIPO_CAPITAL
  • QTD_VAL_COBERTURA
  • VAL_COBERTURA
  • VAL_FATURA_MINIMA
  • NUM_SEGURADOS (vem do payload)
  • VAL_CUSTO_ASSOCIADO / VAL_CUSTO_NAO_ASSOCIADO
  • COD_MODULO, COD_MODULO_ADICIONAL
  • COD_CORRETOR_COMISSAO = COD_USUARIO
  • COD_OPCOES_COMISSAO
  • PRC_COMISSAO (de OpcoesComissao.FncVAL_PERCENTUAL_COMISSAO())【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L128-L135】

A4.4 Response do POST /api/Proposta/Novo (CCT) e uso no portal

Exemplo real de response (CCT):【173:2†LEGADO_PropostaController_POST_Proposta-Novo.md†L63-L76】

{
  "NUM_COTACAO": 543210,
  "NUM_ADESAO": 123456,
  "NUM_PROPOSTA": null,
  "NUM_VERSAO_CAPITAL": 1,
  "Bloqueio": false,
  "Mensagem": "Cotação gravada com sucesso.",
  "mensagemLinkBloqueado": null
}

Como o portal usa
- NUM_COTACAO: identifica a cotação gravada; tipicamente usado para navegar para telas seguintes (resumo, adesão, etc.) — [A CONFIRMAR] quais telas pós-cotação.
- NUM_ADESAO: parece indicar criação/consulta de adesão associada (o código tenta consultar adesão após gravar a cotação)【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L136-L136】.
- Bloqueio/mensagemLinkBloqueado: usados para bloquear o fluxo quando UF corretor ≠ UF cidade.


A.5 Linhagem de dados (CCT) — do UI + endpoints até Proposta/Novo

Objetivo: deixar explícito de onde vem cada campo relevante e como chega ao payload final.

A5.1 Estado do front (campos “de sessão”)

Campo (estado UI) Origem Observação
COD_USUARIO Sessão/token do corretor No legado, também é enviado como número no payload【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L17】
COD_PRODUTO Seleção em Produtos[] [A CONFIRMAR] produto/flag que caracteriza CCT
UF (ufCotacao) Seleção UI, baseada no retorno de ListaUFCotacao Pré-check (comparaUfCorretorCotacao) e usado indiretamente no bloqueio do POST
COD_CIDADE/NOM_CIDADE Seleção UI a partir de /Localidade/Cidade/{UF} COD_CIDADE vai ao payload; NOM_CIDADE vai a queries no fluxo CCT

A5.2 Data mapping para o POST /api/Proposta/Novo (campos principais)

campo_origem transformação campo_destino (PropostaNovoPayload) Evidência
Sessão do corretor (sem transformação) COD_USUARIO Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L17】
Seleção de cidade pegar COD_CIDADE (int) COD_CIDADE Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L11-L17】
Input do usuário remover máscara NUM_IDENTIFICACAO Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L15-L20】
Consulta Receita selecionar razão social/nome NOM_EMPRESA Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L15-L20】
Seleção sindicatos COD_ENTIDADE patronal COD_ENTIDADE_PATRONAL Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L17-L20】
Seleção sindicatos COD_ENTIDADE laboral COD_ENTIDADE_LABORAL Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L17-L20】
Abrangência territorial texto do response DSC_TERRITORIAL Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L19-L23】
Seleção comissão Comissao[].COD_OPCOES_COMISSAO COD_OPCOES_COMISSAO Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L15-L20】
UI (aceite) valores coletados no navegador DSC_GEOLOCALIZACAO_ACEITE_CORRETOR, DSC_ENDERECO_IP_ACEITE_CORRETOR, DSC_EMAIL_ACEITE_CORRETOR Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L19-L24】
UI (contatos) input NOM_CONTATO_SOLICITANTE, NOM_EMAIL_SOLICITANTE, NUM_TELEFONE_SOLICITANTE Exemplo request【173:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L19-L24】

A5.3 Campos que o backend calcula/força (não confiar no front)

campo_destino como o legado define impacto
COD_SOL_CORRETOR payload.COD_USUARIO Vincula corretor solicitante【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L101-L107】
COD_RESPONSAVEL "173" hard-coded Risco de regra fixa sem configuração【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L108-L116】
IND_CANAL_VENDA "P" hard-coded Normalização server-side【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L108-L116】
DAT_ACEITE_CORRETOR_DATETIME DateTime.Now Legado ignora timestamp do front【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L116-L118】
IND_STATUS_ATUAL / Bloqueio regra UF + lista exceções + PME Pode bloquear fluxo【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L79-L96】
COD_MODULO, VAL_FATURA_MINIMA, etc. derivado de COD_OPCOES_COMISSAO Determina capital e precificação【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】

A.6 Diagrama de sequência (CCT)

Baseado no diagrama do documento do fluxo do portal legado【112:11†MVP_Cotacao_Fluxo_Portal_Legado.md†L40-L72】.

sequenceDiagram participant Front as Portal Legado participant API as PASI API (Legado) Front->>API: GET /api/Proposta/ProdutosPME/Lista/{codCorretor} API-->>Front: Lista de produtos Front->>API: GET /api/Corretor/ListaUFCotacao/Lista/{corretor} API-->>Front: Lista de UFs Front->>API: GET /api/Validar/CorretorLojaCCT?COD_CORRETOR=... API-->>Front: true/false Front->>API: GET /api/Localidade/Cidade/{estado} API-->>Front: Lista de cidades Front->>API: GET /api/Combo/Atividade/{CodigoCorretor}/{Estado}?Cidade=... API-->>Front: Lista de atividades Front->>API: GET /api/Entidade/Combo/Patronal/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT} API-->>Front: Lista de entidades patronais Front->>API: GET /api/Entidade/Combo/Laboral/{CodigoCorretor}/{Estado}/{COD_CATEGORIA_CCT}?COD_ENTIDADE_PATRONAL=...&Cidade=...&NOM_SINDICATO_LABORAL=... API-->>Front: Lista de entidades laborais Front->>API: GET /api/Entidade/Combo/AbrangenciaTerritorial/{laboral}/{patronal}?NOM_CIDADE=...&cod_categoria_cct=... API-->>Front: Abrangência territorial + CCT Front->>API: GET /api/Proposta/comparaUfCorretorCotacao/{codCorretor}/{ufCotacao} API-->>Front: Resultado + Mensagem Front->>API: GET /api/Corretor/Comissao/{patronal}/{laboral}?cod_corretor=...&NOM_CIDADE=... API-->>Front: Lista de comissões Front->>API: GET /api/ConsultaCNPJReceita?NumIdentificacao=...&COD_CORRETOR=...&ContratacaoImediata=false&COD_CCT=...&COD_PRODUTO=... API-->>Front: Dados da Receita Front->>API: POST /api/Proposta/Novo (payload) API-->>Front: NUM_COTACAO + Bloqueio + etc.

Fluxo B — Cotação Express (PME ≠ CCT)

B.1 Pré-requisitos específicos

  • Corretor logado (Bearer)
  • Seleção de produto PME
  • Seleção de UF/cidade
  • Seleção de condição comercial + visualização de coberturas
  • Seleção de comissão por condição comercial (COD_OPCOES_COMISSAO)
  • Consulta Receita (CNPJ)
  • POST /api/Proposta/Novo

B.2 Sequência UI → endpoints (PME ≠ CCT)

Passo na UI Endpoint Request (params) Principais campos do response Como é usado depois
Abrir Cotação Express GET /api/Proposta/ProdutosPME/Lista/{codCorretor} codCorretor Produtos[] Lista produtos
Selecionar produto GET /api/Corretor/ListaUFCotacao/Lista/{corretor} corretor ListaUFCotacaoCorretor[] Lista UFs
Selecionar produto GET /api/Proposta/CondicoesComerciais/Lista/{codProduto}?codCorretor=... codProduto (path), codCorretor (query) CondicoesComerciais[] Popula combo “Condição Comercial”【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L27-L31】
Selecionar UF e cidade GET /api/Localidade/Cidade/{estado} UF Cidades[] Escolha de cidade (COD_CIDADE para POST)
Selecionar condição comercial GET /api/Proposta/CondicoesComerciais/Coberturas/Lista/{codCondicaoComercial} codCondicaoComercial (path) Coberturas[] Exibe coberturas vinculadas à condição【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L33-L36】
Próximo Passo → comissão GET /api/Corretor/ComissaoPorCondicaoComercial/{cod_condicoes_comerciais}/{cod_corretor}?lojaPme=false path + query Comissao[] Seleção de COD_OPCOES_COMISSAO no fluxo PME【111:19†MVP_Cotacao_Fluxo_Portal_Legado.md†L37-L40】
Identificar empresa GET /api/ConsultaCNPJReceita?...&COD_PRODUTO=... query Dados Receita Prefill/validações
Finalizar POST /api/Proposta/Novo payload viewModel Grava cotação

Sequência conforme o documento do fluxo do Portal Legado【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L24-L36】【111:19†MVP_Cotacao_Fluxo_Portal_Legado.md†L37-L46】.


B.3 Detalhamento por etapa (PME ≠ CCT)

B3.1 Listar condições comerciais (produto PME)

Endpoint
GET /api/Proposta/CondicoesComerciais/Lista/{codProduto}?codCorretor=...【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L27-L31】

Response (principais campos)
A ficha indica retorno com CondicoesComerciais[] contendo o identificador da condição comercial (usado nos próximos endpoints)【141:0†LEGADO__PropostaController__ListaCondicoesComerciais__api-Proposta-CondicoesComerciais-Lista-codProduto.md†L44-L60】.

Como é usado depois (front)
- Seleção de uma condição comercial → COD_CONDICOES_COMERCIAIS: - entra no endpoint de coberturas - entra no endpoint de comissão por condição - entra no POST /api/Proposta/Novo (payload PME)【111:19†MVP_Cotacao_Fluxo_Portal_Legado.md†L37-L40】.

Regras/validações (legado)
- Lista apenas condições IND_STATUS='A' e IND_COTACAO_EXPRESS='S' e com opções de comissão/fatura mínima (ver ficha) [A CONFIRMAR] detalhes completos se necessário.


B3.2 Listar coberturas da condição comercial

Endpoint
GET /api/Proposta/CondicoesComerciais/Coberturas/Lista/{codCondicaoComercial}【70:1†MVP_Cotacao_Fluxo_Portal_Legado.md†L33-L36】

Response (principais campos)
- Coberturas[] (códigos/nomes/valores)【141:2†LEGADO__PropostaController__ListaCoberturasCondicoesComerciais__api-Proposta-CondicoesComerciais-Coberturas-Lista-codCondicaoComercial.md†L45-L59】.

Como é usado depois (front)
- Renderizar a tela de coberturas/benefícios.
- Não há evidência de que o usuário selecione uma cobertura específica para enviar no POST /Proposta/Novo; parece ser apenas informativo. [A CONFIRMAR] se existe seleção de cobertura no front.


B3.3 Selecionar comissão por condição comercial (PME)

Endpoint
GET /api/Corretor/ComissaoPorCondicaoComercial/{cod_condicoes_comerciais}/{cod_corretor}?lojaPme=false【111:19†MVP_Cotacao_Fluxo_Portal_Legado.md†L37-L40】

Response (principais campos)
- Comissao[] com COD_OPCOES_COMISSAO, VAL_PERCENTUAL_COMISSAO, VAL_ASSOCIADO【177:0†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L38-L60】.

Regra do parâmetro lojaPme
- lojaPme=false: retorna todas opções
- lojaPme=true: retorna apenas 1 opção (a de maior percentual por causa do ORDER BY ASC e “pega último”)【177:8†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L10-L14】

Como é usado depois (front)
- Seleção de COD_OPCOES_COMISSAO para enviar no POST /api/Proposta/Novo. - No backend, COD_OPCOES_COMISSAO determina: - se a cotação é classificada como “PME” (FncCotacaoPME) e, portanto, força IND_STATUS_ATUAL="E"【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L79-L85】. - capital/módulos/fatura mínima (mesma derivação do CCT)【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】.


B.4 Exemplo real de request (PME) no POST /api/Proposta/Novo

Request real fornecido (PME):【173:1†LEGADO_PropostaController_POST_Proposta-Novo.md†L28-L42】

{
  "COD_USUARIO": 1,
  "COD_CIDADE": 1234,
  "NUM_SEGURADOS": 10,
  "NUM_IDENTIFICACAO": "12345678000199",
  "NOM_EMPRESA": "EMPRESA PME",
  "COD_OPCOES_COMISSAO": 123,
  "COD_CONDICOES_COMERCIAIS": 3706,
  "COD_PRODUTO": 25,
  "DSC_GEOLOCALIZACAO_ACEITE_CORRETOR": "lat=-23.5;lng=-46.6",
  "DSC_ENDERECO_IP_ACEITE_CORRETOR": "200.0.0.1",
  "DSC_EMAIL_ACEITE_CORRETOR": "corretor@exemplo.com"
}

Observação: campos de sindicatos (COD_ENTIDADE_*, DSC_TERRITORIAL) não aparecem no exemplo PME — coerente com o fluxo PME ≠ CCT.


B.5 Diagrama de sequência (PME ≠ CCT)

Baseado no diagrama do documento do fluxo do portal legado【111:20†MVP_Cotacao_Fluxo_Portal_Legado.md†L47-L58】.

sequenceDiagram participant Front as Portal Legado participant API as PASI API (Legado) Front->>API: GET /api/Proposta/ProdutosPME/Lista/{codCorretor} API-->>Front: Lista de produtos Front->>API: GET /api/Corretor/ListaUFCotacao/Lista/{corretor} API-->>Front: Lista de UFs Front->>API: GET /api/Proposta/CondicoesComerciais/Lista/{codProduto}?codCorretor=... API-->>Front: Lista de condições comerciais Front->>API: GET /api/Localidade/Cidade/{estado} API-->>Front: Lista de cidades Front->>API: GET /api/Proposta/CondicoesComerciais/Coberturas/Lista/{codCondicaoComercial} API-->>Front: Lista de coberturas Front->>API: GET /api/Corretor/ComissaoPorCondicaoComercial/{cod_condicoes_comerciais}/{cod_corretor}?lojaPme=false API-->>Front: Lista de comissões Front->>API: GET /api/ConsultaCNPJReceita?NumIdentificacao=...&COD_CORRETOR=...&ContratacaoImediata=false&COD_PRODUTO=... API-->>Front: Dados da Receita Front->>API: POST /api/Proposta/Novo (payload) API-->>Front: NUM_COTACAO + Bloqueio + etc.

Divergências Swagger × Código (principais achados)

Objetivo: registrar pontos onde o contrato (Swagger) e a implementação (C#/VB) divergem — isso deve orientar o redesenho da API Nova.

1) GET /api/Corretor/Comissao
- Swagger marca cod_corretor e NOM_CIDADE como opcionais, mas o código valida como obrigatórios e pode quebrar com parse【177:1†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L52-L63】.

2) GET /api/Corretor/ListaUFCotacao/Lista/{corretor}
- Swagger sugere retorno “por corretor”, mas o código observado retorna lista genérica (27 UFs), sem filtrar por corretor【177:11†LEGADO__CorretorController__ListaUFCotacao__api-Corretor-ListaUFCotacao-Lista-corretor.md†L11-L17】.

3) GET /api/Localidade/Cidade/{estado}
- Controller permite [AllowAnonymous] (sem token). Isso pode ou não estar refletido no Swagger; na API Nova precisamos decidir se será público【138:0†LEGADO__LocalidadeController__BuscarCidade__api-Localidade-Cidade-estado.md†L33-L41】.

4) POST /api/Proposta/Novo
- O Swagger expõe muitas propriedades, mas o backend: - força COD_RESPONSAVEL=173, IND_CANAL_VENDA="P" etc. - ignora DAT_ACEITE_CORRETOR_DATETIME do payload (substitui por DateTime.Now)【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L108-L118】. - Implicação: a API Nova deve decidir o que é input vs server-managed.

5) Mensagens/erros
- Vários endpoints documentam apenas 200, mas na prática existe 401 por [Authorize], e falhas de validação/negócio voltam como 200 + Resultado=false (padrão legado)【177:5†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L43-L47】.


Regras e validações observadas (bloqueios, UF, loja CCT, etc.)

1) Loja CCT (habilitação por lista)

  • Habilitação é feita por LISTACORRETORLOJACCT-PORTAL (string separada por ;) e o endpoint retorna true/false【177:14†LEGADO__ConfiguracoesController__ValidaCorretorLojaCCT__api-Validar-CorretorLojaCCT.md†L50-L59】.
  • Exceções são silenciadas (risco de falso negativo).

2) Bloqueio por UF

  • Pré-check: GET /api/Proposta/comparaUfCorretorCotacao/{codCorretor}/{ufCotacao}【177:15†LEGADO__PropostaController__ComparaUfCorretorCotacao__api-Proposta-comparaUfCorretorCotacao-codCorretor-ufCotacao.md†L1-L17】
  • Regra final (server-side): se UF corretor ≠ UF cidade, pode retornar Bloqueio=true e IND_STATUS_ATUAL="B"【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L86-L96】.

3) CCT candidata por cidade na territorial (endpoint de comissão CCT)

  • Busca CCT “candidata” usando MAX(COD_CONVENCAO_COLETIVA) e comparando cidade vs DSC_TERRITORIAL (LIKE)【177:2†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L28-L38】.
  • Há riscos técnicos: SQL injection, performance, ambiguidade de versionamento【177:9†LEGADO__CorretorController__BuscarComissao__api-Corretor-Comissao-cod_entidade_patronal-cod_entidade_laboral.md†L8-L12】.

4) PME por condição comercial (endpoint de comissão PME)

  • Filtra opções de comissão por COD_CONDICOES_COMERCIAIS e respeita corretor exclusivo (quando aplicável)【177:8†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L4-L9】.

Status / transições (evidência vs pendências)

Evidência disponível:

  • IND_STATUS_ATUAL no POST /api/Proposta/Novo assume:
  • "E" (normal) ou "B" (bloqueado), com Bloqueio=true no viewModel【89:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L79-L96】.

Sem evidência suficiente no material fornecido:

  • Lista completa de statuses além de E/B (ex.: A, P, etc.)
  • Transições depois da gravação da cotação (ex.: cotação → proposta → adesão)
    ➡️ [A CONFIRMAR] (ver checklist).

Segurança

1) Legado — fragilidades observadas

A implementação de auth no legado tem vários pontos críticos:

  • CORS AllowAll habilitado (app.UseCors(...AllowAll...))【120:3†Autenticação - Detalhes.md†L8-L16】
  • AllowInsecureHttp = true (token em HTTP)【120:3†Autenticação - Detalhes.md†L16-L21】
  • ValidateClientAuthentication chama context.Validated() sem validar client_id/secret (na prática aceita qualquer client)【120:10†Autenticação - Detalhes.md†L22-L27】
  • No GrantResourceOwnerCredentials, também chama context.Validated() após montar claims (risco de credenciais fracas/fluxo permissivo)【120:4†Autenticação - Detalhes.md†L22-L39】

Risco direto no fluxo de cotação: diversos endpoints recebem cod_corretor em path/query e não há evidência de validação de vínculo com o usuário do token (risco de spoofing)【177:6†LEGADO__CorretorController__BuscarComissaoPorCondicaoComercial__api-Corretor-ComissaoPorCondicaoComercial-cod_condicoes_comerciais-cod_corretor.md†L27-L33】.


2) API Nova — como deve ficar (MVP Parceiros)

Baseado nos guardrails do projeto:

  • API exposta a parceiros em /v1/partners/*【116:0†Matriz_Politicas_API_Nova_PASI.md†L12-L16】
  • Auth: OAuth2 Client Credentials (Auth interno) + gateway【116:0†Matriz_Politicas_API_Nova_PASI.md†L16-L21】
  • X-Correlation-Id obrigatório (gateway gera se ausente) + auditoria/log em SQL Server【116:0†Matriz_Politicas_API_Nova_PASI.md†L20-L24】【123:0†Matriz_Politicas_API_Nova_PASI.md†L55-L68】
  • Allowlist de IP no gateway para parceiros【116:0†Matriz_Politicas_API_Nova_PASI.md†L16-L21】

Recomendação explícita para Cotação (ownership + scopes)

O gateway valida token, mas o core deve validar ownership (não confiar em cod_corretor/broker_id recebido).

  • Definir scopes mínimos para cotação (ex.: quotes:create, quotes:read) — [A CONFIRMAR] nomes oficiais de scopes.
  • Validar vínculo:
  • partner_id (do token) deve estar autorizado para operar no broker_id/corretor_id referenciado.
  • Bloquear com 403 e gravar auditoria.

Observabilidade (API Nova)

Requisitos mínimos (projeto)

  • Header X-Correlation-Id obrigatório (gerado no gateway se ausente) e propagado end-to-end【123:0†Matriz_Politicas_API_Nova_PASI.md†L55-L63】
  • Persistência em SQL Server (retenção 60 dias):
  • audit_events: para auditoria de chamadas/decisões
  • app_errors: para exceções/erros【123:0†Matriz_Politicas_API_Nova_PASI.md†L64-L68】

Eventos sugeridos para o fluxo de cotação

A Matriz descreve a existência das tabelas e retenção; o catálogo de eventos abaixo é uma sugestão mínima alinhada ao fluxo.

  • quote.products.listed
  • quote.uf.listed
  • quote.city.listed
  • quote.cct.entities.selected (CCT)
  • quote.conditions.listed (PME)
  • quote.commission.options.listed
  • quote.company.lookup.performed (Consulta Receita)
  • quote.created (POST /quotes)

[A CONFIRMAR]: esquema exato (DDL) das tabelas audit_events e app_errors (campos obrigatórios).


Idempotência (API Nova)

Requisito do MVP (mesmo que o legado não tenha):

  • Implementar idempotência em criação de cotação via chave composta:
  • (partner_id, external_reference)

Comportamento esperado: - Primeira requisição: cria cotação e retorna quote_id (ou NUM_COTACAO equivalente).
- Requisições repetidas com a mesma chave: retornar a mesma resposta (200/201) sem duplicar registros.

[A CONFIRMAR]: status code padrão (201 vs 200) e envelope de retorno do contrato Partners.


Testes mínimos (unit + integração)

Unit tests (core API Nova)

1) Validação de entrada - obrigatórios por fluxo (CCT vs PME)
- formatos: CNPJ, UF, NUM_SEGURADOS > 0

2) Ownership / autorização - partner_id sem vínculo com broker_id → 403
- scope faltando → 403

3) Regra de bloqueio UF - UF corretor ≠ UF cidade → blocked=true + motivo
- exceções (whitelist) não devem ser hard-coded na API Nova; devem ser config/feature flag [A CONFIRMAR].

4) Idempotência - repetição com mesma chave retorna mesma cotação

Integração (end-to-end, por fluxo)

CCT

  • feliz: seleciona entidades + comissão → cria cotação
  • falha: sem COD_ENTIDADE_PATRONAL/COD_ENTIDADE_LABORAL → 422
  • bloqueio: UF divergente → bloqueia criação ou cria com status “blocked” (decisão) [A CONFIRMAR]

PME

  • feliz: condição comercial + comissão → cria cotação
  • falha: condição inválida → 422

Observabilidade

  • garante X-Correlation-Id em todas as respostas
  • garante escrita em audit_events e app_errors (em erro)

Checklist final de pendências [A CONFIRMAR]

1) Como o portal decide CCT vs PME: existe flag no ProdutosPME/Lista? Existe “produto CCT” retornando nesse endpoint? (precisamos de 1 response real do endpoint no contexto CCT).
2) Campos exatos retornados por ConsultaCNPJReceita e quais o front envia no POST /Proposta/Novo (enviar 1 request/response real).
3) DSC_TERRITORIAL vs COD_CIDADE: confirmar como o legado define “dentro da abrangência” (há suspeita de bug na regra que busca COD_CIDADE dentro de texto territorial).
4) Telas pós-POST /Proposta/Novo: quais passos/telas o portal abre usando NUM_COTACAO/NUM_ADESAO.
5) Catálogo completo de status (além de E e B) e transições (cotação → proposta → adesão).
6) Contrato de erros da API Nova (envelope padrão, status codes para validação/negócio).
7) DDL (schema/índices) das tabelas mínimas e logs/auditoria: - legado: tabelas de log (quando citado como “onde grava”)
- API Nova: audit_events e app_errors.
8) Nomenclatura oficial de scopes para Parceiros (Matriz aponta existência de scopes, mas não define nomes finais).


Referências adicionais do projeto (não são “fonte de verdade” do legado)

  • Documentos de arquitetura (API única vs por público, gateway segmentado, etc.) foram carregados no projeto e podem ser usados para decisões de desenho da API Nova. Não foram necessários para descrever o fluxo legado, mas podem ser consultados para a fase de arquitetura.