5.4 KiB
Implementation Plan: Sistema de Autenticação de Clientes
Branch: 005-authentication | Date: 2026-04-13 | Spec: spec.md
Input: Sistema de autenticação para clientes: login com e-mail + senha (JWT, sem OAuth), auto-cadastro público.
Summary
Adiciona autenticação JWT ao SaaS imobiliário. Backend: novo model ClientUser na tabela client_users, hashing de senha com bcrypt, emissão de token PyJWT com TTL de 7 dias, blueprint /api/v1/auth com endpoints register/login/me, e decorator require_auth reutilizável para proteger rotas. Frontend: AuthContext com persistência em localStorage, páginas Login e Cadastro no tema Linear escuro do projeto, interceptor Axios automático para injeção do header Authorization, e ProtectedRoute que guarda /area-do-cliente/*.
Technical Context
Language/Version: Python 3.12 (backend) · TypeScript 5.5 (frontend)
Primary Dependencies: Flask 3.x, SQLAlchemy 2.x, Pydantic v2, PyJWT>=2.9, bcrypt>=4.2, pydantic[email]; React 18, react-router-dom v6, Axios
Storage: PostgreSQL 16 via Flask-SQLAlchemy — nova tabela client_users via migration Alembic
Testing: pytest + pytest-flask (backend); nenhum teste automatizado de frontend nesta fase
Target Platform: Linux/Docker (servidor) + navegadores modernos (SPA)
Project Type: Web service REST + Single Page Application
Performance Goals: <200ms p95 nos endpoints de autenticação
Constraints: Stateless JWT, TTL de 7 dias, sem refresh token, sem verificação de e-mail, sem rate limiting (escopo MVP definido na spec)
Scale/Scope: MVP, ~100 usuários iniciais, single-tenant
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
| Princípio | Status | Justificativa |
|---|---|---|
| I. Design-First | ✅ PASS | LoginPage e RegisterPage seguem DESIGN.md: fundo #08090a, panel #0f1011, tipografia Inter Variable, accent #5e6ad2/#7170ff, bordas rgba(255,255,255,0.06). Mesmo estilo do PropertiesPage existente. |
| II. Separation of Concerns | ✅ PASS | Flask retorna JSON puro; React é SPA. CORS configurado explicitamente em create_app(). Sem Jinja2 nas rotas da API. |
| III. Spec-Driven | ✅ PASS | spec.md aprovado. Ciclo spec → plan → tasks → implement respeitado. |
| IV. Data Integrity | ✅ PASS | Todos os inputs validados por Pydantic (RegisterIn/LoginIn). Migration Alembic. Tipos corretos (String, UUID, DateTime). nullable=False declarado explicitamente em todos os campos obrigatórios. |
| V. Security | ✅ PASS | JWT_SECRET_KEY lido exclusivamente de variável de ambiente. bcrypt irreversível. 401 genérico em credenciais inválidas (SC-006). password_hash ausente em todas as respostas. |
| VI. Simplicity First | ✅ PASS | 2 novos pacotes com razão clara (PyJWT para JWT, bcrypt para hashing). Sem refresh token, verificação de e-mail ou rate limiting (YAGNI — fora do escopo MVP conforme assumptions da spec). Sem flask-jwt-extended (overhead desnecessário). |
Gate Result: ✅ PASS — nenhuma violação. Prosseguir para Phase 0.
Project Structure
Documentation (this feature)
.specify/features/005-authentication/
├── plan.md # Este arquivo
├── research.md # Fase 0 — resolução de unknowns (gerado)
├── data-model.md # Fase 1 — modelo de dados (gerado)
├── quickstart.md # Fase 1 — como rodar e testar (gerado)
├── contracts/
│ └── auth-api.md # Contratos dos endpoints /api/v1/auth (gerado)
└── tasks.md # Fase 2 — gerado pelo /speckit.tasks
Source Code
backend/
├── app/
│ ├── models/
│ │ └── user.py # ClientUser — NOVO
│ ├── schemas/
│ │ └── auth.py # RegisterIn, LoginIn, UserOut, AuthTokenOut — NOVO
│ ├── routes/
│ │ └── auth.py # auth_bp (/api/v1/auth) — NOVO
│ ├── utils/
│ │ └── auth.py # require_auth decorator — NOVO
│ └── __init__.py # ATUALIZADO: user model import + auth blueprint + JWT_SECRET_KEY
├── migrations/versions/
│ └── <hash>_add_client_users.py # NOVO — gerado via flask db migrate
└── pyproject.toml # ATUALIZADO: PyJWT>=2.9, bcrypt>=4.2, pydantic[email]
frontend/
└── src/
├── types/
│ └── auth.ts # User, AuthState — NOVO
├── contexts/
│ └── AuthContext.tsx # AuthProvider, useAuth — NOVO
├── services/
│ ├── api.ts # ATUALIZADO: interceptor Authorization header
│ └── auth.ts # registerUser, loginUser, getMe — NOVO
├── pages/
│ ├── LoginPage.tsx # rota /login — NOVO
│ └── RegisterPage.tsx # rota /cadastro — NOVO
├── components/
│ ├── ProtectedRoute.tsx # redireciona se !isAuthenticated — NOVO
│ └── Navbar.tsx # ATUALIZADO: Entrar / avatar + Sair
└── App.tsx # ATUALIZADO: AuthProvider wrap + novas rotas
Complexity Tracking
Sem violações de constituição — esta seção não se aplica.