feat: add full project - backend, frontend, docker, specs and configs

This commit is contained in:
MatheusAlves96 2026-04-20 23:59:45 -03:00
parent b77c7d5a01
commit e6cb06255b
24489 changed files with 61341 additions and 36 deletions

View file

@ -0,0 +1,140 @@
# 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**:
1. **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).
2. **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.
3. **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.
4. **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**:
1. **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).
2. **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.
3. **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**:
1. **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.
2. **Given** uma requisição sem token de autorização, **When** tenta acessar uma rota protegida, **Then** o sistema retorna status 401.
3. **Given** uma requisição com token expirado ou adulterado, **When** tenta acessar uma rota protegida, **Then** o sistema retorna status 401.
4. **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 P1P3 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**:
1. **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.
2. **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.