sass-imobiliaria/.specify/features/005-authentication/plan.md

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.