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,175 @@
# API Contract: Auth Endpoints
**Prefixo**: `/api/v1/auth`
**Blueprint**: `auth_bp` em `backend/app/routes/auth.py`
**Content-Type**: `application/json`
**Autenticação**: Bearer token via header `Authorization` (onde indicado)
---
## POST /api/v1/auth/register
Cria uma nova conta de cliente. Token de acesso emitido imediatamente na resposta.
### Request Body
```json
{
"name": "João Silva",
"email": "joao@exemplo.com",
"password": "minhasenha123"
}
```
| Campo | Tipo | Obrigatório | Regras |
|-------|------|-------------|--------|
| `name` | string | ✅ | 1150 caracteres |
| `email` | string (RFC 5321) | ✅ | Email válido; normalizado para lowercase antes de persistir |
| `password` | string | ✅ | Mínimo 8 caracteres |
### Respostas
**201 Created**
```json
{
"access_token": "<jwt_string>",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "joao@exemplo.com",
"role": "client",
"created_at": "2026-04-13T15:00:00"
}
}
```
**409 Conflict** — e-mail já cadastrado
```json
{ "error": "E-mail já cadastrado." }
```
**422 Unprocessable Entity** — falha de validação Pydantic
```json
{
"error": "Dados inválidos.",
"details": [
{ "loc": ["body", "password"], "msg": "String should have at least 8 characters", "type": "string_too_short" }
]
}
```
---
## POST /api/v1/auth/login
Autentica um cliente existente e emite token de acesso.
### Request Body
```json
{
"email": "joao@exemplo.com",
"password": "minhasenha123"
}
```
| Campo | Tipo | Obrigatório |
|-------|------|-------------|
| `email` | string (email válido) | ✅ |
| `password` | string | ✅ |
### Respostas
**200 OK**
```json
{
"access_token": "<jwt_string>",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "joao@exemplo.com",
"role": "client",
"created_at": "2026-04-13T15:00:00"
}
}
```
**401 Unauthorized** — e-mail não encontrado **ou** senha incorreta (mesma resposta para não revelar qual campo falhou — FR-007, SC-006)
```json
{ "error": "Credenciais inválidas." }
```
**422 Unprocessable Entity** — falha de validação Pydantic
```json
{ "error": "Dados inválidos.", "details": [...] }
```
---
## GET /api/v1/auth/me
Retorna dados do usuário autenticado. Requer `Authorization: Bearer <token>`.
### Headers
```
Authorization: Bearer <jwt_string>
```
### Respostas
**200 OK**
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "joao@exemplo.com",
"role": "client",
"created_at": "2026-04-13T15:00:00"
}
```
**401 Unauthorized** — sem token, token inválido ou token expirado
```json
{ "error": "Token de acesso inválido ou expirado." }
```
---
## JWT Payload
```json
{
"sub": "<uuid-string do ClientUser>",
"exp": <unix timestamp now() + 7 dias>
}
```
| Campo | Valor |
|-------|-------|
| Algorithm | HS256 |
| Secret | `JWT_SECRET_KEY` (variável de ambiente) |
| TTL | 7 dias (604800 s) |
| Claim `sub` | UUID do `ClientUser` como string |
---
## Envelope de Erro Padrão
Todas as respostas de erro seguem o envelope:
```json
{ "error": "<mensagem legível>" }
```
Erros de validação 422 incluem `details` com a lista de erros Pydantic.
Respostas de erro **nunca** incluem informações que permitam distinguir e-mail vs. senha incorretos (SC-006).
---
## Notas de Segurança
- Nenhuma resposta inclui `password_hash`
- `401` em credenciais inválidas NÃO DEVE indicar qual campo está incorreto
- `JWT_SECRET_KEY` NUNCA deve aparecer em logs ou respostas da API
- CORS configurado explicitamente em `create_app()` (sem wildcard em produção)