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_*.mdeLEGADO__*.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 (viaEntidade.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"
}
]
}
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 == 0 → false
- 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】
{
"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_USUARIOeCOD_SOL_CORRETORsã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 paraDateTime.Now(ignora valor do payload)【86:11†LEGADO_PropostaController_POST_Proposta-Novo.md†L116-L118】IND_DENTRO_ABRANGENCIAé calculado a partir deDSC_TERRITORIALvsCOD_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_USUARIOestiver 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=truee 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_CAPITALVAL_CAPITAL_SEGURADOQTD_VAL_COBERTURAVAL_FATURA_MINIMACOD_MODULOCOD_MODULO_ADICIONALVAL_ASSOCIADOVAL_NAO_ASSOCIADO【86:0†LEGADO_PropostaController_POST_Proposta-Novo.md†L139-L165】
E popula CotacaoCapital:
IND_TIPO_CAPITALQTD_VAL_COBERTURAVAL_COBERTURAVAL_FATURA_MINIMANUM_SEGURADOS(vem do payload)VAL_CUSTO_ASSOCIADO/VAL_CUSTO_NAO_ASSOCIADOCOD_MODULO,COD_MODULO_ADICIONALCOD_CORRETOR_COMISSAO = COD_USUARIOCOD_OPCOES_COMISSAOPRC_COMISSAO(deOpcoesComissao.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】.
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】.
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 retornatrue/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=trueeIND_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 vsDSC_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_COMERCIAISe 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_ATUALnoPOST /api/Proposta/Novoassume:"E"(normal) ou"B"(bloqueado), comBloqueio=trueno 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 AllowAllhabilitado (app.UseCors(...AllowAll...))【120:3†Autenticação - Detalhes.md†L8-L16】AllowInsecureHttp = true(token em HTTP)【120:3†Autenticação - Detalhes.md†L16-L21】ValidateClientAuthenticationchamacontext.Validated()sem validar client_id/secret (na prática aceita qualquer client)【120:10†Autenticação - Detalhes.md†L22-L27】- No
GrantResourceOwnerCredentials, também chamacontext.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-Idobrigató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_idrecebido).
- 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 nobroker_id/corretor_idreferenciado.- Bloquear com
403e gravar auditoria.
Observabilidade (API Nova)¶
Requisitos mínimos (projeto)¶
- Header
X-Correlation-Idobrigató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õesapp_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.listedquote.uf.listedquote.city.listedquote.cct.entities.selected(CCT)quote.conditions.listed(PME)quote.commission.options.listedquote.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-Idem todas as respostas - garante escrita em
audit_eventseapp_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.