7 KiB
Implementation Plan: Área do Cliente
Branch: master | Date: 2026-04-13 | Spec: spec.md
Input: Feature specification from .specify/features/006-client-area/spec.md
Depends On: Feature 005 — ClientUser model, require_auth decorator, JWT middleware
Summary
Implementação da Área do Cliente: favoritos (persistidos no backend), comparação de imóveis (localStorage), histórico de visitas e boletos. O backend expõe dois blueprints novos (/api/v1/me e /api/v1/admin) com autenticação JWT. O frontend adiciona rotas protegidas sob /area-do-cliente, contextos React para favoritos e comparação, e componentes de interação (HeartButton, ComparisonBar).
Technical Context
Language/Version: Python 3.12 (backend) · TypeScript 5.5 (frontend)
Primary Dependencies: Flask 3.x, SQLAlchemy 2.x, Pydantic v2, PyJWT (backend) · React 18, react-router-dom v6, Axios, Tailwind CSS 3.4 (frontend)
Storage: PostgreSQL 16 — 3 novas tabelas: saved_properties, visit_requests, boletos
Testing: pytest (backend) — testes de rotas com client fixture; Vite build check (frontend)
Target Platform: Servidor Linux (Docker) + SPA na mesma origem via proxy Vite
Project Type: Web service (Flask REST API) + SPA (React)
Performance Goals: Favoritar/desfavoritar < 2 s; tabela de comparação renderizada < 1 s para 3 imóveis
Constraints: Comparação não persiste no backend; admin sem UI no MVP; sem integração com gateway de pagamento
Scale/Scope: MVP — funcionalidades essenciais da área logada; admin opera via API direta
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
| Princípio | Status | Observação |
|---|---|---|
| I. Design-First | ✅ PASS | Todos os novos componentes React usam tokens do DESIGN.md: fundo #08090a, painéis #0f1011, acento #5e6ad2/#7170ff. Nenhum estilo inline fora do sistema. |
| II. Separation of Concerns | ✅ PASS | Flask retorna JSON puro; React é SPA. Contextos (FavoritesContext, ComparisonContext) são camada de estado frontend apenas. |
| III. Spec-Driven | ✅ PASS | spec.md aprovado → plan.md (este arquivo) → tasks.md → implementação. |
| IV. Data Integrity | ✅ PASS | Todas as entradas via Pydantic schemas. amount usa Numeric(12, 2). Novas tabelas via migração Alembic. Foreign keys explicitamente anuláveis ou não-anuláveis conforme modelo. |
| V. Security | ⚠️ PARTIAL | /api/v1/me/* protegido por require_auth. /api/v1/admin/* protegido por require_auth mas sem verificação de role no MVP — qualquer ClientUser autenticado pode acessar rotas admin. FR-018 exige 403 para token de ClientUser; esta verificação é adiada e documentada como dívida técnica (ver Complexity Tracking). |
| VI. Simplicity First | ✅ PASS | Comparação em localStorage (sem backend). Sem gateway de pagamento. Admin sem UI. Nenhuma abstração nova sem 3+ usos concretos. |
POST-DESIGN RE-CHECK: ✅ Após Phase 1, o modelo de dados não introduz complexidade adicional. Violação de Princípio V documentada como dívida técnica deliberada para MVP.
Project Structure
Documentation (this feature)
.specify/features/006-client-area/
├── plan.md # Este arquivo
├── research.md # Fase 0 — decisões e alternativas
├── data-model.md # Fase 1 — entidades e relacionamentos
├── quickstart.md # Fase 1 — como rodar e testar localmente
├── contracts/
│ ├── me-favorites.md
│ ├── me-visits.md
│ ├── me-boletos.md
│ └── admin.md
└── tasks.md # Fase 2 (gerado por /speckit.tasks)
Source Code (repository root)
backend/
├── app/
│ ├── models/
│ │ ├── saved_property.py # NOVO — SavedProperty
│ │ ├── visit_request.py # NOVO — VisitRequest
│ │ ├── boleto.py # NOVO — Boleto
│ │ └── client_user.py # PRÉ-REQUISITO (Feature 005)
│ ├── schemas/
│ │ └── client_area.py # NOVO — todos os schemas de entrada/saída
│ ├── routes/
│ │ ├── client_area.py # NOVO — blueprint client_bp (/api/v1/me)
│ │ └── admin.py # NOVO — blueprint admin_bp (/api/v1/admin)
│ └── __init__.py # ATUALIZAR — registrar modelos e blueprints
└── migrations/
└── versions/
└── xxxx_add_saved_properties_visit_requests_boletos.py # NOVO
frontend/
└── src/
├── types/
│ └── clientArea.ts # NOVO — VisitRequest, Boleto, ComparisonState
├── contexts/
│ ├── ComparisonContext.tsx # NOVO — estado de comparação (localStorage)
│ └── FavoritesContext.tsx # NOVO — favoritos (backend, apenas logado)
├── components/
│ ├── ComparisonBar.tsx # NOVO — barra flutuante rodapé
│ ├── HeartButton.tsx # NOVO — toggle favorito
│ ├── PropertyCard.tsx # ATUALIZAR — HeartButton + botão Comparar
│ └── PropertyDetail/
│ └── ContactSection.tsx # ATUALIZAR — criar VisitRequest se logado
├── layouts/
│ └── ClientLayout.tsx # NOVO — sidebar da área do cliente
├── pages/
│ └── client/
│ ├── ClientDashboardPage.tsx # NOVO
│ ├── FavoritesPage.tsx # NOVO
│ ├── ComparisonPage.tsx # NOVO
│ ├── VisitsPage.tsx # NOVO
│ └── BoletosPage.tsx # NOVO
├── services/
│ └── clientArea.ts # NOVO — getFavorites, addFavorite, removeFavorite, getVisits, getBoletos
└── App.tsx # ATUALIZAR — rotas protegidas + providers de contexto
backend/tests/
├── test_client_area.py # NOVO — testes de rotas /me e /admin
└── conftest.py # ATUALIZAR — fixture client_user + auth token
Structure Decision: Web application (Option 2). Backend Flask REST API + frontend React SPA. Estrutura de arquivos segue o padrão já estabelecido no projeto (um arquivo por model, um arquivo por blueprint, schemas agrupados por domínio).
Complexity Tracking
| Violação | Por que necessária | Alternativa mais simples rejeitada porque |
|---|---|---|
Princípio V: rotas /api/v1/admin/* sem verificação de role no MVP |
Admin opera via API direta; implementar RBAC completo exige tabela de roles, seed e testes adicionais fora do escopo desta feature | Adicionar require_admin_role desde já acoplaria esta feature a Feature 005 e bloquearia o MVP sem benefício real — único usuário da API admin é o próprio dono da aplicação |