Alice · Squad Alfa
S2 — Cadastro de Proposta P2 QD2-26 · deadline 2026-05-22 · Discovery

S2 — Cadastro de Proposta P2

Habilitar o cadastro autônomo de propostas P2 (30–99 vidas) dentro do Portal de Vendas, eliminando a dependência de múltiplos sistemas internos (Cognito + Heco + planilha + Portal do RH).

9
Entregáveis detalhados
36
Dúvidas mapeadas
29 / 7
Resolvidas / em aberto
7
Serviços impactados

Mapa visual da jornada

flowchart LR L["Login
(#1 gating)"] --> A1["Aba Corretor
(#8 reuso)"] A1 --> A2["Aba Empresa
(#8 reuso)"] A2 --> A3["Aba Coligadas
(#8 reuso)"] A3 --> A4["Aba Contratação
(#2 extensão P2)"] A4 --> A5["Aba Beneficiários
(#3 modo planilha)"] A5 --> A6["Anexos Obrigatórios
(#7+#9 reuso)"] A6 --> S["Submit"] S --> B1["Entidades backend
(#4)"] B1 --> B2["Trigger Hubspot
(#6)"] B1 --> B3["Ativação pré-paga
N boletos (#5)"] style L fill:#FCE6F3,stroke:#E738AD,stroke-width:2px style A4 fill:#FCE6F3,stroke:#E738AD,stroke-width:2px style A5 fill:#FCE6F3,stroke:#E738AD,stroke-width:2px style B1 fill:#FCE6F3,stroke:#E738AD,stroke-width:2px style B3 fill:#FCE6F3,stroke:#E738AD,stroke-width:2px style B2 fill:#E1E9FE,stroke:#6189FA

Em rosa: entregáveis com mudança P2 substancial. Em azul: extensão menor.

Visão geral

Objetivo

Eliminar a dependência atual de múltiplos sistemas internos (Cognito + Heco + planilha + Portal do RH) e dar paridade mínima com operadoras PME no momento da implantação. Esta entrega é o primeiro desbloqueio do funil de P2 via corretores — sem ela, todo o roadmap de QD2 trava.

Escopo

✅ Dentro do escopo

  • Entidades a nível empresa: company, contract, N subcontracts, proposal
  • Responsável financeiro
  • Persistência dos documentos da empresa

✗ Fora do escopo

  • Cadastro de produtos e preços (segue manual via Ops no Heco)
  • Cadastro de membros (segue planilha + batch no Portal do RH em S3-S5)
  • Validação de conteúdo dos documentos da empresa (Ops valida)

Estratégia

Reaproveitar o formulário de P1, adicionando a opção 30–99 vidas no campo "número de vidas contratando", que destrava as regras específicas de P2 nas demais abas.

Premissas

🔵 Notion vinda direto do Notion oficial 💡 Recomendação técnica nossa, pendente validação produto

Diferenças P1 vs P2

DimensãoP1P2
Filiais/coligadasInclusão só na 1ª importaçãoInclusão a qualquer momento (mas só coleta inicial nesta entrega)
FaturamentoSeparação por CNPJ é exceçãoEmpresa define no cadastro: conjunto ou separado por CNPJ
Subcontratos1 por contratoN por contrato (1 por CNPJ se separado)
CoparticipaçãoEmbutida no produto selecionado3 opções (Total/Flexível/Sem) + percentual (10/20/30%)
Pré/PósPré-pagoPré-pago

Entregáveis

#EntregávelTipoStatus
1Permissionamento de acesso ao form P2Backend✅ Detalhado
2Aba Contratação — extensão P2Front + Back✅ Detalhado
3Aba Beneficiários — modo planilhaFront + Back✅ Detalhado
4Criação de entidades no backend P2Back (ABS + Acquisition)✅ Detalhado
5Ativação pré-paga com N subcontratosBack✅ Detalhado
6Trigger HubSpot com campos P2Back (Revenue)✅ Detalhado
7+8+9Abas e documentos reusadosValidação✅ Reuso confirmado
1

Permissionamento de acesso ao form P2

Backend

TL;DR

Permissionamento P2 não vai usar feature flag. Decisão da reunião 2026-05-06 (Vittoria): a capability "pode cadastrar P2" é uma propriedade persistente da corretora — gerenciada por ops via tela de cadastro/edição da corretora no backoffice, e modelada como lista extensível (não boolean) para suportar futuros tipos de proposta.

Modelo: allowedProposalTypes: List<ProposalType> em SalesFirm + 2 colunas de auditoria. Migration backfilla [P1] em todas as corretoras existentes (Q-040). FF P1 (proposal_enabled_sales_firm_ids) é descontinuada na mesma entrega.

O que muda

  1. Migration: 3 colunas em sales_firm (allowed_proposal_types TEXT[], proposal_types_updated_at, proposal_types_updated_by_staff_id) + backfill [P1] em todas as corretoras
  2. Modelo + Transport + DataService: 3 campos novos em SalesFirm + enum ProposalType { P1, P2 }
  3. Endpoint admin: PATCH /admin/sales-firms/{id}/proposal-types em sales-channel-domain-service com role check
  4. Form field no backoffice: multi-select P1/P2 na tela de cadastro/edição da corretora — Squad Alfa mantém
  5. Reescrita do gating no BFF: AuthControllersalesFirm.allowedProposalTypes em vez de FF (uma chamada externa a menos)
  6. Gate server-side em updatePlan: mantém regra (defesa em profundidade), agora lendo do SalesFirm
  7. Frontend: sem mudança — enabledModules.includes('P2_PROPOSAL_CREATE') continua liberando "30–99 vidas"
  8. Cleanup FF P1: remover helper antigo + descontinuar FF proposal_enabled_sales_firm_ids

Diagrama D1 — Login & visibilidade da UI

sequenceDiagram autonumber actor User as SalesFirmStaff participant Front as front-app-sales-channel participant Auth as AuthController participant FirmSvc as SalesFirmService User->>Front: Login (Firebase magic link) Front->>Auth: GET /me (getLogged) Auth->>FirmSvc: get(salesFirmId) FirmSvc-->>Auth: SalesFirm (allowedProposalTypes) Note over Auth: enabledModules inclui
PROPOSAL_CREATE se P1 ∈ list
P2_PROPOSAL_CREATE se P2 ∈ list Auth-->>Front: StaffResponse(enabledModules) Note over Front: libera opção "30-99 vidas"
na aba Contratação

Diagrama D2 — Validação server-side

sequenceDiagram autonumber actor Staff participant Front participant Ctrl as ProposalDraftController participant FirmSvc as SalesFirmService Staff->>Front: Seleciona "30-99 vidas" Front->>Ctrl: PUT /v2/proposals/draft/{id}/plan Ctrl->>FirmSvc: get(callerSalesFirmId) FirmSvc-->>Ctrl: SalesFirm alt P2 ∉ firm.allowedProposalTypes Ctrl-->>Front: 403 Forbidden else P2 ∈ firm.allowedProposalTypes Ctrl-->>Front: 200 OK end

Diagrama D3 — Adm habilita P2 numa corretora

sequenceDiagram autonumber actor Ops as Adm Alice participant BO as Backoffice UI participant SCDS as sales-channel-domain-service participant DB as DB (SalesFirm) Ops->>BO: edita corretora
marca P2 no multi-select BO->>SCDS: PATCH /admin/sales-firms/{id}/proposal-types SCDS->>SCDS: valida role admin do caller SCDS->>DB: UPDATE sales_firm SET
allowed_proposal_types,
proposal_types_updated_at,
proposal_types_updated_by_staff_id DB-->>SCDS: ok SCDS-->>BO: 200 OK Note over Ops,BO: A partir de agora, staffs
dessa corretora têm
P2_PROPOSAL_CREATE no /me.

Decisões

Entregável #1 com todas as dúvidas resolvidas — pronto para entrar em desenvolvimento.

2

Aba Contratação — extensão P2

Front + Back

TL;DR

Aba onde P2 nasce no fluxo do usuário. Endpoint PUT /v2/proposals/draft/{id}/plan já existe — só estender payload. Adicionar 1 valor no enum de range (THIRTY_TO_NINETY_NINE) em 3 camadas, 1 branch no use case GetAvailableProductsUseCase, e 2 colunas novas na Proposal (copay não é capturada hoje no fluxo Proposal — vem do produto selecionado).

3 campos novos exclusivos para 30-100 vidas

CampoQuando apareceValoresBackend
Faturamento das filiais/coligadasSe willHaveAffiliated == trueBoleto único · Boleto por CNPJaffiliatedBillingPreference (#4)
Pacote de coparticipaçãoSempre (range = 30-100)Total · Flexível · SemcopaymentPackage.packageType
% de cobrança copartSe pacote ≠ Sem (default 30%)10% · 20% · 30%copaymentPackage.percentage

Mudanças no enum em 3 camadas

CamadaArquivoMudança
OpenAPIsales-portal-bff/build/openapi/...+ _30Minus99
TransportRangeMembersToBeTransport.kt+ THIRTY_TO_NINETY_NINE("30-99")
ModelRangeMembersToBeModel.ktidem
Atenção: GetAvailableProductsUseCase.kt:55 tem else que lança exceção se range desconhecido. Quando o enum receber THIRTY_TO_NINETY_NINE, tem que receber também o branch → {MEDIUM_30_99_OPTIONAL, MEDIUM_30_99_MANDATORY} (já existem no CompanyProductType).

Diagrama de fluxo

C1, C2, C3 = os 3 campos novos exclusivos de P2 da tabela acima:
C1 = faturamento das filiais · C2 = pacote de coparticipação · C3 = % de cobrança copart.

sequenceDiagram autonumber actor Staff participant Front participant Ctrl as ProposalDraftController participant Acq as ProposalBuilderInternalService participant DB as Proposal DB Staff->>Front: Seleciona "30 a 100" + preenche C1, C2, C3 Front->>Ctrl: PUT /draft/{id}/plan + 3 campos novos Ctrl->>Ctrl: gate P2 (do entregável 1) Ctrl->>Ctrl: validações estruturais P2 Ctrl->>Acq: updatePlan(transport) Acq->>DB: persiste 3 campos novos Acq-->>Ctrl: 200 OK Note over Acq: emite evento de validação assíncrona
(pattern P1 reusado — Q-018)

Em aberto

3

Aba Beneficiários — modo planilha P2

Front + Back

TL;DR

Para P2, a aba substitui a UI de cadastro individual por upload único de planilha Excel, opcional. Toda a infraestrutura de upload (FileVault + pre-signed URL) já existe — basta adicionar BENEFICIARIES_SPREADSHEET ao enum FileType, 1 campo no payload, e bypassar a validação de lives quando range = 30-99. A feature lib de beneficiários NÃO é tocada (compartilhada com Portal de RH).

Atualização 2026-05-06 (Figma): design tem 3 estados visuais explícitos (vazio/drag-drop, carregando com botão "Cancelar", sucesso com "Reenviar nova planilha"). Modelo de planilha único; upload é substituição, não incremental. Q-046 nova: corrigir copy do helper text (atualmente "PNG, JPEG ou PDF" no design — bug de copy).

Mudanças necessárias

  1. Adicionar BENEFICIARIES_SPREADSHEET em FileType enum
  2. OpenAPI: campo beneficiariesSpreadsheet: List<String>? em UpsertProposalFilesRequestBody
  3. ProposalValidationStatusConverter: retornar proposalLifeValidation = null quando range = 30-99 (campo já é nullable no transport)
  4. Bloquear server-side POST/PUT/DELETE /lives em P2 (defesa em profundidade)
  5. Front: 3 estados visuais (vazio/drag-drop, carregando com cancelamento via AbortController, sucesso com substituição); botão "Baixar planilha modelo" único; helper text corrigido (.xlsx ou .xls)
  6. Backstage: planilha flui pra HECO + upload manual no Portal de RH (Q-020 ✅)

3 estados visuais (Figma 2026-05-06)

EstadoVisualImplementação FE
VazioÁrea drag-and-drop com helper "Solte aqui seu arquivo / Máx. 10MB"Listener drop + click para abrir file picker; helper text correto (.xlsx ou .xls — Q-046)
CarregandoSpinner + "Carregando planilha" + botão "Cancelar"AbortController; cancel descarta arquivo do bucket temporário e limpa estado
SucessoCheckmark verde + nome do arquivo + botão "Reenviar nova planilha"Substituição (não incremental); item de menu lateral muda de "30 a 99 vidas" para "100% preenchido"
Erro(não está no Figma — definir copy)Mensagem + botão "Tentar novamente"

Diagrama de fluxo

sequenceDiagram autonumber actor Staff participant Front participant Up as UploadController participant FV as FileVault participant S3 participant Ctrl as ProposalDraftController Note over Staff,Front: Aba Beneficiários, range = "30-99" Front->>Front: detecta range → renderiza upload Staff->>Front: Clica "baixar template" Staff->>Front: Seleciona arquivo Excel Front->>Up: GET /v1/upload/link?fileType=BENEFICIARIES_SPREADSHEET Up->>FV: generateSelfUploadUrl FV-->>Front: {url, fileId} Front->>S3: PUT direto na URL pré-assinada Front->>Ctrl: PUT /draft/{id}/files {beneficiariesSpreadsheet: [fileId]} Note over Ctrl: ProposalValidationStatusConverter:
se range == "30-99"
→ proposalLifeValidation = null

Decisões e dúvidas

4

Criação de entidades no backend P2

Back (ABS + Acquisition)

TL;DR

Modelo de dados está pronto, mas o contrato de transporte Acquisition → ABS hoje é mais limitado do que P2 precisa. Fluxo novo (pós-Cognito, ativo desde 22/abr/2026) usa RPC síncrono (CompanyProposalService.createSmallCompany), não Kafka. O request atual não carrega groupCompany, affiliatedCompanies, nem preferência de faturamento. Estender esse contrato é o coração do entregável #4.

O que já existe vs. o que falta

CamadaStatusObservação
copaymentPackage em CompanySubContract✅ ExisteJá tem {percentage, packageType: STANDARD\|FLEXIBLE}
Mapeamento billingGroup pré-pago✅ Existe0019 → 0026/0027/0028 em CompanyConverter.kt:39-69
FK contractId permite N subcontratos✅ ExisteModelo já suporta — falta service fazer loop
Responsável financeiro modelado✅ ExisteProposalCompanyStaffModel com enum
affiliatedCompanies na Proposal✅ ExisteComo ProposalAffiliatedCompanyEntity (1:N)
affiliatedBillingPreference❌ AdicionarMigration nova: coluna affiliated_billing_preference
CreateSmallCompanyRequest não carrega P2❌ Estender+ groupCompany, companySize, affiliatedBillingPreference, affiliatedCompanies
groupCompany no fluxo Proposal⚠️ Bug latenteHoje chega null em P1 também — ver Q-009

Diagrama do fluxo P2

sequenceDiagram autonumber participant Front participant BFF participant Acq as acquisition-domain-service participant UC as SubmitProposalUseCase participant CPS as CompanyProposalService
(business RPC) Note over Front,BFF: Etapa 1 — preencher draft Front->>BFF: PUT /draft/{id}/affiliated-company Front->>BFF: PUT /draft/{id}/plan + affiliatedBillingPreference BFF->>Acq: persiste Note over Front,Acq: Etapa 2 — submit Front->>BFF: POST /v2/proposals/{id}/submit BFF->>Acq: submitProposal Acq->>UC: execute(proposal) UC->>CPS: createSmallCompany(NOVO: groupCompany, affiliatedCompanies, affiliatedBillingPreference, companySize) Note over CPS: Etapa 3 — criação ABS alt SINGLE_INVOICE (ou null = P1) CPS->>CPS: 1 subcontract com CNPJ principal else INVOICE_PER_AFFILIATED CPS->>CPS: loop: 1 subcontract por CNPJ filial end CPS-->>UC: response Note over Acq: ABS publica ProposalCompanyCreationChangedEvent (FINISHED)
→ acquisition dispara SubmitProposalFamiliesUseCase
⚠️ Em P2 (modo planilha), 0 vidas → no-op (Q-034)

Em aberto

5

Ativação pré-paga em N subcontratos

Back

TL;DR

INVOICE_PER_AFFILIATED (N boletos) tem custo zero — está pronto. A verificação no código (Q-030) confirmou que o fluxo P1 atual já é scoped por subcontract: cada PreActivationPaymentPaidEvent ativa só os beneficiaries daquele subcontract.

SINGLE_INVOICE (1 boleto agregando N CNPJs) é o ponto difícil. Reunião 2026-05-06 (Higo) revelou que precisaria de entidades novas: PreActivationPaymentGroup + MemberInvoiceGroup. Custo estimado: 8-13 SP. Quote da Bruna na spec: "podemos seguir pelo caminho que gerar menos esforço" — abre espaço para postergar.

Decisão pendente (Q-041): 4 opções viáveis, com recomendação Opção B (não oferecer SINGLE_INVOICE em P2 v1).

Decisões fechadas pela reunião 2026-05-06

Q-041 — SINGLE_INVOICE: 4 opções viáveis

Por que existem 2 grupos (e não só 1): PreActivationPaymentGroup agrupa N CompanySubContract na fase pré-ativação (1 boleto agregado). MemberInvoiceGroup cobre o ciclo recorrente pós-ativação — sem ele, faturamento mensal volta a gerar boleto separado por subcontrato.

OpçãoEsforçoTrade-offVeredicto
A Group completo em S28-13 SPSINGLE_INVOICE end-to-end com auditoria por filial❌ Risco de prazo
B Sem SINGLE_INVOICE em v10 SPEmpresas com filiais recebem N boletos✅ Recomendada
C SINGLE_INVOICE = 1 subcontract3-5 SPPerde rastreabilidade por filial; conflita com Q-008❌ Trade-off ruim
D Boleto manual via Ops0-1 SPCarga em ops, dívida visível⚠️ Aceitável temporariamente

Razões pra B: lança P2 no prazo; quote da Bruna dá cobertura; diferença de UX (1 vs N boletos) é real mas não bloqueia adoção. Ponto que invalidaria B: compromisso comercial assinado/empresa-piloto que exija SINGLE_INVOICE — validar com Bruna.

Mudanças necessárias para P2 — Opção B (recomendada)

  1. PreActivationPaymentServiceImpl: detectar N subcontratos e criar 1 PreActivationPayment por subcontract (loop)
  2. PreActivationPaymentBatchRequestBuilder: confirmar que N invocações funcionam
  3. Sem mudança em BeneficiaryActivationService — Strategy B é o comportamento natural existente
  4. Member-to-subcontract assignment via CNPJ na planilha (escopo S3-S5, mas dependência crítica — Q-031)
  5. Se Q-041 fechar em A/C/D: escopo de #5 cresce. Documentação atualizada conforme decisão.

Diagrama do fluxo P2 (Opção B — INVOICE_PER_AFFILIATED)

sequenceDiagram autonumber participant Acq as acquisition participant Bus as business participant Money as money-in participant Nullvs as nullvs-integration participant TOTVS Note over Acq: Proposal SUBMITTED (P2 + INVOICE_PER_AFFILIATED) Acq->>Bus: createSmallCompany (N coligadas) Bus->>Bus: cria Company + Contract + N Subcontracts (PRE_PAY) loop para cada Subcontract Money->>Money: generateForB2B (1 PreActivationPayment) Money->>Nullvs: build invoice request Nullvs->>TOTVS: cria 1 invoice (título) end Acq->>Acq: Proposal.status = AWAITING_PAYMENT Note over TOTVS: Cliente paga 1 dos N boletos TOTVS->>Money: PreActivationPaymentPaidEvent Money->>Bus: ativa beneficiaries DESSE subcontract apenas (parcial)

Decisões e dúvidas

6

Trigger HubSpot com campos P2

Back (Revenue)

TL;DR

Correção de premissa: Hubspot não é cego à estrutura — existe mapeamento explícito field-by-field em ProposalConverter.kt. Cada campo vira uma deal property com nome em pt-BR. 3 campos P2 precisam de mapeamento explícito em 4 lugares no crm-integration-service. Direção é uma mão só — volta (Hubspot → Acquisition) é apenas status, sem campos novos.

Mudanças necessárias

  1. Pré-deploy (Ops Hubspot): cadastrar 3 deal properties: preferencia_faturamento_coligadas, tipo_pacote_copagamento, percentual_copagamento
  2. Adicionar 3 campos em ProposalModel do crm-integration-service
  3. Adicionar 3 campos em CrmProposalProperties (IDs literais das deal properties)
  4. Mapear em ProposalConverter (transport→model + model→properties)
  5. Testes ProposalConverterTest: P1 (null) + P2 (preenchidos)

Diagrama do fluxo

sequenceDiagram autonumber participant Acq as acquisition participant Kafka participant CRM as crm-integration-service participant Hub as Hubspot API Acq->>Kafka: emit ProposalCreatedEvent Kafka-->>CRM: ProposalCreatedEvent CRM->>CRM: ProposalTransport → ProposalModel
→ CrmProposalProperties (mapeia field-by-field
com nomes pt-BR) CRM->>Hub: createDeal(CrmProposalProperties) Note over Hub: Volta (não muda em P2) Hub-->>CRM: webhook (status change) CRM-->>Acq: CrmProposalNotificationEvent

Em aberto

7-9

Abas e documentos reusados de P1

Validação

TL;DR

Reuso seguro confirmado para todas as abas (Corretor/Empresa/Coligadas/Anexos) e para a persistência de documentos da empresa. Nenhum endpoint exige modificação para P2. Único ponto de atenção: TODO desabilitado em ValidateMainCompanyRulesUseCase.kt:62 que vale reativar — ver Q-024.

5 hipóteses validadas

IDHipóteseStatus
HVR-1Nenhum endpoint P1 tem hardcode "range = 30-99 → reject"✅ Confirmado
HVR-2Payload de Coligadas suporta a estrutura que #4 espera✅ Confirmado
HVR-3Aba Empresa propaga willHaveAffiliated para a Proposal✅ Confirmado
HVR-4Validações da aba Anexos são range-agnósticas✅ Confirmado
HVR-5Não há validação "≥1 coligada se willHaveAffiliated == true"⚠️ Confirmado (gap)

Em aberto

Dúvidas e decisões

Fonte da verdade do tracking. Cada dúvida tem ID estável (Q-XXX) que pode ser citado em reuniões, Slack e Jira.

🔴 Aberta 🟡 Em discussão 💡 Recomendação dada 🟢 Resolvida

Tabela completa (com filtros)

36 dúvidas · 29 resolvidas · 7 em aberto. Filtre por categoria, status ou texto livre.

IDCatPerguntaEntregávelOwnerStatusRecomendação / Notas
Q-001EngGranularidade do gating P2: por firm ou por agent?#1🟢Por firm. Corretor pode pertencer a múltiplas firms; uma proposta sempre fica ligada a uma firm específica. Reuso direto do pattern P1. Fonte: reunião "[Portal de vendas] Fluxo atual de proposta" (Caroline R. Andrade), 2026-05-04 @ 00:00:00 — "todo corretor vai tá ligado numa corretora para numa proposta… mas um corretor pode estar em mais de uma corretora".
Q-002ProdutoSalesAgent (corretor) deve ter acesso ao formulário P2 ou só SalesFirmStaff (funcionário da corretora)?#1🟢Apenas SalesFirmStaff. Corretor não cria proposta — só passa dados pro staff, que insere no portal. Regra de negócio (não decisão técnica). Mantemos o mesmo padrão de P1. Fonte: reunião 2026-05-04 @ 00:01:45 — "Corretor não tem acesso hoje à criação de propostas, então só quem tem acesso hoje é o sales firm staff".
Q-003EngReusar a feature flag de P1 ou criar flag novo paralelo para P2?#1INVALIDADA pela reunião 2026-05-06. Decisão de não usar FF de jeito nenhum — gating vira capability persistente em SalesFirm (allowedProposalTypes: List<ProposalType>). Nem FF P1 nem FF P2 existem mais — ambos substituídos pela coluna nova. Ver Q-040 para o plano de migração de P1.
Q-004EngImplementar validação server-side em updatePlan?#1🟢Reformulada (2026-05-06): a validação server-side em updatePlan continua sendo necessária (defesa em profundidade), mas agora salesFirm.allowedProposalTypes.contains(P2) em vez de chamar FeatureService.getList(...). Comportamento equivalente, fonte da verdade diferente.
Q-005Eng / OpsNome final do feature flag de gating P2?#1INVALIDADA. Não há FF. Ver Q-040 (campo allowedProposalTypes: List<ProposalType> em SalesFirm).
Q-006ProdutoNome final do enum de preferência de faturamento das filiais?#4🟢AffiliatedBillingPreference { SINGLE_INVOICE, INVOICE_PER_AFFILIATED }. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-007ProdutoSalvar affiliatedBillingPreference também em Contract, ou só em Proposal?#4🟢Só na Proposal. Cada subcontract gerado já materializa a decisão (SINGLE_INVOICE = 1 subcontract no CNPJ principal; INVOICE_PER_AFFILIATED = N subcontracts). Salvar em Contract seria duplicação sem benefício. Notion ambíguo interpretado como alternativa, não conjunção. Custo: zero ajuste (vs. salvar em ambos: nova coluna em Contract + propagação + migration). Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-06.
Q-008EngCriação de N subcontratos: 1 por CNPJ filial ou por categoria de plano?#4🟢1 por CNPJ filial. Todas com mesmas condições comerciais (mesmo copaymentPackage, paymentType, groupCompany). "Categoria de plano" não é caso atual em P2. Loop sequencial OK — volume baixo (N≤10 filiais). Reunião S2 - Proposta PAP e MIG, 2026-05-06.
Q-009Eng / ProdutoAproveitar P2 para popular groupCompany também em P1 (corrige bug latente)?#4🟢Sim, em PR separado depois do P2 entrar. Mantém P2 enxuto e o fix tem identidade própria. Bug descoberto em 2026-05-04 (M4 do entregável #4). Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-010EngRenomear CreateSmallCompanyRequestCreateCompanyRequest?#4🟢Sim, em PR separado depois do P2 entrar. Refactor puro, baixo risco. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-011Engcrm-integration-service precisa refletir os novos campos?#4🟢Sim — há mapeamento explícito field-by-field em ProposalConverter.kt. Implementação detalhada no entregável #6: 3 campos novos no ProposalModel + CrmProposalProperties + mapping no converter. Pré-condição operacional: cadastrar 3 deal properties no Hubspot (Q-027). Verificação no código + decisão entregável #6.
Q-012EngOPA policies precisam atualização?#4🟢Não, OPA é table-level. Policies em data-layer-core/resources/policies/ controlam acesso por entidade (opaType), não por coluna. Os 3 novos campos estão automaticamente cobertos pelo permissionamento existente da tabela proposal. Sem mudança em OPA. Verificação no código, 2026-05-05.
Q-013Produto / EngTítulo do subcontract para P1 — manter ou padronizar?#4🟢Manter P1 inalterado ("Subcontrato {cnpj}"). Aplicar "{cnpj} - {legalName}" só para P2. Não quebrar histórico/UI legada. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-014Produto / EngMapeamento companySize → groupCompany para outros tamanhos além de M?#4🟢Para o escopo S2, só M → "0019" importa (confirmado pelo Notion). Outros tamanhos (P, MEI, ME_*) não são afetados pelo S2 — fluxo P2 só lida com M. Tabela completa só precisa ser preenchida se Q-009 for atacada (PR separado). Verificação no código, 2026-05-05.
Q-015MetaSquad Alfa tem padrão de decision log?🟢Sim, há modelo de documento que vamos preencher ao final da entrega. Decisões desta feature ficam consolidadas no 90-duvidas.md e migrarão para o decision log da squad ao final. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-016Eng / ProdutoComo modelar "Sem coparticipação" no backend?#2🟢Tratar caso NONE. Enum CopaymentPackageOption { STANDARD, FLEXIBLE, NONE } na Proposal, traduzindo NONE → copaymentPackage = null no Subcontract no momento da criação no business-domain-service. Decisão de Maria Trevisan (dev, Squad Alfa), confirmada após reunião 2026-05-06.
Q-017EngValidações dos 3 campos novos P2 devem ser síncronas (no updatePlan) ou assíncronas (via evento, igual P1)?#2🟢Seguir pattern P1. Estruturais (enum válido, percentual ∈ {10,20,30}, campos obrigatórios quando range = 30-99) síncronas inline no updatePlan com 400; regra de negócio cruzada/pesada (que precisa RPC pra ABS) vai pelo pattern assíncrono existente (evento → cache → front faz pulling em /validation-status). Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-018EngPattern de validação assíncrona cobre os 3 campos novos de P2 sem ajuste?#2🟢Sim, o pipeline é genérico. Verificado no código: ProposalValidationEvent agnóstico aos campos; infra evento → cache → pulling completamente genérica. Mudanças necessárias: (1) +3 valores no enum ProposalValidationError (123 valores hoje); (2) +3 takeIf no ValidatePlanRulesUseCase. Errors no OpenAPI são additionalProperties: string — não há acoplamento de release com o front. Sem migration, sem schema versioning, sem mudança no consumer. Verificação no código, 2026-05-05.
Q-019EngEndpoints POST/PUT/DELETE /lives em P2 — bloquear server-side ou só esconder no front?#3🟢Bloquear server-side com 400. Guard nos 3 endpoints em ProposalDraftController que rejeita quando proposal.rangeMemberToBe == "30-99" com erro lives_endpoints_not_available_for_p2. Defesa em profundidade contra requests forjadas. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-020Produto / OpsOnde o time de vendas baixa a planilha?#3🟢Planilha flui para o HECO, onde o time de vendas baixa e faz upload manual no Portal de RH (nessa primeira fase). Workaround temporário; iteração futura pode automatizar via webhook. Não há trabalho de "tela de download" no S2 — fluxo é pelo HECO existente. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-06.
Q-021Produto / EngValidação de schema/conteúdo da planilha?#3🟢Apenas validação estrutural — extensão (.xlsx/.xls) + tamanho razoável (<10MB). NÃO validar schema, conteúdo ou cruzamento com a Proposal nesta entrega — é "fase 1" e Ops já valida ao processar no Portal de RH. Estrutural protege só contra erros gritantes (anexar PDF por engano). Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-022Produto / EngOnde fica hospedado o template da planilha?#3🟢Asset estático em front-app-sales-channel/public/. Convenção do projeto (favicon, robots.txt, imagens). Adicionar public/templates/template-beneficiarios-p2.xlsx. Botão de download via URL relativa. Atualizar = commit + release. Trade-off aceito para v1: simplicidade > agilidade. Verificação no código, 2026-05-05.
Q-023EngPergunta-mestre da fronteira P2 sem vidas. Em P2 com modo planilha (0 vidas no submit), a ativação funciona?#3, #4, #5, #6🟢CENÁRIO A: Funciona end-to-end. 3 subdúvidas verificadas no código (Q-034, Q-035, Q-029) — todas favoráveis. S2 vai até IMPLEMENTED mesmo sem vidas no submit. Members vêm depois via Portal de RH (S3-S5) e populam o subcontrato — vida normal. Verificação no código (3 subdúvidas), 2026-05-05.
Q-024EngReativar validação COMPANY_WILL_HAVE_AFFILIATED_REQUIRED (TODO em ValidateMainCompanyRulesUseCase.kt:62)?#8🟢Sim, reativar. P2 depende de willHaveAffiliated para mostrar/persistir affiliatedBillingPreference (#4). Mudança: descomentar a linha + rodar testes. Antes de codar, verificar com Carol qual era o "backward compatibility issue" do TODO original. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-025Produto / EngAdicionar validação "≥1 coligada quando INVOICE_PER_AFFILIATED"?#8🟢Sim, adicionar. Escolher "boleto por CNPJ" sem informar nenhuma coligada é estado inválido — geraria 0 subcontratos no ABS, empresa nunca recebe boleto. Regra ativa SÓ quando INVOICE_PER_AFFILIATED (não bloquear SINGLE_INVOICE mesmo com willHaveAffiliated == true). Implementar em ValidateProposalAffiliatedCompaniesRulesUseCase ou ValidatePlanRulesUseCase (decisão do dev). Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-026ProdutocopaymentPackageType e copaymentChargePercentage precisam ir pro Hubspot?#6🟢Sim, enviar. Custo de implementação baixo (3 linhas + 2 properties no Hubspot). Permite que o time comercial filtre/analise deals por configuração de copart. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-027OpsQuem cadastra as 3 deal properties novas no Hubspot?#6Vittoria + Hubspot admin🔴Pré-condição operacional. Properties não cadastradas = campos descartados silenciosamente.
Q-028EngaffiliatedBillingPreference propagado por coligada ou só na proposta?#6🟢Só no nível da proposta. Coerente com Q-007 (que decide salvar só na Proposal, não em Contract): o atributo é decisão da empresa e tem escopo único; não duplica nem em Contract nem por filial. Manter dados_das_coligadas inalterado no Hubspot. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-05.
Q-029EngCRM/Hubspot dependem de ProposalLifeCreatedEvent?#6🟢Não, são operações independentes. No DomainServiceEventsConsumer: consumeProposalCreated cria deal sem lives; consumeProposalLifeCreated cria lives separadamente. Em P2 com 0 lives, deal existe normal — só não tem line items. Verificação no código (crm-integration-service), 2026-05-05.
Q-030ProdutoAtivação P2: all-or-nothing ou parcial?#5🟢Parcial — Strategy B confirmada (zero LOC). Reunião 2026-05-06 (Higo): "o pagamento ativa somente o subcontrato que recebeu o valor". Verificação prévia no código já confirmava: BeneficiaryActivationService é scoped por subcontract. Quote da Bruna: "caminho de menor esforço". Nota: existe job recorrente que ativa membros novos em contratos com subcontract pago — ver Q-042. UX: ativação progressiva.
Q-037Eng / OpsCronograma de descontinuação da AffiliateOfCompany impacta S2?#4Carol / Bernardo🔴Carol mencionou plano de descontinuar AffiliateOfCompany e incorporar dados direto na Company. Se rodar em paralelo com S2, precisamos saber: (a) cronograma, (b) S2 consome novo modelo ou atual, (c) se há janela de coexistência. Reunião [Portal de vendas] Arquitetura de proposta (00:20:52), 2026-05-05.
Q-038Produto / OpsExiste planilha-modelo no Portal de RH? Sub-perguntas (a) e (c) fechadas pelo Figma.#3Vittoria / Bruna🟡Sub-perguntas fechadas pelos prints do Figma (2026-05-06): (a) modelo único (1 botão "Baixar planilha modelo"); (c) substituição (botão "Reenviar nova planilha"). Em aberto: (b) modelo derivado de "empresa contratará Alice para CLT?" da aba Contratação? (d) "empresa pode enviar depois" — depois de qual step e até quando edita?
Q-039Eng / OpsComo adm habilita P2 numa corretora?#1🟢Tela de cadastro/edição da corretora no backoffice (backoffice-dev2.dev.alice.com.br/business/sales-firm/...) com campo multi-select. Ops gerencia diretamente, sem precisar de tech. Implementação: endpoint backend (PATCH/PUT) em sales-channel-domain-service + form field no backoffice. Squad Alfa mantém todos os repos. Estimativa: 3-5 SP. Reunião S2 - Proposta PAP e MIG, 2026-05-06.
Q-040EngP1 também migra do FF para o novo modelo?#1🟢Sim, junto. Migration backfilla allowedProposalTypes = [P1] em todas as corretoras existentes (FF P1 está em ["*"] = todas). FF de P1 (proposal_enabled_sales_firm_ids) é descontinuada. PR de cleanup do código que lê a FF entra junto. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-06.
Q-041Eng / ProdutoCusto de implementar PreActivationPaymentGroup + MemberInvoiceGroup para SINGLE_INVOICE em P2 com filiais?#5Higo / Bruna / Maria🟡4 opções viáveis (detalhadas no entregável #5): A) Group completo em S2 (8-13 SP, alto risco prazo); B) Lançar P2 sem SINGLE_INVOICE em v1 (0 SP, recomendada); C) SINGLE_INVOICE = 1 subcontrato com CNPJ principal (3-5 SP, perde rastreabilidade); D) Boleto manual via Ops (0-1 SP, dívida operacional). Recomendação: B (quote da Bruna: "caminho de menor esforço"). Validar com Bruna se há compromisso comercial que force A.
Q-042EngIdentificar o job recorrente que ativa membros novos em contratos com subcontract já pago#5🟢Achado parcial — o que existe NÃO bate com a hint do Higo. Job RecurrentController.activateBeneficiariesBasedOnActivationDate() em business-domain-service/.../RecurrentController.kt:77-80 (entry) e :287-347 (impl). Agendado via k8s CronJob com cron "0 3/4 * * *" (de 4h em 4h a partir das 03:00) — k8s-apps/.../business-domain-service/prod.yaml:64-78. O critério é MemberStatus.PENDING + activatedAt = hoje — sem filtro por paymentType ou status do subcontract. A regra que o Higo descreveu (contrato com subcontract pago ativa membros novos) não está implementada dessa forma — se surgir necessidade em S3+, precisa ser explicitamente adicionada. Verificação no código (Explore agent), 2026-05-06.
Q-043Produto / EngEmpresa fica em "rascunho" até pagar todos os boletos?#5🟢NÃO. Ativação na TOTVS depende da data de início do contrato, não do pagamento. Se data não estipulada → vira a data do 1º pagamento. "é incoerente ter membros ativos enquanto o contrato não está ativo" (Higo). Reunião S2 - Proposta PAP e MIG (00:11:05 — 00:12:24), 2026-05-06.
Q-044Produto / EngBloqueio de ativação de membros sem documentação validada — modelagemS3+🟢Fora do escopo S2 — fica para S3+. Higo + Thales discutiram 3 opções: (a) novo status no membro, (b) novo campo de bloqueio, (c) nova fase no onboarding. Higo também mencionou habilitar edição de beneficiários e liberação manual do bloqueio por ops. Não há trabalho em S2. Decisão de Maria Trevisan (dev, Squad Alfa), 2026-05-06.
Q-045Eng / FECompatibilidade DS v3 (Portal RH) vs v7 (Portal Vendas) e leitura de Excel no FE#3Vittoria / Thales🟡Risco em T3.3/T3.4. A lib que exporta tabela + drawer está em DS v7, mas Portal de RH (que processa Excel) está em v3. "o processo atual de leitura do Excel no frontend e chamada de endpoint no BFF, conforme o portal da RH faz, será desafiador de implementar". Vittoria + Thales vão alinhar. Pode estourar a estimativa atual. Reunião S2 - Proposta PAP e MIG (00:19:52 — 00:23:26), 2026-05-06.
Q-046UX / FEHelper text do upload de planilha está com copy errado no Figma#3Vittoria / UX🔴Descoberto na análise dos prints (2026-05-06). Design diz "Máx. 10MB. Arquivos PNG, JPEG ou PDF." mas a entrada esperada é planilha Excel. Provável copy genérico copiado de outro componente. Texto correto: "Máx. 10MB. Arquivos .xlsx ou .xls". Solicitar à UX a correção. Não bloqueia dev — FE pode usar texto correto direto.
Q-031Produto / EngMember-to-subcontract assignment via planilha + Portal de RH#5🟢Modelo OK, fluxo de upload é S3-S5. Member.companySubContractIds: List<UUID> em MemberTransport.kt:22 é plural — modelagem many-to-many member↔subcontract já pronta. Entry point específico do batch upload do Portal de RH não foi traceado nesta verificação — fica como item explícito em S3-S5 (escopo das próximas entregas). Verificação parcial — modelo OK, 2026-05-05.
Q-032EngTOTVS aceita N títulos pré-pagos da mesma company?#5🟢Sim, sem barreira no código. PreActivationPaymentBatchRequestBuilder.kt:22-50 é construído por (billingAccountablePartyId + companySubContractId), não por companyId. Sem findFirstByCompanyId ou assumeSingle. Validar com nullvs/Bernardo se a TOTVS API real (Protheus) tem idempotência por companyId — mas no nosso lado está OK. Verificação no código, 2026-05-05.
Q-033ProdutoAdicionar paidInvoicesCount/totalInvoicesCount na Proposal?#5Vittoria / Bruna💡Nice-to-have, não bloqueia.
Q-034EngSubmitProposalFamiliesUseCase tem pré-condição "≥1 família"?#4🟢Não, gracefully no-op. execute() linhas 32-59 busca lives, agrupa em famílias (linha 85: if (lives.isEmpty()) return emptyList()), forEach executa 0 vezes, retorna true.success(). Sem precondição de erro. Verificação no código (acquisition-domain-service), 2026-05-05.
Q-035EngP2 sem vidas: Company ativa só com pagamento ou espera members?#5🟢Não há gate de members. PreActivationPaymentPaidConsumer linhas 25-48 valida só companyId e companySubContractId. BeneficiaryActivationService.handleBeneficiaryActivation() aceita lista vazia de beneficiaries. Pagamento ativa direto. Verificação no código (business-domain-service), 2026-05-05.
Q-036Produto / Eng(Descoberta via Figma) Em P2, se documento da empresa for inválido após submit, onde o Adm reinsere o documento?#7Vittoria / Bernardo🔴As-is P1 mostra fallback "Adm insere documentos em um Cognito" para pendências; em P2 o Cognito não existe mais. Opções: (A) manter Cognito como fallback transitório, (B) novo endpoint de "atualizar documento de proposta submetida" no Portal de Vendas, (C) outro mecanismo. Descoberto via análise dos prints Figma, 2026-05-05.

Decisões já tomadas — sumário

Visão rápida (linhas detalhadas com citação literal estão na tabela acima).

IDPerguntaResoluçãoFonte
Q-001 🟢Granularidade firm vs agent?Por firm.Reunião 2026-05-04, 00:00:00
Q-002 🟢SalesAgent cria proposta?Não — só staff.Reunião 2026-05-04, 00:01:45
Q-003Reusar flag P1 ou criar novo?INVALIDADA — sem FFReunião 2026-05-06
Q-004 🟢Validação server-side em updatePlan?Sim — lê SalesFirm.allowedProposalTypesReunião 2026-05-06
Q-005Nome final do FF P2?INVALIDADA — sem FFReunião 2026-05-06
Q-039 🟢Como adm habilita P2 numa corretora?Tela de cadastro/edição da corretora no backoffice + multi-select. Ops gerencia direto.Reunião 2026-05-06
Q-040 🟢P1 também migra do FF para o novo modelo?Sim, junto. Backfill [P1]; FF P1 descontinuada.Maria Trevisan, 2026-05-06
Q-008 🟢Subcontract por CNPJ filial ou categoria?1 por CNPJ filial, mesmas condições comerciais.Reunião 2026-05-06
Q-016 🟢"Sem coparticipação" como modelar?Enum {STANDARD, FLEXIBLE, NONE}; NONE → null no Subcontract.Maria Trevisan, 2026-05-06
Q-043 🟢Empresa fica em rascunho até pagar todos boletos?NÃO. Ativação depende da data de início do contrato.Reunião 2026-05-06
Q-020 🟢Onde o time de vendas baixa a planilha?HECO + upload manual no Portal de RH (workaround temporário); sem trabalho de tela em S2.Maria Trevisan, 2026-05-06
Q-042 🟢Job recorrente que ativa membros em contratos com subcontract pago?Achado parcial — job existe mas filtra por activatedAt = hoje, não por subcontract pago. A regra do Higo não está implementada como descrita.Verificação no código, 2026-05-06
Q-044 🟢Bloqueio de ativação de membros sem doc validada?Fora do S2 — fica para S3+ (escopo de members). Sem trabalho em S2.Maria Trevisan, 2026-05-06
Q-007 🟢affiliatedBillingPreference em Contract também?Só na Proposal. Subcontracts já materializam a decisão; salvar em Contract seria duplicação. Custo zero.Maria Trevisan, 2026-05-06
Q-017 🟢Validações P2 síncronas ou assíncronas?Pattern P1: estruturais síncronas, regra de negócio assíncronas.Maria Trevisan (dev, Squad Alfa), 2026-05-05
Q-018 🟢Pipeline de validação cobre campos novos sem ajuste?Sim, é genérico — só +3 enum + 3 checks.Verificação no código, 2026-05-05
Q-019 🟢Bloquear lives endpoints em P2?Sim, server-side com 400.Maria Trevisan (dev, Squad Alfa), 2026-05-05
Q-024 🟢Reativar TODO de willHaveAffiliated?Sim, reativar.Maria Trevisan (dev, Squad Alfa), 2026-05-05
Q-021 🟢Validação de schema da planilha?Apenas estrutural (extensão + tamanho).Maria Trevisan (dev, Squad Alfa), 2026-05-05
Q-025 🟢Validação ≥1 coligada quando INVOICE_PER_AFFILIATED?Sim, adicionar.Maria Trevisan (dev, Squad Alfa), 2026-05-05
Q-023 🟢Pergunta-mestre — fronteira P2 sem vidasCenário A: P2 com 0 vidas funciona end-to-end. S2 chega em IMPLEMENTED.Verificação no código (3 subdúvidas), 2026-05-05
Q-034 🟢SubmitProposalFamiliesUseCase quebra com 0 vidas?Não, gracefully no-op.Verificação no código, 2026-05-05
Q-035 🟢P2 sem vidas: Company ativa só com pagamento?Sim, sem gate de members.Verificação no código, 2026-05-05
Q-029 🟢Hubspot depende de ProposalLifeCreatedEvent?Não, deal e lives são independentes.Verificação no código, 2026-05-05
Q-012 🟢OPA policies precisam atualização?Não, é table-level.Verificação no código, 2026-05-05
Q-014 🟢Mapeamento companySize → groupCompany para outros tamanhos?Para S2, só M → "0019". Outros são Q-009.Verificação no código, 2026-05-05
Q-022 🟢Onde hospedar o template?Asset estático em front-app-sales-channel/public/.Verificação no código, 2026-05-05
Q-031 🟢Member-to-subcontract via CNPJ?Modelo OK (plural). Fluxo de upload em S3-S5.Verificação parcial, 2026-05-05
Q-032 🟢TOTVS aceita N títulos da mesma company?Sim, sem barreira no código.Verificação no código, 2026-05-05

Comparação com a doc oficial

Cruzamento com a Documentação de Proposta (Tech Revenue, auditada contra main em 2026-05-04).

Resultado: nenhuma contradição direta. Plano alinhado com a arquitetura oficial.

🟢 Confirmações importantes

🟡 Lacunas no nosso plano (descobertas pela comparação)

🔵 Dessincronias na doc oficial (não nos afetam)