sass-imobiliaria/specs/024-filtro-busca-avancada/contracts/api-catalog-enhancements.md
MatheusAlves96 cf5603243c
Some checks failed
CI/CD → Deploy via SSH / Build & Push Docker Images (push) Successful in 1m0s
CI/CD → Deploy via SSH / Deploy via SSH (push) Successful in 4m35s
CI/CD → Deploy via SSH / Validate HTTPS & Endpoints (push) Failing after 46s
feat: features 025-032 - favoritos, contatos, trabalhe-conosco, area-cliente, navbar, hero-light-dark, performance-homepage
- feat(025): favoritos locais com FavoritesContext, HeartButton, PublicFavoritesPage
- feat(026): central de contatos admin (leads/contatos unificados)
- feat(027): configuração da página de contato via admin
- feat(028): trabalhe conosco - candidaturas com upload e admin
- feat(029): UX área do cliente - visitas, comparação, perfil
- feat(030): navbar UX - menu mobile, ThemeToggle, useFavorites
- feat(031): hero light/dark - imagens separadas por tema, upload, preview, seed
- feat(032): performance homepage - Promise.all parallel fetches, sessionStorage cache,
  preload hero image, loading=lazy nos cards, useInView hook, will-change carrossel,
  keyframes em index.css, AgentsCarousel e HomeScrollScene via props
- fix: light mode HomeScrollScene - gradiente, cores de texto, scroll hint

migrations: g1h2i3j4k5l6 (source em leads), h1i2j3k4l5m6 (contact_config),
            i1j2k3l4m5n6 (job_applications), j2k3l4m5n6o7 (hero theme images)
2026-04-22 22:35:17 -03:00

4.1 KiB

API Catalog Enhancements — Contrato de Interface

Feature: 024-filtro-busca-avancada Tipo de mudança: Adição de campo somente-leitura em endpoints existentes (backward-compatible) Versão da API: /api/v1 (sem mudança de versão — campo adicional não quebra clientes existentes)


Resumo das Mudanças

Três endpoints existentes passam a incluir o campo property_count na resposta. Nenhum endpoint novo é criado. Nenhum parâmetro de entrada é modificado.


GET /api/v1/cities

Sem alteração na assinatura. O campo property_count é adicionado à resposta.

Response (200 OK)

[
  {
    "id": 1,
    "name": "Rio de Janeiro",
    "slug": "rio-de-janeiro",
    "state": "RJ",
    "property_count": 47
  },
  {
    "id": 2,
    "name": "São Paulo",
    "slug": "sao-paulo",
    "state": "SP",
    "property_count": 12
  },
  {
    "id": 3,
    "name": "Belo Horizonte",
    "slug": "belo-horizonte",
    "state": "MG",
    "property_count": 0
  }
]

Regras:

  • property_count conta apenas imóveis com is_active = true associados à cidade via properties.city_id
  • Cidades sem imóveis ativos retornam property_count: 0 (não são omitidas da lista)
  • Ordenação mantida: state ASC, name ASC

GET /api/v1/neighborhoods

Sem alteração na assinatura. Parâmetro opcional ?city_id=<int> permanece inalterado.

Response (200 OK)

[
  {
    "id": 10,
    "name": "Copacabana",
    "slug": "copacabana",
    "city_id": 1,
    "property_count": 23
  },
  {
    "id": 11,
    "name": "Ipanema",
    "slug": "ipanema",
    "city_id": 1,
    "property_count": 15
  },
  {
    "id": 12,
    "name": "Santa Teresa",
    "slug": "santa-teresa",
    "city_id": 1,
    "property_count": 0
  }
]

Regras:

  • property_count conta apenas imóveis com is_active = true via properties.neighborhood_id
  • Bairros sem imóveis ativos retornam property_count: 0
  • Ordenação mantida: name ASC
  • Filtro ?city_id mantém comportamento existente

GET /api/v1/property-types

Sem alteração na assinatura. property_count é adicionado nos subtypes (leaf nodes). Os tipos pai (parent_id = null) retornam property_count: 0 (sem significado — contagem relevante é nos subtipos).

Response (200 OK)

[
  {
    "id": 1,
    "name": "Residencial",
    "slug": "residencial",
    "parent_id": null,
    "property_count": 0,
    "subtypes": [
      {
        "id": 2,
        "name": "Apartamento",
        "slug": "apartamento",
        "parent_id": 1,
        "property_count": 38,
        "subtypes": []
      },
      {
        "id": 3,
        "name": "Casa",
        "slug": "casa",
        "parent_id": 1,
        "property_count": 14,
        "subtypes": []
      },
      {
        "id": 4,
        "name": "Cobertura",
        "slug": "cobertura",
        "parent_id": 1,
        "property_count": 5,
        "subtypes": []
      }
    ]
  },
  {
    "id": 5,
    "name": "Comercial",
    "slug": "comercial",
    "parent_id": null,
    "property_count": 0,
    "subtypes": [
      {
        "id": 6,
        "name": "Sala Comercial",
        "slug": "sala-comercial",
        "parent_id": 5,
        "property_count": 7,
        "subtypes": []
      }
    ]
  }
]

Regras:

  • property_count nos subtypes conta imóveis com is_active = true via properties.subtype_id
  • Tipos pai recebem property_count: 0 (campo presente para consistência de schema, não usado pelo frontend)
  • Ordenação mantida: por PropertyType.id ASC (categorias pai); subtypes herdados via SQLAlchemy relationship

Backward Compatibility

Aspecto Garantia
Clientes existentes que ignoram campos extras Não quebram — campo adicional em JSON é ignorado
Frontend antes da feature 024 property_count?: number (opcional no TypeScript) — não causa erro de tipo
Testes existentes (test_properties.py, test_homepage.py) Não testam payload de catálogo em detalhe; COUNT adicional não altera filtros
Admin panel Não consome esses endpoints; sem impacto