Feature: Signup Confirmation
Introdução ao documento
Este documento descreve a feature de confirmação de cadastro em /{slug}/inscricao/confirmacao, responsável por pré-preencher, validar, persistir dados do participante e disparar o envio do OTP.
Evidências:
../../app/[slug]/inscricao/confirmacao/page.tsx#L8-L16../../src/features/components/SignupConfirmation/SignupConfirmation.component.tsx#L12-L91../../src/features/components/SignupConfirmation/components/ProfileForm/ProfileForm.component.tsx#L21-L285
Versionamento
Atualizar este documento quando mudarem:
- os campos do formulário de participante;
- a estratégia de pré-preenchimento via AMEI/sessão;
- o upsert em
/v1/participantes/{cpf}; - o disparo de OTP e o tracking de
CompleteRegistration.
Evidências:
../../src/features/components/SignupConfirmation/SignupConfirmation.component.tsx#L21-L82../../src/features/components/SignupConfirmation/components/ProfileForm/ProfileForm.schema.ts#L5-L47../../src/features/api/subscribeToCourse/subscribeToCourse.api.ts#L4-L21
Referencial teórico
O mapeamento desta feature foi derivado da página protegida, do componente de confirmação, do formulário, das validações e dos endpoints internos de participante/OTP/tracking.
Evidências:
../../app/[slug]/inscricao/confirmacao/page.tsx#L11-L15../../src/common/components/AuthProtected/AuthProtected.component.tsx#L14-L20../../pages/api/v1/participantes/[cpf].ts#L11-L52../../pages/api/v1/otp/send.ts#L20-L35../../app/api/meta-conversion/route.ts#L7-L47
Visão geral
- A página é protegida por
AuthProtected(confirmacao/page.tsx#L11-L15). - O componente monta o
participanta partir da sessão ou do usuário AMEI (SignupConfirmation.component.tsx#L21-L82). - O formulário valida, normaliza, persiste dados do participante, envia OTP e atualiza a sessão antes de avançar para a etapa de código (ProfileForm.component.tsx#L50-L105, ProfileConfirmation.component.tsx#L17-L35).
Atores
- Participante autenticado (confirmacao/page.tsx#L11-L15).
- Usuário AMEI, quando houver
amei_auth(SignupConfirmation.component.tsx#L23-L28). - App Next.js / sessão
NextAuth(SignupConfirmation.component.tsx#L15-L17, ProfileConfirmation.component.tsx#L17-L20). - Backend WordPress de participante (pages/api/v1/participantes/[cpf].ts#L23-L48).
- Backend WhatsApp e Meta Conversions API (ProfileForm.component.tsx#L50-L57, ProfileConfirmation.component.tsx#L22-L34).
Pré-condições
- O participante precisa ter passado pelo gate de autenticação anterior, senão
AuthProtectedo devolve para a rota do curso (AuthProtected.component.tsx#L14-L20). - A feature precisa ter
slugpara compor sessão e chamadas de API (SignupConfirmation.component.tsx#L12-L14). - O formulário depende de dados válidos segundo o schema de participante (ProfileForm.schema.ts#L5-L47).
Fluxo principal
- A página protegida renderiza
SignupConfirmation(confirmacao/page.tsx#L11-L15). - O componente detecta se
amei_authestá ativo e montaparticipanta partir deuserAMEI ou da sessão local (SignupConfirmation.component.tsx#L21-L78). - Em AMEI, a feature busca o ID canônico do participante por CPF e atualiza a sessão com esse
id(SignupConfirmation.component.tsx#L45-L53). ProfileFormvalida os campos, normaliza strings e executaPUT /v1/participantes/{cpf}(ProfileForm.component.tsx#L72-L105, subscribeToCourse.api.ts#L8-L21).- Em sucesso, a feature dispara
/v1/otp/send, atualiza a sessão e fazrouter.pushpara/{slug}/inscricao/codigo(ProfileForm.component.tsx#L50-L57, ProfileConfirmation.component.tsx#L17-L20).
Fluxos alternativos
- Se não houver
participant.id, o formulário é renderizado comcpfpré-preenchido e sem dados adicionais (ProfileConfirmation.component.tsx#L37-L44). - Em falha de sessão local, o componente registra erro no console (SignupConfirmation.component.tsx#L69-L77).
- Em falha no upsert ou no envio de OTP, a feature mostra snackbar de erro (ProfileForm.component.tsx#L42-L48, ProfileForm.component.tsx#L60-L69).
- O botão
Avançarfica bloqueado enquanto o formulário está inválido, validando ou carregando (ProfileForm.component.tsx#L272-L278).
Regras de negócio
- O CPF é obrigatório, tem 11 dígitos e precisa passar por
validateCpf(ProfileForm.schema.ts#L6-L11, validateCpf.ts#L10-L18). - O nome é obrigatório, é trimado e precisa aparentar nome completo com pelo menos dois termos (ProfileForm.schema.ts#L13-L17).
- O e-mail é obrigatório e precisa ter formato válido (ProfileForm.schema.ts#L19-L22).
- Telefone, data de nascimento, sexo e raça são obrigatórios (ProfileForm.schema.ts#L24-L46).
- A data de nascimento precisa ser uma data passada válida no formato
dd/MM/yyyy(ProfileForm.schema.ts#L29-L36). - O nome é normalizado para capitalização
pt-BR, e todos os campos string são trimados antes do upsert (ProfileForm.component.tsx#L72-L95). - Quando
isAmei = false, o campophoneinicial é limpo mesmo que exista valor pré-preenchido; quandoisAmei = true, o telefone pode ser reaproveitado (ProfileForm.component.tsx#L116-L119). - No fluxo AMEI,
birthDateé reformatado deyyyy-MM-ddparadd/MM/yyyy, e o telefone recebe prefixo+55quando ausente (SignupConfirmation.component.tsx#L29-L43).
Estados possíveis
- Participante identificado com
id/ participante ainda semid(ProfileConfirmation.component.tsx#L37-L54). idle,loading,success,errorno submit local (ProfileForm.component.tsx#L31-L36).- Fluxo AMEI / fluxo sessão local (SignupConfirmation.component.tsx#L23-L28, SignupConfirmation.component.tsx#L68-L78).
Endpoints envolvidos
OpenAPIpath/v1/participantes/{cpf}para leitura/upsert de participante (pages/api/v1/participantes/[cpf].ts#L23-L48).OpenAPIpath/v1/otp/sendpara envio do código (pages/api/v1/otp/send.ts#L20-L32).OpenAPIpath/meta-conversionpara tracking deCompleteRegistration(ProfileConfirmation.component.tsx#L22-L34, ../../app/api/meta-conversion/route.ts#L12-L43).
Dados impactados
- A feature cria/atualiza
Participante sincronizaSessionUsercom o payload confirmado (SignupConfirmation.component.tsx#L50-L53, pages/api/v1/participantes/[cpf].ts#L29-L48).
Pendências
- A atualização de sessão em
onUpdateProfileusaparticipant.IDe nãoparticipant.id, o que sugere divergência de contrato entre frontend e runtime. modalMultipleInscriptionsé setado a partir decanceledEnrolls, mas não participa de renderização observável nesta feature.
Evidências: