# Research: Property Detail Page (004) **Feature**: `004-property-detail-page` **Date**: 2026-04-13 **Status**: Complete — todos os NEEDS CLARIFICATION resolvidos --- ## R-01 — Campos `code` e `description` ausentes no modelo `Property` **Pergunta**: Os campos `code` e `description` devem ser adicionados nesta feature ou numa feature separada? **Evidência**: O contrato da API em `spec.md` inclui explicitamente `"code": "AP-00042"` e `"description": "..."` na resposta de `GET /api/v1/properties/`. A Constituição (Princípio III) define que a spec é a fonte de verdade. **Decisão**: Adicionar ambos os campos ao modelo `Property` nesta feature. A migration que cria `contact_leads` também incluirá as novas colunas. **Campos a adicionar**: - `code`: `VARCHAR(30)`, `UNIQUE`, `nullable=True` (nullable para não quebrar registros existentes sem migration data) - `description`: `TEXT`, `nullable=True` **Rationale**: Agrupar numa única migration evita fragmentação de DDL. Os campos são necessários para o contrato da API desta feature. **Alternativa rejeitada**: Feature separada só para `code`/`description` — overhead desnecessário para dois campos simples. --- ## R-02 — Campo `address` ausente em `PropertyOut` **Pergunta**: O campo `address` existe no modelo mas não está em `PropertyOut`. Como tratar? **Evidência**: `Property.address = db.Column(db.String(300), nullable=True)` existe no modelo. `PropertyOut` não inclui `address`. O contrato da spec exige `address` na resposta de detalhe. **Decisão**: Adicionar `address: str | None` ao `PropertyOut` existente. É um campo geral do imóvel (não exclusivo da tela de detalhe) e sua ausência no schema era uma omissão. **Impacto nos consumers existentes**: O endpoint `GET /api/v1/properties` (list) passará a incluir `address` na resposta. Isso é retrocompatível — campos adicionais em JSON não quebram consumers que não os leem. **Alternativa rejeitada**: `PropertyDetailOut` separado apenas para `address` — over-engineering para um campo que logicamente pertence ao schema base. --- ## R-03 — `type` vs `listing_type` no contrato da API **Pergunta**: O contrato da spec documenta `listing_type` mas o schema e o modelo usam `type`. O que usar na implementação? **Evidência**: - Model: `type = db.Column(db.Enum("venda", "aluguel", name="property_type"))` - `PropertyOut`: `type: Literal["venda", "aluguel"]` - Spec API contract: `"listing_type": "venda"` **Decisão**: Manter `type` no schema e na serialização JSON. O contrato da spec usa `listing_type` como nome descritivo na documentação, mas o campo JSON emitido pelo backend será `type` (consistente com o endpoint de listagem já em produção). A spec documenta o _significado_ do campo, não exige renaming. **Rationale**: Renomear para `listing_type` quebraria o endpoint de listagem que já retorna `type`. Backward compatibility supera a preferência de nomenclatura da spec, especialmente porque o frontend já consome `type`. **Alternativa rejeitada**: Alias Pydantic `listing_type` via `Field(alias="type")` — introduziria inconsistência entre list e detail sem benefício real no MVP. --- ## R-04 — Carousel: biblioteca externa vs handlers nativos **Pergunta**: Usar Embla Carousel, Swiper.js ou implementar com React state + handlers nativos? **Análise**: | Opção | Tamanho bundle | Complexidade | Justificativa | |-------|---------------|--------------|---------------| | Embla Carousel | ~7 KB gzip | baixa (API simples) | overkill para carousel básico | | Swiper.js | ~35 KB gzip | média-alta | excesso de features desnecessárias | | React state nativo | 0 KB extra | baixa-média | suficiente para os requisitos da spec | **Requisitos da spec**: navegação por teclado (←/→), swipe touch, thumbnail strip com estado ativo. Tudo implementável com: - `useState` para índice ativo - `onKeyDown` no container (tabIndex=0) - `onTouchStart`/`onTouchEnd` para detectar swipe horizontal - CSS `transition` para animação suave **Decisão**: Implementar com React state + handlers nativos. Zero nova dependência npm (alinhamento com Princípio VI). **Rationale**: Os requisitos são exatos e limitados. Uma lib traz overhead de API para aprender, bundle weight extra e potencial conflito com o design system customizado. --- ## R-05 — Mapa (US3 P3): Google Maps Embed **Pergunta**: Qual serviço de mapa usar para US3? Chave de API necessária? **Análise**: - US3 é P3 (prioridade mais baixa) — não bloqueia o MVP funcional - Google Maps Embed API: iframe simples, sem SDK JS, sem package npm - URL: `https://www.google.com/maps/embed/v1/place?key=API_KEY&q=ENDEREÇO_CODIFICADO` - Requer chave de API com "Maps Embed API" habilitada - OpenStreetMap via `iframe` Nominatim: gratuito, sem chave, mas qualidade variável **Decisão**: Google Maps Embed via `