--- id: "RF-SCR-003" title: "Pipeline ETL y Normalizacion" type: "Functional Requirement" epic: "IAI-007" priority: "Alta" status: "Draft" project: "inmobiliaria-analytics" created_date: "2026-01-04" updated_date: "2026-01-04" --- # RF-IA-007-003: Pipeline ETL y Normalizacion --- ## Descripcion El sistema debe procesar los datos raw extraidos de multiples fuentes, normalizarlos a un schema unificado, enriquecerlos con geocoding y cargarlos en la base de datos de propiedades. --- ## Justificacion Cada portal inmobiliario tiene su propia estructura de datos y nomenclatura. Para poder realizar analytics consistentes, los datos deben normalizarse a un schema comun con campos estandarizados. --- ## Requisitos Funcionales ### RF-003.1: Extraccion | ID | Requisito | Prioridad | |----|-----------|-----------| | RF-003.1.1 | El sistema debe parsear HTML a JSON estructurado | Alta | | RF-003.1.2 | El sistema debe extraer todos los campos definidos en el schema | Alta | | RF-003.1.3 | El sistema debe manejar variaciones en estructura HTML | Alta | | RF-003.1.4 | El sistema debe almacenar raw data en storage persistente | Media | ### RF-003.2: Transformacion | ID | Requisito | Prioridad | |----|-----------|-----------| | RF-003.2.1 | El sistema debe normalizar tipos de propiedad a enum unificado | Alta | | RF-003.2.2 | El sistema debe convertir precios a formato numerico estandar | Alta | | RF-003.2.3 | El sistema debe normalizar unidades de superficie (m2) | Alta | | RF-003.2.4 | El sistema debe extraer caracteristicas de texto libre | Media | | RF-003.2.5 | El sistema debe limpiar y estandarizar direcciones | Alta | ### RF-003.3: Enriquecimiento | ID | Requisito | Prioridad | |----|-----------|-----------| | RF-003.3.1 | El sistema debe geocodificar direcciones a lat/lon | Alta | | RF-003.3.2 | El sistema debe calcular precio por m2 | Alta | | RF-003.3.3 | El sistema debe asignar zona/colonia normalizada | Alta | | RF-003.3.4 | El sistema debe detectar duplicados cross-source | Media | ### RF-003.4: Carga | ID | Requisito | Prioridad | |----|-----------|-----------| | RF-003.4.1 | El sistema debe hacer upsert en tabla de propiedades | Alta | | RF-003.4.2 | El sistema debe mantener historial de cambios de precio | Alta | | RF-003.4.3 | El sistema debe marcar propiedades inactivas | Alta | | RF-003.4.4 | El sistema debe emitir eventos de nuevas propiedades | Media | --- ## Schema Normalizado ```yaml Property: # Identificacion id: UUID source: string # inmuebles24, vivanuncios, etc source_id: string # ID original del portal source_url: string # Tipo property_type: enum - house - apartment - land - commercial - office - warehouse transaction_type: enum [sale, rent] # Ubicacion address: string neighborhood: string city: string state: string postal_code: string latitude: decimal longitude: decimal zone_id: UUID (FK) # Caracteristicas bedrooms: integer bathrooms: decimal parking_spaces: integer construction_m2: decimal land_m2: decimal age_years: integer floors: integer # Precio price: decimal currency: string # MXN, USD price_per_m2: decimal (calculado) # Descripcion title: string description: text amenities: string[] images: string[] # Metadata is_active: boolean first_seen_at: timestamp last_seen_at: timestamp price_history: JSONB created_at: timestamp updated_at: timestamp ``` --- ## Mappings por Fuente ### Inmuebles24 ```yaml mappings: property_type: "Casa": house "Departamento": apartment "Terreno": land "Local comercial": commercial "Oficina": office "Bodega": warehouse transaction_type: "Venta": sale "Renta": rent "Venta o Renta": sale # priorizar venta precio: selector: ".price-value" transform: "remove_currency_symbols | to_number" superficie: selector: ".surface-value" transform: "extract_number | assume_m2" ``` --- ## Reglas de Validacion ```yaml validations: precio: min: 10000 # MXN max: 500000000 required: true superficie: min: 10 # m2 max: 100000 required: false coordenadas: latitude_range: [14.5, 32.7] # Mexico longitude_range: [-118.5, -86.7] deduplicacion: strategy: "source_id + source" fallback: "address_normalized + price + type" ``` --- ## Criterios de Aceptacion - [ ] Pipeline procesa 1000 propiedades/hora minimo - [ ] Todos los campos requeridos se mapean correctamente - [ ] Precios se convierten a formato numerico sin errores - [ ] Geocoding tiene 95%+ success rate - [ ] Duplicados se detectan con 98%+ precision - [ ] Historial de precios se mantiene correctamente - [ ] Raw data se almacena para debugging --- ## Dependencias - Cheerio o similar para parsing HTML - Google Maps API para geocoding - PostgreSQL para persistencia - S3/MinIO para raw data storage --- ## Historias de Usuario Relacionadas - US-SCR-003: Normalizacion de datos --- **Autor:** Tech Lead **Fecha:** 2026-01-04