@horizon-integrations/jetimob-crm
Version:
Integração da Imobland Horizon com a Jetimob CRM
1 lines • 322 kB
Source Map (JSON)
{"version":3,"sources":["../src/services/PropertyConverter/convertBaseFields.ts","../src/services/PropertyConverter/convertExtendedFields.ts","../src/services/PropertyConverter/index.ts","../src/services/PropertyDownloader.ts","../src/data/fake-data/apartamentos.json","../src/data/fake-data/casas.json","../src/data/fake-data/comerciais.json","../src/data/fake-data/terrenos.json","../src/data/fake-data/coberturas.json","../src/data/fake-data/index.ts","../src/schemas/horizon-property-schema-by-jetimob.ts","../src/schemas/jetimob-property-schema.zod.ts","../src/schemas/generated/horizon-property-schema-by-jetimob.zod.ts"],"sourcesContent":["import { type JetimobPropertySchema as JetimobImovel } from '../../schemas/jetimob-property-schema.zod'\nimport { type HorizonPropertySchemaByJetimobType as JetimobPropertyV3 } from '../../schemas/generated/horizon-property-schema-by-jetimob.zod'\n\n/**\n * Converte campos do schema base (horizon-property-schema-base.json)\n * Esses são os campos padrão que existem em todos os property models\n */\nexport function convertBaseFields(imovel: JetimobImovel): Partial<JetimobPropertyV3> {\n const result: Partial<JetimobPropertyV3> = {}\n\n // ========== IDENTIFICAÇÃO BÁSICA ==========\n result.reference = imovel.codigo\n if (imovel.titulo_anuncio) result.title = imovel.titulo_anuncio\n if (imovel.observacoes) result.description = imovel.observacoes\n result.updated_at = imovel.updated_at || new Date().toISOString()\n\n // ========== SEO ==========\n if (imovel.titulo_anuncio) result.seo_title = imovel.titulo_anuncio.substring(0, 60)\n if (imovel.meta_description) result.seo_description = imovel.meta_description\n\n // ========== CONFIGURAÇÕES ==========\n result.currency = \"BRL\"\n result.unit_area = (imovel.medida === \"m²\" || imovel.medida === \"m2\") ? \"m2\" : \"m2\"\n result.unit_distance = \"meters\"\n result.map_show_proximity = false\n\n // ========== OPERAÇÃO (discoverOperation) ==========\n if (imovel.contrato) {\n const contratoLower = imovel.contrato.toLowerCase()\n if (contratoLower === \"compra\") {\n result.operacao = [\"venda\"]\n } else if (contratoLower === \"locação\" || contratoLower === \"aluguel\") {\n result.operacao = [\"locacao\"]\n } else if (contratoLower === \"temporada\") {\n result.operacao = [\"temporada\"]\n } else {\n result.operacao = [imovel.contrato as \"venda\" | \"locacao\" | \"temporada\"]\n }\n }\n\n // ========== VALORES MONETÁRIOS COM VISIBILIDADE ==========\n // valor_venda SEMPRE mapear (sem filtro visibilidade)\n if (imovel.valor_venda) {\n const valor = Number(imovel.valor_venda)\n if (!isNaN(valor) && valor > 0) result.valor_venda = valor\n }\n \n // valor_locacao SÓ se valor_locacao_visivel for true\n if (imovel.valor_locacao && imovel.valor_locacao_visivel) {\n const valor = Number(imovel.valor_locacao)\n if (!isNaN(valor) && valor > 0) result.valor_locacao = valor\n }\n \n // valor_temporada SÓ se valor_temporada_visivel for true\n if (imovel.valor_temporada && imovel.valor_temporada_visivel) {\n const valor = Number(imovel.valor_temporada)\n if (!isNaN(valor) && valor > 0) result.valor_diaria = valor\n }\n \n // valor_condominio SÓ se valor_condominio_visivel for true\n if (imovel.valor_condominio && imovel.valor_condominio_visivel) {\n const valor = Number(imovel.valor_condominio)\n if (!isNaN(valor) && valor >= 0) result.valor_condominio = valor\n }\n \n // valor_iptu SÓ se valor_iptu_visivel for true\n if (imovel.valor_iptu && imovel.valor_iptu_visivel) {\n const valor = Number(imovel.valor_iptu)\n if (!isNaN(valor) && valor >= 0) result.valor_iptu = valor\n }\n\n // ========== ÁREAS COM VALIDAÇÃO ==========\n if (imovel.area_total) {\n const area = Number(imovel.area_total)\n if (!isNaN(area) && area > 0) result.area_total = area\n }\n if (imovel.area_privativa) {\n const area = Number(imovel.area_privativa)\n if (!isNaN(area) && area > 0) result.area_privativa = area\n }\n if (imovel.area_util) {\n const area = Number(imovel.area_util)\n if (!isNaN(area) && area > 0) result.area_util = area\n }\n\n // ========== DEPENDÊNCIAS ==========\n if (imovel.dormitorios) result.dormitorios = Number(imovel.dormitorios)\n if (imovel.suites) result.suites = Number(imovel.suites)\n if (imovel.banheiros) result.banheiros = Number(imovel.banheiros)\n if (imovel.garagens) result.vagas_garagem = Number(imovel.garagens)\n\n // ========== TIPO E FINALIDADE ==========\n if (imovel.tipo) result.finalidade = imovel.tipo\n if (imovel.subtipo) result.tipo = imovel.subtipo\n\n // ========== LOCALIZAÇÃO (sempre mapear endereços) ==========\n if (imovel.endereco_cep) {\n // Formatar CEP para 00000-000 (9 caracteres com traço)\n const cepLimpo = imovel.endereco_cep.replace(/\\D/g, '') // Remove não-dígitos\n if (cepLimpo.length === 8) {\n result.endereco_cep = `${cepLimpo.slice(0, 5)}-${cepLimpo.slice(5)}`\n } else {\n result.endereco_cep = imovel.endereco_cep\n }\n }\n if (imovel.endereco_estado) result.endereco_estado = imovel.endereco_estado\n if (imovel.endereco_cidade) result.endereco_cidade = imovel.endereco_cidade\n if (imovel.endereco_bairro) result.endereco_bairro = imovel.endereco_bairro\n if (imovel.endereco_logradouro) result.endereco_logradouro = imovel.endereco_logradouro\n if (imovel.endereco_numero) result.endereco_numero = imovel.endereco_numero\n if (imovel.endereco_complemento) result.endereco_complemento = imovel.endereco_complemento\n if (imovel.endereco_referencia) result.endereco_referencia = imovel.endereco_referencia\n if (imovel.endereco_zona) result.endereco_zona = imovel.endereco_zona\n\n // ========== COORDENADAS COM GEOPOSICIONAMENTO ==========\n const geoValue = imovel.geoposicionamento_visivel ? Number(imovel.geoposicionamento_visivel) : 0\n if (imovel.latitude && imovel.longitude && geoValue !== 0) {\n const lat = Number(imovel.latitude)\n const lng = Number(imovel.longitude)\n if (!isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0) {\n result.latitude = lat\n result.longitude = lng\n }\n }\n\n // ========== CARACTERÍSTICAS BOOLEANAS (SÓ incluir quando true) ==========\n if (String(imovel.mobiliado) === \"1\" || String(imovel.mobiliado) === \"true\") {\n result.mobiliado = true\n }\n\n // ========== COMODIDADES ==========\n if (imovel.imovel_comodidades) {\n const comodidadesArray = String(imovel.imovel_comodidades)\n .split(',')\n .map(c => c.trim())\n .filter(c => c.length > 0)\n if (comodidadesArray.length > 0) {\n result.caracteristicas = comodidadesArray\n }\n }\n\n // ========== DESTAQUE ==========\n if (imovel.destaque && imovel.destaque !== \"Sem destaque\") {\n if (imovel.destaque === \"Destaque\" || imovel.destaque === \"true\" || String(imovel.destaque) === \"true\") {\n result.destaque = true\n }\n }\n\n // ========== CORRETOR ==========\n if (imovel.id_corretor) {\n result.corretor_key = String(imovel.id_corretor)\n }\n\n // ========== CONDOMÍNIO BÁSICO ==========\n if (imovel.id_condominio) {\n result.condominio_key = String(imovel.id_condominio)\n }\n if (imovel.condominio_nome) {\n result.condominio_nome = imovel.condominio_nome\n }\n\n // ========== TAGS ==========\n if (imovel.tags) {\n result.tags = imovel.tags.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0)\n }\n\n // ========== PESSOAS ==========\n if (imovel.numero_pessoas) {\n const pessoas = Number(imovel.numero_pessoas)\n if (!isNaN(pessoas) && pessoas > 0) result.numero_pessoas = pessoas\n }\n\n // ========== MÍDIA (discoverMedias) ==========\n // Imagens\n if (imovel.imagens && imovel.imagens.length > 0) {\n result.images = imovel.imagens.map((imagem, index) => ({\n full: imagem.link,\n md: imagem.link_thumb || imagem.link,\n sm: imagem.link_thumb || imagem.link,\n cover: index === 0 // primeira imagem como cover\n }))\n \n // Definir main_image como a imagem principal (cover)\n const imagemPrincipal = imovel.imagens[0]\n if (imagemPrincipal) {\n result.main_image = {\n full: imagemPrincipal.link,\n md: imagemPrincipal.link_thumb || imagemPrincipal.link,\n sm: imagemPrincipal.link_thumb || imagemPrincipal.link\n }\n }\n }\n\n // Vídeos\n if (imovel.videos && imovel.videos.length > 0) {\n result.videos = imovel.videos.map(url => generateVideo(url))\n }\n\n // Tours virtuais\n if (imovel.tour360 && imovel.tour360.length > 0 ) {\n result.virtual_tours = imovel.tour360.map(tour => ({ embed_url: tour }))\n }\n\n // Documentos (plantas)\n if (imovel.plantas && imovel.plantas.length > 0) {\n result.documents = imovel.plantas.map((plantaUrl, index) => ({\n name: `Planta ${index + 1}`,\n url: plantaUrl\n }))\n }\n\n return result\n}\n\n// Função auxiliar para gerar vídeos (preservada do discoverMedia)\nfunction generateVideo(url: string): any {\n try {\n const parsed = new URL(url)\n const host = parsed.hostname\n\n if (host.includes(\"youtube.com\") || host.includes(\"youtu.be\")) {\n const id = parsed.searchParams.get(\"v\") || parsed.pathname.split(\"/\").pop()\n return {\n provider: \"youtube\",\n id: id || undefined,\n embed_url: `https://www.youtube.com/embed/${id}`,\n }\n }\n\n return {\n embed_url: url,\n }\n } catch (e) {\n return {\n embed_url: url,\n }\n }\n}","import { type JetimobPropertySchema as JetimobImovel } from '../../schemas/jetimob-property-schema.zod'\nimport { type HorizonPropertySchemaByJetimobType } from '../../schemas/generated/horizon-property-schema-by-jetimob.zod'\n\n/**\n * Converte campos específicos do Jetimob (não existem no schema base)\n * Esses são os campos extras que foram adicionados especificamente para o Jetimob\n */\nexport function convertExtendedFields(imovel: JetimobImovel): Partial<HorizonPropertySchemaByJetimobType> {\n const result: Partial<HorizonPropertySchemaByJetimobType> = {}\n\n // ========== VALORES ADICIONAIS JETIMOB ==========\n if (imovel.valor_seguro_incendio) {\n const valor = Number(imovel.valor_seguro_incendio)\n if (!isNaN(valor) && valor >= 0) result.valor_seguro_incendio = valor\n }\n if (imovel.valor_taxa_limpeza) {\n const valor = Number(imovel.valor_taxa_limpeza)\n if (!isNaN(valor) && valor >= 0) result.valor_taxa_limpeza = valor\n }\n\n // ========== ANDAR ==========\n if (imovel.andar) result.andar = Number(imovel.andar)\n\n // ========== CARACTERÍSTICAS BOOLEANAS ESPECÍFICAS ==========\n if (String(imovel.financiavel) === \"1\" || String(imovel.financiavel) === \"true\") {\n result.financiavel = true\n }\n if (String(imovel.exclusividade) === \"true\" || String(imovel.exclusividade) === \"1\") {\n result.exclusividade = true\n }\n if (String(imovel.permuta) === \"true\" || String(imovel.permuta) === \"1\") {\n result.permuta = true\n }\n if (String(imovel.seguro_fianca) === \"true\" || String(imovel.seguro_fianca) === \"1\") {\n result.seguro_fianca = true\n }\n\n // ========== CAMPOS ESPECÍFICOS JETIMOB ==========\n if (imovel.situacao) result.situacao = imovel.situacao\n if (imovel.distancia_mar) result.distancia_mar = Number(imovel.distancia_mar)\n if (imovel.posicao_solar) result.posicao_solar = imovel.posicao_solar\n if (imovel.status) result.status = imovel.status\n if (imovel.posicao) result.posicao = imovel.posicao\n\n // ========== CALENDÁRIO TEMPORADA ==========\n if (imovel.calendario_temporada) {\n result.calendario_temporada = Array.isArray(imovel.calendario_temporada) \n ? imovel.calendario_temporada \n : [imovel.calendario_temporada]\n }\n\n // ========== CONDOMÍNIO ESTENDIDO ==========\n if (imovel.condominio_comodidades) {\n result.condominio_comodidades = Array.isArray(imovel.condominio_comodidades)\n ? imovel.condominio_comodidades\n : [imovel.condominio_comodidades]\n }\n if (imovel.condominio_tipo) result.condominio_tipo = imovel.condominio_tipo\n if (imovel.id_subcondominio) result.subcondominio_id = String(imovel.id_subcondominio)\n if (String(imovel.condominio_fechado) === \"1\" || String(imovel.condominio_fechado) === \"true\") {\n result.condominio_fechado = true\n }\n\n // ========== CONSTRUÇÃO ==========\n if (imovel.entrega_ano) {\n const ano = Number(imovel.entrega_ano)\n if (!isNaN(ano) && ano > 0) result.entrega_ano = ano\n }\n if (imovel.entrega_mes) {\n const mes = Number(imovel.entrega_mes)\n if (!isNaN(mes) && mes > 0 && mes <= 12) result.entrega_mes = mes\n }\n if (imovel.tipo_construcao) result.tipo_construcao = imovel.tipo_construcao\n if (imovel.tipo_piso) result.tipo_piso = imovel.tipo_piso\n\n // ========== PERÍODOS ==========\n if (imovel.periodicidade_iptu) result.periodicidade_iptu = imovel.periodicidade_iptu\n\n // ========== TERRENO ==========\n if (imovel.terreno_frente) {\n const medida = Number(imovel.terreno_frente)\n if (!isNaN(medida) && medida > 0) result.terreno_frente = medida\n }\n if (imovel.terreno_fundos) {\n const medida = Number(imovel.terreno_fundos)\n if (!isNaN(medida) && medida > 0) result.terreno_fundos = medida\n }\n if (imovel.terreno_esquerdo) {\n const medida = Number(imovel.terreno_esquerdo)\n if (!isNaN(medida) && medida > 0) result.terreno_esquerdo = medida\n }\n if (imovel.terreno_direita) {\n const medida = Number(imovel.terreno_direita)\n if (!isNaN(medida) && medida > 0) result.terreno_direita = medida\n }\n if (imovel.terreno_total) {\n const area = Number(imovel.terreno_total)\n if (!isNaN(area) && area > 0) result.terreno_area_total = area\n }\n\n // ========== RURAL ==========\n if (imovel.rural?.rural_area_aravel) {\n const area = Number(imovel.rural.rural_area_aravel)\n if (!isNaN(area) && area > 0) result.rural_area_aravel = area\n }\n if (imovel.rural?.rural_sedes) {\n const sedes = Number(imovel.rural.rural_sedes)\n if (!isNaN(sedes) && sedes > 0) result.rural_sedes = sedes\n }\n if (imovel.rural?.atividade_rural) result.rural_atividade = imovel.rural.atividade_rural\n\n return result\n}","import { type JetimobPropertySchema as JetimobImovel } from '../../schemas/jetimob-property-schema.zod'\nimport { type HorizonPropertySchemaByJetimobType } from '../../schemas/generated/horizon-property-schema-by-jetimob.zod'\nimport { convertBaseFields } from './convertBaseFields'\nimport { convertExtendedFields } from './convertExtendedFields'\n\n/**\n * Converte um imóvel do formato Jetimob para o formato PropertyV3 específico\n * \n * Dividido em duas partes:\n * 1. Base Fields: campos que existem no horizon-property-schema-base.json\n * 2. Extended Fields: campos específicos do Jetimob (não existem no schema base)\n */\nexport function convertJetimobPropertyToHorizon(imovel: JetimobImovel): HorizonPropertySchemaByJetimobType {\n // Converter campos do schema base\n const baseFields = convertBaseFields(imovel)\n \n // Converter campos específicos do Jetimob\n const extendedFields = convertExtendedFields(imovel)\n \n // Combinar os dois resultados\n const result = {\n ...baseFields,\n ...extendedFields\n }\n\n return result as HorizonPropertySchemaByJetimobType\n}\n\n// Re-exportar as funções individuais para uso separado se necessário\nexport { convertBaseFields } from './convertBaseFields'\nexport { convertExtendedFields } from './convertExtendedFields'","import { promises as fs } from \"fs\";\nimport { join } from \"path\";\n\n// Types do PropertyDownloader\nexport interface PropertyDownloaderConfig {\n webserviceKey: string;\n outputDir: string;\n baseUrl?: string;\n}\n\nexport interface DownloadResult {\n totalPages: number;\n totalItems: number;\n downloadedItems: number;\n errors: string[];\n}\n\nexport class PropertyDownloader {\n private webserviceKey: string;\n private baseUrl: string;\n private outputDir: string;\n\n constructor(config: PropertyDownloaderConfig) {\n this.webserviceKey = config.webserviceKey;\n this.baseUrl =\n config.baseUrl ||\n \"https://api.jetimob.com\";\n this.outputDir = config.outputDir;\n }\n\n private async getProperties(\n page: number = 1,\n pageSize: number = 50\n ): Promise<any> {\n const url = `${this.baseUrl}/webservice/${this.webserviceKey}/imoveis?v=4&page=${page}&pageSize=${pageSize}`;\n\n console.log(`🔗 Requisição: ${url}`);\n\n const response = await fetch(url);\n\n if (!response.ok) {\n const errorText =\n await response.text();\n throw new Error(\n `Erro ${response.status}: ${errorText}`\n );\n }\n\n return response.json();\n }\n\n private async ensureOutputDir(): Promise<void> {\n try {\n await fs.access(this.outputDir);\n } catch {\n await fs.mkdir(this.outputDir, {\n recursive: true,\n });\n }\n }\n\n private async savePageData(\n page: number,\n data: any\n ): Promise<boolean> {\n // API retorna um objeto com propriedade 'data' que contém o array\n const properties = data?.data || data;\n\n // Não salvar se os dados estiverem vazios\n if (\n !Array.isArray(properties) ||\n properties.length === 0\n ) {\n console.log(\n ` 📄 Página ${page} vazia, não salvando arquivo`\n );\n return false;\n }\n\n const fileName = `page-${page}.json`;\n const filePath = join(\n this.outputDir,\n fileName\n );\n // Salva apenas o array de propriedades para compatibilidade\n await fs.writeFile(\n filePath,\n JSON.stringify(properties, null, 2),\n \"utf8\"\n );\n return true;\n }\n\n async downloadAll(\n pageSize: number = 100\n ): Promise<DownloadResult> {\n await this.ensureOutputDir();\n\n const errors: string[] = [];\n let totalPages = 0;\n let downloadedItems = 0;\n let currentPage = 1;\n\n console.log(\n `🚀 Iniciando download completo da API...`\n );\n console.log(\n `📄 Tamanho da página: ${pageSize} propriedades`\n );\n\n try {\n while (true) {\n console.log(\n `\\n📄 Baixando página ${currentPage}...`\n );\n\n const response =\n await this.getProperties(\n currentPage,\n pageSize\n );\n const properties =\n response?.data || response;\n\n // Se página vazia, fim do download\n if (\n !Array.isArray(properties) ||\n properties.length === 0\n ) {\n console.log(\n `✅ Página ${currentPage} vazia - download completo!`\n );\n break;\n }\n\n // Salva a página\n const saved =\n await this.savePageData(\n currentPage,\n response\n );\n if (saved) {\n downloadedItems +=\n properties.length;\n console.log(\n `✅ Página ${currentPage}: ${properties.length} propriedades salvas`\n );\n }\n\n // Metadata da API se disponível\n if (response?.totalPages) {\n console.log(\n `📊 Progresso: ${currentPage}/${response.totalPages} páginas`\n );\n }\n\n currentPage++;\n totalPages = currentPage - 1;\n\n // Pausa entre páginas\n await new Promise((resolve) =>\n setTimeout(resolve, 500)\n );\n }\n } catch (error) {\n const errorMsg = `Erro no download: ${\n error instanceof Error\n ? error.message\n : String(error)\n }`;\n errors.push(errorMsg);\n console.error(`❌ ${errorMsg}`);\n }\n\n // Resumo final\n console.log(`\\n📊 RESUMO DO DOWNLOAD:`);\n console.log(\n `📄 Total de páginas: ${totalPages}`\n );\n console.log(\n `✅ Propriedades baixadas: ${downloadedItems}`\n );\n if (errors.length > 0) {\n console.log(\n `❌ Erros: ${errors.length}`\n );\n errors.forEach((err) =>\n console.log(` - ${err}`)\n );\n }\n\n return {\n totalPages,\n totalItems: downloadedItems,\n downloadedItems,\n errors,\n };\n }\n}","[\n {\n \"codigo\": \"FAKE_APARTAMENTOS_001\",\n \"titulo_anuncio\": \"Apartamento Centro - 2 dorm, 2 suítes, 165m², 1 vaga\",\n \"observacoes\": \"Apartamento com vista para o mar em Torres, a praia mais linda do RS.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-01-06 13:26:01\",\n \"data_update\": \"2025-03-03 00:46:23\",\n \"data_atualizacao\": \"2025-03-16 10:42:00\",\n \"updated_at\": \"2025-03-19 08:18:57\",\n \"dormitorios\": 2,\n \"suites\": 2,\n \"banheiros\": 3,\n \"garagens\": 1,\n \"area_total\": 150,\n \"area_privativa\": 165,\n \"andar\": 1,\n \"valor_venda\": 280000,\n \"endereco_bairro\": \"Vila São João\",\n \"endereco_logradouro\": \"Rua Júlio de Castilhos\",\n \"endereco_numero\": \"491\",\n \"endereco_cep\": \"95560-070\",\n \"endereco_complemento\": \"Apto 1\",\n \"latitude\": -29.342936776054497,\n \"longitude\": -49.72035923955464,\n \"imovel_comodidades\": \"Sacada,Próximo à praia,Área de serviço,Churrasqueira,Lavabo\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1565183997392-2f6f122e5912?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1565183997392-2f6f122e5912?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_002\",\n \"titulo_anuncio\": \"Apartamento Centro - 4 dorm, 3 suítes, 165m², 3 vagas\",\n \"observacoes\": \"Unidade moderna próxima ao Centro Histórico e ao Farol de Torres.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-03-10 02:20:33\",\n \"data_update\": \"2025-05-18 22:01:44\",\n \"data_atualizacao\": \"2025-04-13 15:23:31\",\n \"updated_at\": \"2025-01-14 22:31:12\",\n \"dormitorios\": 4,\n \"suites\": 3,\n \"banheiros\": 3,\n \"garagens\": 3,\n \"area_total\": 105,\n \"area_privativa\": 165,\n \"andar\": 10,\n \"valor_venda\": 850000,\n \"endereco_bairro\": \"Vila São João\",\n \"endereco_logradouro\": \"Rua João Neves da Fontoura\",\n \"endereco_numero\": \"882\",\n \"endereco_cep\": \"95560-020\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.326109044782587,\n \"longitude\": -49.72886046595862,\n \"imovel_comodidades\": \"Área gourmet,Área de serviço,Lavabo,Hidromassagem\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"5.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_003\",\n \"titulo_anuncio\": \"Apartamento Centro - 3 dorm, 115m², 3 vagas\",\n \"observacoes\": \"Imóvel com excelente localização e acabamentos de primeira linha.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2025-07-23 02:33:46\",\n \"data_update\": \"2024-06-18 14:20:49\",\n \"data_atualizacao\": \"2025-05-26 22:11:42\",\n \"updated_at\": \"2025-07-18 14:46:17\",\n \"dormitorios\": 3,\n \"suites\": 0,\n \"banheiros\": 3,\n \"garagens\": 3,\n \"area_total\": 45,\n \"area_privativa\": 115,\n \"andar\": 15,\n \"valor_venda\": 850000,\n \"endereco_bairro\": \"Praia Grande\",\n \"endereco_logradouro\": \"Rua Senador Pinheiro Machado\",\n \"endereco_numero\": \"430\",\n \"endereco_cep\": \"95560-060\",\n \"endereco_complemento\": \"Apto 2\",\n \"latitude\": -29.336375878338483,\n \"longitude\": -49.72503985134924,\n \"imovel_comodidades\": \"Ar condicionado,Varanda,Área gourmet,Área de serviço\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=800&q=80\",\n \"titulo\": \"5.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_004\",\n \"titulo_anuncio\": \"Apartamento Centro - 3 dorm, 2 suítes, 140m², 1 vaga\",\n \"observacoes\": \"Imóvel com excelente localização e acabamentos de primeira linha.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2025-01-12 05:21:57\",\n \"data_update\": \"2025-07-10 14:50:25\",\n \"data_atualizacao\": \"2024-10-07 07:40:13\",\n \"updated_at\": \"2025-05-05 10:51:02\",\n \"dormitorios\": 3,\n \"suites\": 2,\n \"banheiros\": 1,\n \"garagens\": 1,\n \"area_total\": 65,\n \"area_privativa\": 140,\n \"andar\": 12,\n \"valor_venda\": 850000,\n \"endereco_bairro\": \"Jardim Ubatuba\",\n \"endereco_logradouro\": \"Rua Senador Pinheiro Machado\",\n \"endereco_numero\": \"427\",\n \"endereco_cep\": \"95560-020\",\n \"endereco_complemento\": \"Apto 6\",\n \"latitude\": -29.339157171441027,\n \"longitude\": -49.72632203630522,\n \"imovel_comodidades\": \"Ar condicionado,Jardim,Garagem coberta,Terraço,Sacada,Próximo à praia\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_005\",\n \"titulo_anuncio\": \"Apartamento Centro - 3 dorm, 3 suítes, 55m², 2 vagas\",\n \"observacoes\": \"Apartamento com sacada, a poucos metros da Praia Grande.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-05-08 10:23:39\",\n \"data_update\": \"2024-09-18 14:42:42\",\n \"data_atualizacao\": \"2024-01-07 03:13:44\",\n \"updated_at\": \"2025-02-09 06:49:29\",\n \"dormitorios\": 3,\n \"suites\": 3,\n \"banheiros\": 4,\n \"garagens\": 2,\n \"area_total\": 180,\n \"area_privativa\": 55,\n \"andar\": 12,\n \"valor_venda\": 180000,\n \"endereco_bairro\": \"Prainha\",\n \"endereco_logradouro\": \"Rua Barão do Rio Branco\",\n \"endereco_numero\": \"526\",\n \"endereco_cep\": \"95560-060\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.33708529462322,\n \"longitude\": -49.73430782637095,\n \"imovel_comodidades\": \"Lareira,Varanda\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_006\",\n \"titulo_anuncio\": \"Apartamento Centro - 4 dorm, 2 suítes, 55m², 3 vagas\",\n \"observacoes\": \"Apartamento com vista para o mar em Torres, a praia mais linda do RS.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2025-06-12 10:45:18\",\n \"data_update\": \"2024-09-07 03:24:40\",\n \"data_atualizacao\": \"2024-12-04 16:01:29\",\n \"updated_at\": \"2024-07-27 13:34:42\",\n \"dormitorios\": 4,\n \"suites\": 2,\n \"banheiros\": 4,\n \"garagens\": 3,\n \"area_total\": 105,\n \"area_privativa\": 55,\n \"andar\": 12,\n \"valor_venda\": 620000,\n \"endereco_bairro\": \"Residencial Quinta da Colina\",\n \"endereco_logradouro\": \"Rua Cristóvão Colombo\",\n \"endereco_numero\": \"52\",\n \"endereco_cep\": \"95560-010\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.3424800569058,\n \"longitude\": -49.71831372337415,\n \"imovel_comodidades\": \"Churrasqueira,Vista para o mar,Garagem coberta,Ar condicionado\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1574362848149-11496d93a7c7?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1574362848149-11496d93a7c7?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1565183997392-2f6f122e5912?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1565183997392-2f6f122e5912?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_007\",\n \"titulo_anuncio\": \"Apartamento Centro - 2 dorm, 3 suítes, 35m², 2 vagas\",\n \"observacoes\": \"Apartamento com sacada, a poucos metros da Praia Grande.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-10-27 12:03:54\",\n \"data_update\": \"2025-03-07 19:18:00\",\n \"data_atualizacao\": \"2024-07-30 07:14:20\",\n \"updated_at\": \"2024-08-20 11:51:48\",\n \"dormitorios\": 2,\n \"suites\": 3,\n \"banheiros\": 3,\n \"garagens\": 2,\n \"area_total\": 180,\n \"area_privativa\": 35,\n \"andar\": 15,\n \"valor_venda\": 180000,\n \"endereco_bairro\": \"Vila Aparecida\",\n \"endereco_logradouro\": \"Avenida Paraguassu\",\n \"endereco_numero\": \"501\",\n \"endereco_cep\": \"95560-001\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.32939553045724,\n \"longitude\": -49.72914491690439,\n \"imovel_comodidades\": \"Hidromassagem,Garagem coberta,Área de serviço\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=800&q=80\",\n \"titulo\": \"5.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_008\",\n \"titulo_anuncio\": \"Apartamento Centro - 4 dorm, 3 suítes, 75m², 3 vagas\",\n \"observacoes\": \"Apartamento com sacada, a poucos metros da Praia Grande.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-08-09 15:10:05\",\n \"data_update\": \"2024-11-13 10:58:00\",\n \"data_atualizacao\": \"2024-06-27 21:22:25\",\n \"updated_at\": \"2024-04-26 14:12:51\",\n \"dormitorios\": 4,\n \"suites\": 3,\n \"banheiros\": 4,\n \"garagens\": 3,\n \"area_total\": 105,\n \"area_privativa\": 75,\n \"andar\": 12,\n \"valor_venda\": 180000,\n \"endereco_bairro\": \"Prainha\",\n \"endereco_logradouro\": \"Avenida Beira Mar\",\n \"endereco_numero\": \"573\",\n \"endereco_cep\": \"95560-010\",\n \"endereco_complemento\": \"Apto 13\",\n \"latitude\": -29.33017236005315,\n \"longitude\": -49.7229083304007,\n \"imovel_comodidades\": \"Churrasqueira,Área gourmet,Terraço,Vista para o mar\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_009\",\n \"titulo_anuncio\": \"Apartamento Centro - 4 dorm, 95m², 1 vaga\",\n \"observacoes\": \"Imóvel com excelente localização e acabamentos de primeira linha.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2025-02-11 23:09:26\",\n \"data_update\": \"2024-06-21 03:00:28\",\n \"data_atualizacao\": \"2024-02-08 04:56:29\",\n \"updated_at\": \"2024-07-04 12:24:44\",\n \"dormitorios\": 4,\n \"suites\": 0,\n \"banheiros\": 4,\n \"garagens\": 1,\n \"area_total\": 150,\n \"area_privativa\": 95,\n \"andar\": 8,\n \"valor_venda\": 280000,\n \"endereco_bairro\": \"Vila São João\",\n \"endereco_logradouro\": \"Rua Benjamin Constant\",\n \"endereco_numero\": \"967\",\n \"endereco_cep\": \"95560-020\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.338789575624848,\n \"longitude\": -49.736857533133374,\n \"imovel_comodidades\": \"Garagem coberta,Ar condicionado,Lareira,Churrasqueira\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_010\",\n \"titulo_anuncio\": \"Apartamento Centro - 3 dorm, 55m², 2 vagas\",\n \"observacoes\": \"Imóvel com excelente localização e acabamentos de primeira linha.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\n \"exclusividade\": false,\n \"medida\": \"m²\",\n \"endereco_estado\": \"Rio Grande do Sul\",\n \"endereco_cidade\": \"Torres\",\n \"data_cadastro\": \"2024-03-07 04:52:16\",\n \"data_update\": \"2025-01-02 06:07:47\",\n \"data_atualizacao\": \"2024-10-27 06:54:47\",\n \"updated_at\": \"2024-12-01 12:54:25\",\n \"dormitorios\": 3,\n \"suites\": 0,\n \"banheiros\": 2,\n \"garagens\": 2,\n \"area_total\": 150,\n \"area_privativa\": 55,\n \"andar\": 1,\n \"valor_venda\": 620000,\n \"endereco_bairro\": \"Parque Estadual\",\n \"endereco_logradouro\": \"Rua Benjamin Constant\",\n \"endereco_numero\": \"548\",\n \"endereco_cep\": \"95560-001\",\n \"endereco_complemento\": \"\",\n \"latitude\": -29.33153364697405,\n \"longitude\": -49.73064631945697,\n \"imovel_comodidades\": \"Hidromassagem,Terraço,Varanda\",\n \"imagens\": [\n {\n \"link\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800&q=80\",\n \"titulo\": \"1.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800&q=80\",\n \"titulo\": \"2.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=800&q=80\",\n \"titulo\": \"3.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1560185127-6ed189bf02f4?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80\",\n \"titulo\": \"4.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=400&q=80\"\n },\n {\n \"link\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=800&q=80\",\n \"titulo\": \"5.jpg\",\n \"link_thumb\": \"https://images.unsplash.com/photo-1581858726788-75bc0f6a952d?w=400&q=80\"\n }\n ],\n \"videos\": [],\n \"tour360\": [],\n \"plantas\": [],\n \"valor_venda_visivel\": true,\n \"valor_locacao_visivel\": false,\n \"valor_temporada_visivel\": false,\n \"valor_condominio_visivel\": false,\n \"valor_iptu_visivel\": false,\n \"endereco_estado_visivel\": true,\n \"endereco_cidade_visivel\": false,\n \"endereco_bairro_visivel\": false,\n \"endereco_logradouro_visivel\": false,\n \"endereco_numero_visivel\": false,\n \"endereco_complemento_visivel\": false\n },\n {\n \"codigo\": \"FAKE_APARTAMENTOS_011\",\n \"titulo_anuncio\": \"Apartamento Centro - 1 dorm, 2 suítes, 35m², 1 vaga\",\n \"observacoes\": \"Apartamento com vista para o mar em Torres, a praia mais linda do RS.\",\n \"contrato\": \"Compra\",\n \"tipo\": \"Residencial\",\n \"subtipo\": \"Apartamento\",\n \"mobiliado\": 0,\n \"financiavel\": 0,\