Feature: Course Registration
Introdução ao documento
Este documento descreve a feature de inscrição/login exposta em /{slug}/inscricao, cobrindo CPF, caminho AMEI e regras de elegibilidade aplicadas na autenticação.
Evidências:
../../app/[slug]/inscricao/page.tsx#L12-L27../../src/features/components/CourseRegistration/CourseRegistration.component.tsx#L28-L214../../pages/api/auth/[...nextauth].ts#L25-L155
Versionamento
Atualizar este documento quando mudarem:
- a ativação de AMEI/fallback;
- as validações de CPF;
- as regras de bloqueio em
NextAuth; - a navegação para a próxima etapa.
Evidências:
../../app/[slug]/inscricao/page.tsx#L15-L24../../src/features/components/CourseRegistration/CourseRegistration.schema.ts#L4-L10../../pages/api/auth/[...nextauth].ts#L46-L127
Referencial teórico
O mapeamento desta feature foi derivado da rota de inscrição, do formulário client-side, dos toggles de AMEI/fallback e do provider de credenciais do NextAuth.
Evidências:
../../app/[slug]/inscricao/page.tsx#L12-L27../../src/common/util/toggles/toggleAmeiIntegration.ts#L1-L3../../src/common/util/inscriptionFallback/inscriptionFallback.ts#L1-L5../../pages/api/auth/[...nextauth].ts#L39-L151
Visão geral
- A página busca dados do curso, decide se o login AMEI deve ser usado e renderiza
CourseRegistration(inscricao/page.tsx#L15-L24). - O formulário aceita CPF ou fluxo AMEI e, em ambos os casos, tenta autenticar com
signIn("cpf")(CourseRegistration.component.tsx#L45-L75, CourseRegistration.component.tsx#L110-L114). - A autorização final passa pelo catch-all do
NextAuth, que valida participante e elegibilidade antes de montar a sessão (pages/api/auth/[...nextauth].ts#L46-L127).
Atores
- Participante (CourseRegistration.component.tsx#L140-L196).
- App Next.js /
NextAuth(CourseRegistration.component.tsx#L110-L114, pages/api/auth/[...nextauth].ts#L25-L155). - AMEI/Keycloak, quando habilitado (CourseRegistration.component.tsx#L45-L75, ../../pages/api/config/keycloak.ts#L22-L61).
- Backend WordPress de pessoa e matrícula (pages/api/auth/[...nextauth].ts#L65-L99).
Pré-condições
- O curso precisa existir e ter
logo; sem isso a página cai emnotFound(inscricao/page.tsx#L15-L20). - Para o caminho AMEI,
TOGGLE_AMEI_INTEGRATIONprecisa estar ativo e o fallback não pode ter sido solicitado (inscricao/page.tsx#L15-L16, toggleAmeiIntegration.ts#L1-L3, inscriptionFallback.ts#L1-L5). - Para o caminho CPF, o valor precisa passar pela validação de schema (CourseRegistration.schema.ts#L4-L10).
Fluxo principal
- A página calcula
useAmeiAutha partir do toggle e do query paramfallback(inscricao/page.tsx#L15-L16). - O componente limpa sessão anterior com
signOut({ redirect: false })(CourseRegistration.component.tsx#L87-L89). - No fluxo CPF, o participante informa o documento e dispara
signIn("cpf", { cpf, course_slug })(CourseRegistration.component.tsx#L110-L114). - No fluxo AMEI, o usuário é autenticado externamente e depois o CPF limpo é reutilizado no mesmo
signIn("cpf")(CourseRegistration.component.tsx#L45-L69). - Em caso de sucesso, a navegação avança para
/{slug}/inscricao/confirmacao(CourseRegistration.component.tsx#L61-L65, CourseRegistration.component.tsx#L95-L102).
Fluxos alternativos
- Se
pageErrorvier na query string, a tela mostra snackbar de erro (CourseRegistration.component.tsx#L40-L43, CourseRegistration.component.tsx#L91-L93). - Se o login AMEI retornar erro, a feature abre
NotifyModale volta para a home do curso no fechamento/confirmação (CourseRegistration.component.tsx#L57-L60, CourseRegistration.component.tsx#L198-L210). - Se o login CPF falhar, o erro é colocado no campo
cpf(CourseRegistration.component.tsx#L95-L107). - Se
useAmeiAuthfor falso, o botão de conta Sebrae não é renderizado (CourseRegistration.component.tsx#L170-L188).
Regras de negócio
- O CPF é obrigatório, precisa ter 11 dígitos e passar por
validateCpf(CourseRegistration.schema.ts#L4-L10, validateCpf.ts#L10-L18). - O fallback de inscrição sem AMEI só entra quando o toggle
TOGGLE_INSCRIPTION_FALLBACKestiver ativo efallback=true|1vier na URL (inscriptionFallback.ts#L1-L5). - A integração AMEI só participa da feature quando
TOGGLE_AMEI_INTEGRATION === "true"(toggleAmeiIntegration.ts#L1-L3, inscricao/page.tsx#L15-L16). - A autenticação rejeita novas tentativas quando há 5 requisições concorrentes ativas no provider de credenciais (pages/api/auth/[...nextauth].ts#L11-L18, pages/api/auth/[...nextauth].ts#L49-L56).
- A autenticação bloqueia participante já inscrito, inscrito em curso da mesma categoria, inscrito em curso concorrente no mesmo período ou com mais de um cancelamento acumulado (pages/api/auth/[...nextauth].ts#L71-L98).
- O fluxo inteiro de autorização tem timeout máximo de 15 segundos (pages/api/auth/[...nextauth].ts#L63-L64, pages/api/auth/[...nextauth].ts#L109-L120).
Estados possíveis
idle,loading,success,errorno submit local (CourseRegistration.component.tsx#L36-L39).- AMEI habilitado / desabilitado (inscricao/page.tsx#L15-L16).
- Modal de informação fechado / aberto (CourseRegistration.component.tsx#L42-L43, CourseRegistration.component.tsx#L198-L210).
- Sessão criada / sessão rejeitada (pages/api/auth/[...nextauth].ts#L101-L106, pages/api/auth/[...nextauth].ts#L121-L127).
Endpoints envolvidos
- Endpoint interno documentado:
OpenAPIpath/config/keycloak, usado pelo carregamento da integração AMEI (pages/api/config/keycloak.ts#L14-L61). - Rota principal de autenticação:
/api/auth/[...nextauth], usada pela feature, mas fora da cobertura do OpenAPI atual (CourseRegistration.component.tsx#L55-L56, CourseRegistration.component.tsx#L112-L113).
Dados impactados
- A feature lê e prepara
Participant,SessionUser,EnrollmentSnapshoteCourseCycleStatuspara decidir elegibilidade e montar sessão (pages/api/auth/[...nextauth].ts#L65-L106).
Pendências
- O catch-all de
NextAuthcontinua sem contrato OpenAPI local. - O comportamento quando
useAmeiAuth = truemas o usuário AMEI ainda não temcpfexplícito não gera mensagem de erro própria na UI.
Evidências: