# Modelo de dados — referência conceitual ## 1. Aviso Este documento descreve o modelo lógico desejável para análise. Ele **não afirma** que o banco SQLite atual possui essas tabelas ou colunas. O esquema real deve ser inspecionado antes de qualquer consulta. Não migre o banco original para este modelo sem autorização. --- ## 2. Entidades fundamentais O projeto deve distinguir cinco conceitos: 1. **fonte**: site, portal, corretor ou canal; 2. **anúncio**: publicação identificável em uma fonte; 3. **observação**: estado do anúncio em uma data de coleta; 4. **imóvel físico**: unidade residencial que pode aparecer em vários anúncios; 5. **execução de coleta**: processo técnico que obteve os dados. Essa separação é essencial para séries históricas e deduplicação. --- ## 3. Fonte Entidade conceitual: `source` Campos desejáveis: - `source_id` - `name` - `base_url` - `source_type` - `active` - `notes` - `created_at` Não usar domínio ou nome de corretor como identificador único sem normalização. --- ## 4. Execução de coleta Entidade conceitual: `scrape_run` Campos desejáveis: - `run_id` - `source_id` - `started_at` - `finished_at` - `status` - `pages_requested` - `pages_succeeded` - `pages_failed` - `items_seen` - `items_inserted` - `items_updated` - `http_status_summary` - `scraper_version` - `configuration_hash` - `error_summary` Serve para identificar: - períodos sem coleta; - mudanças de cobertura; - falhas; - alterações de código; - diferenças entre ausência real e ausência causada por erro. --- ## 5. Anúncio Entidade conceitual: `listing` Representa a identidade do anúncio, não cada coleta. Campos desejáveis: - `listing_id` - `source_id` - `source_listing_id` - `canonical_url` - `first_seen_at` - `last_seen_at` - `last_successful_seen_at` - `status` - `seller_type` - `seller_name_normalized` - `broker_registration` - `property_candidate_id` - `created_at` - `updated_at` Chave natural potencial: ```text (source_id, source_listing_id) ``` A URL não deve ser a única chave, pois pode mudar. --- ## 6. Observação histórica Entidade conceitual: `listing_snapshot` Representa o conteúdo observado em uma execução. Campos desejáveis: - `snapshot_id` - `listing_id` - `run_id` - `observed_at` - `title` - `description` - `price` - `condominium_fee` - `property_tax` - `area_private` - `area_useful` - `area_built` - `area_total` - `bedrooms` - `suites` - `bathrooms` - `parking_spaces` - `floor` - `elevator` - `furnished` - `property_type` - `address_raw` - `neighborhood_raw` - `latitude` - `longitude` - `image_count` - `status_raw` - `payload_hash` - `raw_payload_reference` Não sobrescrever o histórico quando um anúncio muda. Se os dados atuais usam uma única linha mutável por anúncio, documentar essa limitação. --- ## 7. Imóvel físico candidato Entidade conceitual: `property_candidate` Representa uma hipótese de que anúncios diferentes descrevem o mesmo imóvel. Campos desejáveis: - `property_candidate_id` - `canonical_region` - `canonical_address` - `canonical_unit` - `property_type` - `original_floor_plan` - `dedup_confidence` - `dedup_method` - `review_status` - `created_at` - `updated_at` Não tratar correspondência probabilística como certeza. Estados sugeridos: - `unreviewed` - `probable` - `confirmed` - `rejected` - `ambiguous` --- ## 8. Endereço e localização Entidade conceitual: `location` Campos desejáveis: - `location_id` - `region` - `administrative_region` - `neighborhood` - `superquadra` - `quadra` - `block` - `qc` - `street` - `lot` - `unit` - `postal_code` - `latitude` - `longitude` - `geocode_precision` - `geocode_source` No Distrito Federal, o endereço deve permitir estruturas como: - SHCES; - quadra; - bloco; - superquadra; - conjunto; - lote; - QC; - condomínio; - unidade. Não forçar todos os endereços a um modelo de rua e número. --- ## 9. Mídia Entidade conceitual: `listing_media` Campos desejáveis: - `media_id` - `snapshot_id` - `media_url` - `media_type` - `position` - `content_hash` - `perceptual_hash` - `width` - `height` - `download_status` Hashes perceptuais de imagens podem ajudar na deduplicação, mas não devem decidir sozinhos. --- ## 10. Histórico de preço O histórico pode ser derivado de `listing_snapshot`. View conceitual: ```sql SELECT listing_id, observed_at, price, price - LAG(price) OVER ( PARTITION BY listing_id ORDER BY observed_at ) AS absolute_change FROM listing_snapshot; ``` Regras: - ignorar repetições idênticas; - registrar aumentos e reduções; - não interpretar ausência como venda; - identificar alterações simultâneas de área ou tipologia; - detectar preços promocionais artificiais; - separar moeda e unidades. --- ## 11. Deduplicação ### 11.1 Sinais fortes - mesmo identificador na fonte; - mesmo endereço e unidade; - mesmo conjunto de imagens; - mesmo telefone ou corretor com descrição muito semelhante; - mesma planta, metragem e características; - coordenadas muito próximas; - texto quase idêntico. ### 11.2 Sinais moderados - mesma quadra e bloco; - mesmo preço; - mesma área; - mesmos quartos e vagas; - datas próximas; - imagens parcialmente coincidentes. ### 11.3 Sinais fracos - mesmo bairro; - título genérico; - preço arredondado; - número de quartos isolado. ### 11.4 Regras - manter o anúncio original; - criar relacionamento de duplicidade; - registrar método e confiança; - permitir revisão manual; - não fundir registros de forma irreversível; - não usar apenas texto normalizado; - evitar que atualizações do mesmo anúncio sejam contadas como imóveis novos. --- ## 12. Normalização ### Preço - armazenar como número inteiro em centavos ou valor monetário consistente; - preservar valor bruto; - registrar moeda; - detectar preço por mês confundido com preço total; - detectar valores incompletos. ### Área Manter campos separados: - privativa; - útil; - construída; - total; - terreno. Nunca preencher uma área com outra apenas para completar dados. ### Quartos Separar: - quartos; - suítes; - dependência; - escritório; - quarto reversível; - tipologia original; - tipologia anunciada. ### Localização Preservar: - texto bruto; - versão normalizada; - componentes extraídos; - confiança da extração. ### Datas Usar ISO 8601 e timezone explícito quando relevante. --- ## 13. Qualidade dos dados Criar métricas por fonte, período e região: - percentual sem preço; - percentual sem área; - percentual sem localização; - percentual com preço por m² calculável; - duplicidade estimada; - taxa de mudança de identificador; - cobertura diária; - falhas de coleta; - distribuições implausíveis; - inconsistência entre título e campos; - divergência entre snapshots. --- ## 14. Inspeção inicial do SQLite Consultas somente leitura úteis: ### Tabelas e views ```sql SELECT type, name, tbl_name, sql FROM sqlite_master ORDER BY type, name; ``` ### Contagem aproximada de tabelas Gerar consultas após listar os nomes. Não concatenar nomes externos sem validação. ### Colunas ```sql PRAGMA table_info('nome_da_tabela'); ``` ### Chaves estrangeiras ```sql PRAGMA foreign_key_list('nome_da_tabela'); ``` ### Índices ```sql PRAGMA index_list('nome_da_tabela'); ``` ### Integridade ```sql PRAGMA quick_check; ``` `quick_check` é somente leitura, mas pode ser custoso em bancos grandes. Executar quando apropriado. --- ## 15. Camada derivada recomendada Sem alterar o banco original, criar: ```text data/derived/ ├── listings_clean.parquet ├── snapshots_clean.parquet ├── property_candidates.parquet ├── price_history.parquet ├── locations_normalized.parquet └── quality_metrics.parquet ``` Ou um SQLite derivado: ```text data/derived/analytics.sqlite ``` Toda derivação deve registrar: - data; - versão do código; - fonte; - filtros; - hash ou identificação do banco de origem; - contagem de entrada e saída. --- ## 16. Dicionário do esquema real Após inspecionar o banco, produzir: ```text docs/ACTUAL_SCHEMA.md ``` Esse arquivo deve conter: - diagrama das tabelas; - descrição de cada coluna; - chaves; - índices; - cardinalidades; - exemplos pequenos; - problemas conhecidos; - correspondência com este modelo conceitual; - decisões de interpretação. Não alterar `DATA_MODEL.md` para simplesmente espelhar um esquema ruim. Manter separação entre modelo conceitual e implementação real.