Feature: OTP Confirmation
Introdução ao documento
Este documento descreve a feature de confirmação por OTP em /{slug}/inscricao/codigo, incluindo guarda por sessão, validação do código, reenvio e transição para a etapa final via WhatsApp.
Evidências:
../../app/[slug]/inscricao/codigo/page.tsx#L8-L16../../src/features/components/OTPConfirmation/OTPConfirmation.component.tsx#L7-L28../../src/features/components/OTPConfirmation/components/Form/Form.component.tsx#L17-L123
Versionamento
Atualizar este documento quando mudarem:
- a guarda de sessão/telefone;
- o schema do código OTP;
- o contrato de
/v1/otp/confirm,/v1/otp/sendou/v1/flow/resend; - a navegação para a etapa
turma.
Evidências:
../../src/features/components/OTPConfirmation/OTPConfirmation.component.tsx#L11-L20../../src/features/components/OTPConfirmation/components/Form/Form.schema.ts#L3-L8../../pages/api/v1/otp/confirm.ts#L12-L57../../pages/api/v1/flow/resend.ts#L11-L44
Referencial teórico
O mapeamento desta feature foi derivado da página protegida, do componente OTP, do formulário, do diálogo de reenvio e dos handlers server-side de OTP/template.
Evidências:
../../app/[slug]/inscricao/codigo/page.tsx#L12-L15../../src/common/components/AuthProtected/AuthProtected.component.tsx#L14-L20../../src/features/components/OTPConfirmation/components/Form/Form.component.tsx#L44-L49../../src/features/components/OTPConfirmation/components/ResendCodeDialog/ResendCodeDialog.component.tsx#L39-L43
Visão geral
- A página é protegida por
AuthProtected(codigo/page.tsx#L12-L15). - O componente OTP exige que a sessão tenha
cpfephone; sem isso, devolve o usuário para a inscrição (OTPConfirmation.component.tsx#L11-L20). - O formulário envia
phoneecodepara/v1/otp/confirm; em sucesso, navega para/{slug}/inscricao/turma(Form.component.tsx#L33-L49).
Atores
- Participante autenticado (OTPConfirmation.component.tsx#L8-L20).
- App Next.js / sessão
NextAuth(OTPConfirmation.component.tsx#L8-L18). - Backend WhatsApp OTP (pages/api/v1/otp/confirm.ts#L29-L35, pages/api/v1/otp/send.ts#L27-L32).
- Backend WordPress de customização, usado após confirmação para template de fluxo (pages/api/v1/otp/confirm.ts#L39-L46).
Pré-condições
AuthProtectedprecisa permitir a navegação (codigo/page.tsx#L12-L15).- A sessão precisa conter
cpf; caso contrário, o usuário volta para/{slug}/inscricao?erro=Preencha seu CPF para continuar(OTPConfirmation.component.tsx#L11-L15). - A sessão precisa conter
phone; caso contrário, o usuário volta para/{slug}/inscricao?erro=Preencha seu telefone para continuar(OTPConfirmation.component.tsx#L15-L20). - O código precisa ter 6 dígitos (Form.schema.ts#L3-L8).
Fluxo principal
- A página protegida renderiza
OTPConfirmation(codigo/page.tsx#L12-L15). - O componente verifica
cpfephonena sessão (OTPConfirmation.component.tsx#L11-L20). - O participante digita o código; ao completar 6 dígitos, o formulário submete automaticamente (Form.component.tsx#L57-L60, Form.component.tsx#L72-L79).
- A feature envia
POST /v1/otp/confirm(confirmOtpCode.api.ts#L3-L20). - Em sucesso, o usuário é redirecionado para
/{slug}/inscricao/turma(Form.component.tsx#L33-L35).
Fluxos alternativos
- Se
/v1/otp/confirmfalhar, o erro virafieldErrorno campocode(Form.component.tsx#L37-L42). - O participante pode voltar para a etapa anterior com
router.back()(Form.component.tsx#L29-L31, Form.component.tsx#L94-L102). - O diálogo
Não recebi o códigopode ser aberto, fechado e usado para reenvio (Form.component.tsx#L22-L24, Form.component.tsx#L80-L91, Form.component.tsx#L113-L120). - O reenvio atual usa o telefone já conhecido; o fluxo de alteração de telefone está comentado e não é executado (ResendCodeDialog.component.tsx#L77-L103, ResendCodeDialog.component.tsx#L104-L109).
Regras de negócio
- O código OTP é obrigatório e deve ter exatamente 6 dígitos (Form.schema.ts#L3-L8).
- A feature só renderiza o formulário quando a sessão já tem telefone; antes disso, retorna
nullpara evitar UI inconsistente (OTPConfirmation.component.tsx#L20-L26). - O handler
/v1/otp/confirmexige sessão, métodoPOST,phoneecodeválidos (pages/api/v1/otp/confirm.ts#L12-L27). - Após validar o OTP, o backend envia template de fluxo usando
course_slug,id,flow_template_ideflow_template_header_image(pages/api/v1/otp/confirm.ts#L37-L50). - O reenvio de código atual também exige telefone e sessão válidos via
/v1/otp/send(sendOtpCode.api.ts#L6-L27, pages/api/v1/otp/send.ts#L10-L35).
Estados possíveis
- Formulário
idle,loading,success,error(Form.component.tsx#L26-L27). - Diálogo de reenvio aberto / fechado (Form.component.tsx#L22-L24, Form.component.tsx#L113-L120).
- Código válido / inválido (Form.component.tsx#L37-L42, pages/api/v1/otp/confirm.ts#L31-L35).
Endpoints envolvidos
OpenAPIpath/v1/otp/confirm(pages/api/v1/otp/confirm.ts#L22-L52).OpenAPIpath/v1/otp/send(pages/api/v1/otp/send.ts#L20-L32).OpenAPIpath/v1/flow/resend, usado como reenvio da mensagem final na continuação do fluxo (pages/api/v1/flow/resend.ts#L21-L41).
Dados impactados
- A feature depende de
SessionUserparacpf,phone,id,course_slugenamee consomeCourseCustomizationpara os dados do template de fluxo (OTPConfirmation.component.tsx#L11-L20, pages/api/v1/otp/confirm.ts#L37-L46).
Pendências
- O fluxo de alteração de telefone no diálogo de reenvio está comentado e não existe como jornada ativa.
- O estado
submitStatus = successnão é explorado visualmente no formulário atual.
Evidências: