12 KiB
Feature Specification: Sistema de Autenticação de Clientes
Feature Branch: 005-authentication
Created: 2026-04-13
Status: Draft
Input: User description: "Sistema de autenticação para clientes: login com e-mail + senha (JWT, sem OAuth), auto-cadastro público."
User Scenarios & Testing (mandatory)
User Story 1 - Cadastro Público de Novo Cliente (Priority: P1)
Qualquer pessoa pode criar uma conta no sistema fornecendo nome, e-mail e senha. Após o cadastro, o usuário recebe imediatamente um token de acesso e pode utilizar o sistema sem etapas adicionais de verificação.
Why this priority: É o ponto de entrada do sistema. Sem cadastro funcional, nenhuma outra funcionalidade de autenticação é utilizável. Entregar apenas P1 já permite que um novo usuário se registre e acesse a plataforma.
Independent Test: Pode ser testado isoladamente realizando um cadastro com dados válidos e verificando que o sistema retorna token de acesso e dados do usuário criado; e tentando cadastrar com e-mail duplicado ou senha fraca para verificar as rejeições.
Acceptance Scenarios:
- Given um visitante não autenticado, When ele submete nome, e-mail válido e senha com pelo menos 8 caracteres, Then o sistema cria a conta, retorna status 201 e fornece um token de acesso junto com os dados básicos do usuário (id, nome, e-mail).
- Given um visitante tenta se cadastrar com um e-mail já existente no sistema, When ele submete o formulário, Then o sistema retorna status 409 indicando conflito, sem revelar informações sobre a conta existente.
- Given um visitante tenta se cadastrar com senha contendo menos de 8 caracteres, When ele submete o formulário, Then o sistema retorna status 422 indicando que a senha não atende aos requisitos mínimos.
- Given o formulário de cadastro com campo "confirmar senha" preenchido de forma diferente da senha, When o usuário tenta submeter, Then o sistema exibe mensagem de validação no formulário sem enviar a requisição.
User Story 2 - Login de Cliente Existente (Priority: P2)
Um cliente já cadastrado pode acessar o sistema fornecendo seu e-mail e senha. Após autenticação bem-sucedida, recebe um token de acesso e é redirecionado para sua área pessoal.
Why this priority: É o fluxo principal de acesso recorrente ao sistema. Depende de P1 (a conta precisa existir), mas pode ser desenvolvido e testado de forma independente com dados pré-cadastrados.
Independent Test: Pode ser testado isoladamente realizando login com credenciais válidas (espera token + dados do usuário) e com credenciais inválidas (espera 401 com mensagem genérica). Erro de rede deve exibir mensagem amigável.
Acceptance Scenarios:
- Given um cliente com conta cadastrada, When ele fornece e-mail e senha corretos, Then o sistema retorna status 200 com token de acesso e informações básicas do usuário (id, nome, e-mail).
- Given um visitante, When ele fornece e-mail não cadastrado ou senha incorreta, Then o sistema retorna status 401 com mensagem genérica — sem indicar qual campo está incorreto.
- Given um usuário no formulário de login, When ocorre erro de rede na requisição, Then o formulário exibe mensagem de erro amigável sem expor detalhes técnicos e permite nova tentativa.
User Story 3 - Acesso a Rotas Protegidas com Token (Priority: P3)
Rotas marcadas como protegidas só podem ser acessadas por clientes autenticados. Requisições sem token ou com token inválido/expirado são rejeitadas automaticamente. A interface redireciona usuários não autenticados para o login.
Why this priority: Garante a integridade do sistema. Sem esse mecanismo, dados privados estariam acessíveis publicamente. Depende de P1 e P2 para que haja tokens válidos no sistema.
Independent Test: Pode ser testado tentando acessar uma rota protegida sem token (espera 401 e redirecionamento para /login), com token válido (espera dados normais), e com token expirado ou adulterado (espera 401).
Acceptance Scenarios:
- Given um cliente autenticado com token válido, When ele acessa uma rota protegida enviando o token no cabeçalho de autorização, Then o sistema processa a requisição normalmente e retorna os dados solicitados.
- Given uma requisição sem token de autorização, When tenta acessar uma rota protegida, Then o sistema retorna status 401.
- Given uma requisição com token expirado ou adulterado, When tenta acessar uma rota protegida, Then o sistema retorna status 401.
- Given um usuário não autenticado navegando na interface, When tenta acessar uma página protegida, Then a interface redireciona automaticamente para a tela de login.
User Story 4 - Visualização do Perfil do Cliente Autenticado (Priority: P4)
Um cliente autenticado pode consultar seus próprios dados de perfil: nome, e-mail, papel e data de criação da conta, sem precisar informar o próprio identificador na URL.
Why this priority: Funcionalidade de suporte à identidade do usuário logado. Depende dos fluxos P1–P3 para ter sentido prático.
Independent Test: Pode ser testado acessando o endpoint de perfil com token válido (espera dados completos do usuário autenticado) e sem token (espera 401).
Acceptance Scenarios:
- Given um cliente autenticado, When ele consulta o endpoint de perfil próprio, Then o sistema retorna id, nome, e-mail, papel (role) e data de criação da conta.
- Given uma requisição sem token de autorização, When tenta consultar o perfil, Then o sistema retorna status 401.
Edge Cases
- E-mail duplicado no cadastro: Sistema retorna 409 Conflict sem revelar dados da conta existente.
- Senha abaixo do mínimo: Sistema retorna 422 Unprocessable Entity com descrição do critério não atendido.
- Token JWT adulterado ou expirado: Sistema retorna 401 Unauthorized em qualquer rota protegida.
- Credenciais inválidas no login: Sistema retorna 401 com mensagem genérica — não revela se o e-mail ou a senha está errado.
- Erro de rede nos formulários: Interface exibe mensagem de erro amigável e permite nova tentativa, sem expor erros técnicos.
- Usuário não autenticado em rota protegida: Interface redireciona para /login preservando a intenção de navegação.
- Senha de confirmação não coincide: Validação no formulário impede envio e exibe mensagem explicativa.
- Token armazenado localmente e sessão do servidor: Como o sistema é stateless, não há sessão a invalidar; o logout apenas remove o token do armazenamento do navegador.
Requirements (mandatory)
Functional Requirements
- FR-001: O sistema DEVE permitir que qualquer visitante crie uma conta fornecendo nome, e-mail e senha, sem necessidade de aprovação prévia.
- FR-002: O sistema DEVE validar que senhas tenham no mínimo 8 caracteres no momento do cadastro e retornar erro de validação (422) quando o critério não for atendido.
- FR-003: O sistema DEVE rejeitar cadastros com e-mail já existente retornando resposta 409, sem revelar informações sobre a conta existente.
- FR-004: O sistema DEVE armazenar senhas de forma irreversível — nunca em texto puro.
- FR-005: O sistema DEVE normalizar e-mails para letras minúsculas tanto no armazenamento quanto na comparação durante o login.
- FR-006: O sistema DEVE emitir um token de acesso com validade de 7 dias após cadastro ou login bem-sucedido.
- FR-007: O sistema DEVE retornar resposta genérica (401) em caso de credenciais inválidas no login, sem indicar qual campo (e-mail ou senha) está incorreto.
- FR-008: O sistema DEVE proteger as rotas designadas como privadas, rejeitando com 401 qualquer requisição que não apresente token válido no cabeçalho de autorização.
- FR-009: O sistema DEVE disponibilizar endpoint para o cliente autenticado consultar seus próprios dados de perfil (id, nome, e-mail, papel, data de criação).
- FR-010: O sistema DEVE carregar o segredo de assinatura do token a partir de variável de ambiente — nunca embutido no código-fonte.
- FR-011: A interface DEVE manter o estado de autenticação do usuário entre navegações na aplicação durante a vigência do token.
- FR-012: A interface DEVE redirecionar automaticamente usuários não autenticados para a tela de login ao tentar acessar áreas protegidas.
- FR-013: A interface DEVE redirecionar usuários para a área do cliente após login ou cadastro bem-sucedido.
- FR-014: A interface DEVE exibir opção de "Entrar" na barra de navegação para visitantes não autenticados, e o nome do usuário com opção de "Sair" quando autenticado.
- FR-015: A interface DEVE adicionar o token de autenticação automaticamente em todas as requisições para rotas protegidas, sem necessidade de configuração manual por página.
- FR-016: A interface DEVE exibir mensagem de erro amigável quando ocorrer falha de rede nos formulários de login ou cadastro.
API Contract
| Endpoint | Método | Corpo da Requisição | Resposta de Sucesso | Respostas de Erro |
|---|---|---|---|---|
/api/v1/auth/register |
POST | {name, email, password} |
201 {access_token, user: {id, name, email}} |
409 (e-mail duplicado), 422 (validação) |
/api/v1/auth/login |
POST | {email, password} |
200 {access_token, user: {id, name, email}} |
401 (credenciais inválidas) |
/api/v1/auth/me |
GET | — (Bearer token no header) | 200 {id, name, email, role, created_at} |
401 (sem token ou token inválido) |
Key Entities
- ClientUser: Representa um cliente cadastrado no sistema. Atributos: identificador único (UUID), nome completo (até 150 caracteres), e-mail (único no sistema, até 254 caracteres), senha protegida (hash irreversível), papel no sistema (padrão: 'client'), data e hora de criação da conta.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Um novo visitante consegue criar uma conta e receber token de acesso em menos de 2 minutos ao utilizar o formulário de cadastro.
- SC-002: Um cliente cadastrado consegue realizar login e ser redirecionado para sua área em menos de 30 segundos.
- SC-003: 100% das tentativas de acesso a rotas protegidas sem token válido resultam em rejeição (401) — nenhuma rota protegida é acessível sem autenticação.
- SC-004: 100% das senhas armazenadas no sistema são protegidas — nenhuma é recuperável em texto puro a partir do banco de dados.
- SC-005: O estado de autenticação do usuário persiste entre recarregamentos de página durante o período de validade do token.
- SC-006: Nenhuma resposta do sistema revela se a falha de login se deve ao e-mail ou à senha incorretos — todas as falhas de credencial retornam a mesma mensagem genérica.
- SC-007: O segredo de assinatura de token nunca aparece no código-fonte versionado — auditoria do repositório não encontra nenhuma ocorrência da chave em texto puro.
Assumptions
- Sem verificação de e-mail: A confirmação de conta via link de e-mail está fora do escopo desta versão (MVP). Toda conta criada é imediatamente ativa.
- Sem recuperação de senha: O fluxo "esqueci minha senha" está fora do escopo desta versão.
- Apenas papel 'client': O papel 'admin' é reservado para uso futuro e não possui proteção ou fluxo de acesso implementados nesta versão.
- Sem refresh token: A renovação automática do token de acesso está fora do escopo desta versão. O usuário precisará fazer login novamente após a expiração (7 dias).
- Sem rate limiting de login: Limitação de tentativas de acesso é responsabilidade de infraestrutura e está fora do escopo desta feature.
- HTTPS em produção: A segurança do token em trânsito é garantida pela camada de transporte. O sistema pressupõe ambiente HTTPS em produção.
- Token no armazenamento do navegador: O token é mantido no armazenamento local do navegador; o logout é realizado removendo-o localmente (o servidor não invalida tokens emitidos, pois o sistema é stateless).
- Design conforme sistema vigente: Telas de login e cadastro seguem o design system definido em
DESIGN.md— tema Linear escuro com paleta de cores e tipografia já estabelecidas no projeto.