{"version":3,"sources":["../src/manifest.ts","../src/spec.ts","../package.json","../src/streams/JetimobPropertyStream.ts","../src/services/PropertyConverter/index.ts","../src/schemas/jetimob-property-schema.zod.ts","../src/services/PropertyConverter/convertBaseFields.ts","../src/services/PropertyConverter/convertExtendedFields.ts","../src/source.ts","../src/services/PropertyDownloader.ts","../src/schemas/horizon-property-schema-by-jetimob.ts","../src/schemas/horizon-property-schema-by-jetimob.zod.ts"],"sourcesContent":["import { type SourceManifest, SyncMode } from \"@horizon-js/integrations-core\"\nimport type { JetimobCredentials } from \"./types\"\nimport { jetimobSpec } from \"./spec\"\nimport pkg from \"../package.json\"\n\n/**\n * Manifest declarativo do JetimobSource — cartão de identidade completo.\n *\n * Consumer/IA lê daqui pra entender 100% do adapter sem ler código:\n * capabilities da API, issues conhecidos, streams oferecidos.\n *\n * @see {@link https://api.jetimob.com | API Jetimob}\n */\nexport const jetimobManifest: SourceManifest<JetimobCredentials> = {\n  metadata: {\n    name: \"jetimob\",\n    displayName: \"Jetimob\",\n    type: \"crm\",\n    vendor: {\n      company: \"Jetimob\",\n      website: \"https://jetimob.com\",\n      docsUrl: \"https://api.jetimob.com\",\n    },\n    supportTier: \"community\",\n    adapterVersion: pkg.version,\n  },\n\n  spec: jetimobSpec,\n\n  capabilities: {\n    // API v4 pagina de verdade — ?page=&pageSize=, resposta traz totalPages.\n    pagination: true,\n    // ?start/&end (Unix timestamp), ?codigos, ?id — todos testados e funcionando.\n    filters: true,\n    // Cada imóvel tem data_update / updated_at — melhor que SI9 (que não tem).\n    nativeTimestamp: true,\n    // ?start={unix} filtra por data de atualização server-side. Testado: funciona.\n    incrementalByTimestamp: true,\n    // Busca individual via ?id={id_imovel} (ou ?codigos={codigo}).\n    individualFetch: true,\n    // /imoveis-ativos devolve todos os id_imovel ativos numa tacada (~0.3s, ~9KB).\n    lightweightListing: true,\n    webhooks: false,\n    rateLimit: null,\n    customFields: false,\n    writes: {\n      // API de leads existe (par chave-pública/privada) — writer ainda não implementado.\n      sendLead: false,\n      createProperty: false,\n      updateProperty: false,\n      deleteProperty: false,\n    },\n    softDelete: { enabled: false },\n  },\n\n  streams: [\n    {\n      name: \"properties\",\n      displayName: \"Imóveis\",\n      resourceType: \"property\",\n      supportedSyncModes: [SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL],\n      cursorField: \"source_updated_at\",\n      primaryKey: [\"reference\"],\n      hasListing: true,\n      hasIndividualFetch: true,\n    },\n  ],\n\n  writers: [],\n\n  knownIssues: [\n    {\n      id: \"JET-001\",\n      severity: \"medium\",\n      summary:\n        \"Doc interna antiga afirmava que GET /imoveis retorna array direto — na verdade retorna envelope { total, page, pageSize, totalPages, data: [...] }\",\n      workaround:\n        \"JetimobPropertyStream.parseResponse() lê o envelope `data`. Doc API_JETIMOB.md corrigida com base na doc oficial (docs.jetimob.com).\",\n      category: \"documentation\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-002\",\n      severity: \"low\",\n      summary:\n        \"/imoveis-ativos e /imoveis usam identificadores diferentes: /imoveis-ativos devolve `id_imovel`; ?codigos= filtra por `codigo` (que NÃO é o id). ?id= filtra por `id_imovel`.\",\n      workaround:\n        \"getListing() usa /imoveis-ativos → ListingEntry.ref = id_imovel. fetchByRef() tenta ?id= primeiro e cai pra ?codigos= como fallback, aceitando os dois. O converter expõe `id_imovel` como campo extra pra correlação (reference continua sendo o `codigo`).\",\n      category: \"documentation\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-003\",\n      severity: \"low\",\n      summary:\n        \"Medidas de terreno (terreno_total, terreno_frente, etc.) às vezes vêm como string em vez de number\",\n      workaround:\n        \"Schema raw (jetimob-property-schema.zod.ts) aceita string|number nesses campos; o conversor faz Number().\",\n      category: \"api_bug\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-004\",\n      severity: \"low\",\n      summary:\n        \"API retorna null (não undefined) em praticamente todos os campos opcionais\",\n      workaround:\n        \"Schema raw usa .nullish() em todos os campos opcionais (aceita null | undefined).\",\n      category: \"api_bug\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-005\",\n      severity: \"low\",\n      summary:\n        \"/imoveis não tem parâmetro de seleção de campos (testado: fields, campos, field, select, only — todos ignorados). Toda resposta de /imoveis traz os ~96 campos completos (~9.5KB por imóvel).\",\n      workaround:\n        \"Pra listagem leve usar /imoveis-ativos (só id_imovel). Pra delta eficiente usar ?start={unix} (incremental server-side). Não há como pedir menos campos do /imoveis.\",\n      category: \"missing_feature\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-006\",\n      severity: \"low\",\n      summary:\n        \"API Jetimob devolve 502 Bad Gateway transiente esporádico (nginx). Em paginação de muitas páginas, um 502 isolado derrubaria o sync inteiro.\",\n      workaround:\n        \"JetimobPropertyStream usa retryOptions (httpRetryPolicy, 4 tentativas, backoff exponencial). 5xx/429/timeout são re-tentados automaticamente.\",\n      category: \"performance\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n    },\n    {\n      id: \"JET-007\",\n      severity: \"high\",\n      summary:\n        \"`generateApproximateCoords` usava Math.random() → o campo geo_aproximado mudava a cada conversão → sync_hash instável → o delta re-upsertava ~60% dos imóveis (os com geoposicionamento_visivel=2) em TODO sync.\",\n      workaround:\n        \"Corrigido em 3.1.0: o offset agora é determinístico (FNV-1a hash do codigo/id do imóvel). Mesmo imóvel → mesmo geo_aproximado → sync_hash estável.\",\n      category: \"breaking_change\",\n      reportedToVendor: false,\n      discoveredAt: \"2026-05-14\",\n      resolvedAt: \"2026-05-14\",\n    },\n  ],\n\n  client: {\n    packageName: \"@horizon-integrations/jetimob-crm-client\",\n    className: \"JetimobClient\",\n    apiVersion: \"v1\",\n    endpoints: {\n      properties: \"/api/providers/jetimob/v1/properties\",\n      \"properties.index\": \"/api/providers/jetimob/v1/properties/index\",\n      \"properties.byRef\": \"/api/providers/jetimob/v1/properties/{ref}\",\n    },\n  },\n}\n","import type { SourceSpec } from \"@horizon-js/integrations-core\"\nimport type { JetimobCredentials } from \"./types\"\n\n/**\n * Spec da configuração do JetimobSource — declara o shape das credenciais\n * aceitas. JSON Schema draft-07, inspirado no `spec.json` do Airbyte.\n *\n * Usado pelo hub (UI de setup) e pela validação em runtime.\n */\nexport const jetimobSpec: SourceSpec<JetimobCredentials> = {\n  name: \"jetimob\",\n  title: \"Jetimob\",\n  documentationUrl: \"https://api.jetimob.com\",\n  configSchema: {\n    type: \"object\",\n    required: [\"webserviceKey\"],\n    properties: {\n      webserviceKey: {\n        type: \"string\",\n        title: \"Webservice Key\",\n        description:\n          \"Chave webservice da conta Jetimob. Vai no path da URL (/webservice/{key}/imoveis). Obtida no painel Jetimob da imobiliária.\",\n        airbyteSecret: true,\n      },\n    },\n  },\n}\n","{\n  \"name\": \"@horizon-integrations/jetimob-crm\",\n  \"version\": \"3.1.4\",\n  \"description\": \"Adapter de integração com o CRM Jetimob — padrão Airbyte (@horizon-js/integrations-core)\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.mjs\",\n  \"types\": \"dist/index.d.ts\",\n  \"files\": [\n    \"dist\",\n    \"docs\",\n    \"examples\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsup\",\n    \"dev\": \"tsup --watch\",\n    \"test\": \"vitest\",\n    \"test:coverage\": \"vitest --coverage\",\n    \"typecheck\": \"tsc --noEmit\"\n  },\n  \"keywords\": [\n    \"imobiliario\",\n    \"jetimob\",\n    \"crm\",\n    \"integration\",\n    \"airbyte\",\n    \"converter\",\n    \"horizon\"\n  ],\n  \"author\": \"Horizon Modules\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@horizon-js/integrations-core\": \"^0.5.1\",\n    \"@horizon-js/property-domain-schema\": \"^3.17.0\",\n    \"zod\": \"^3.25.67\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"tsup\": \"^8.0.0\",\n    \"tsx\": \"^4.0.0\",\n    \"typescript\": \"^5.0.0\",\n    \"vitest\": \"^1.0.0\"\n  },\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/index.d.ts\",\n      \"import\": \"./dist/index.mjs\",\n      \"require\": \"./dist/index.js\",\n      \"default\": \"./dist/index.js\"\n    }\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/imobland/horizon-integrations.git\",\n    \"directory\": \"horizon-integrations/jetimob\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n","import {\n  HttpStream,\n  SyncMode,\n  SyncError,\n  fetchWithTimeout,\n  retry,\n  httpRetryPolicy,\n  type RetryOptions,\n  type IncrementalStream,\n  type SyncState,\n  type ListingEntry,\n} from \"@horizon-js/integrations-core\"\nimport type { HorizonPropertySchemaByJetimobType } from \"../schemas/horizon-property-schema-by-jetimob.zod\"\nimport type { JetimobCredentials } from \"../types\"\nimport { convertJetimobPropertyToHorizon } from \"../services/PropertyConverter\"\n\nconst DEFAULT_BASE_URL = \"https://api.jetimob.com\"\nconst DEFAULT_PAGE_SIZE = 200\n\n/** Envelope da resposta da API Jetimob v4 (JET-001). */\ninterface JetimobEnvelope {\n  total?: number\n  page?: number\n  pageSize?: number\n  totalPages?: number\n  data?: unknown\n}\n\nexport interface JetimobPropertyStreamOptions {\n  /** URL base da API. Default: `https://api.jetimob.com`. */\n  readonly baseUrl?: string\n  /** Timeout por request HTTP em ms. Default: `30_000`. */\n  readonly requestTimeoutMs?: number\n  /** Tamanho de página pro endpoint /imoveis. Default: `200`. */\n  readonly pageSize?: number\n}\n\n/**\n * Stream de imóveis da Jetimob.\n *\n * Estende `HttpStream<T>` do `@horizon-js/integrations-core` — a API Jetimob v4\n * pagina de verdade (`?page=&pageSize=`, resposta traz `totalPages`), então o\n * loop de paginação automático do `HttpStream` se aplica.\n *\n * ## A API Jetimob — o que foi testado e confirmado\n *\n * - **`/imoveis`** — endpoint pesado: cada imóvel traz ~96 campos (~9.5KB).\n *   **Não tem** parâmetro de seleção de campos (`fields`/`campos`/etc — JET-005).\n * - **`/imoveis-ativos`** — endpoint LEVE: devolve só os `id_imovel` ativos\n *   numa tacada (~0.3s, ~9KB pros 1000+ imóveis). `getListing()` usa este.\n * - **`?start={unix}`** — filtra `/imoveis` por data de atualização server-side.\n *   `readRecords(INCREMENTAL)` usa este → traz só o delta, sem baixar tudo.\n * - **`?id=` vs `?codigos=`** — `id` filtra por `id_imovel`; `codigos` filtra\n *   por `codigo` (são diferentes — JET-002). `fetchByRef` aceita ambos.\n *\n * ## Peculiaridades de implementação (ver `jetimobManifest.knownIssues`)\n *\n * - **Auth no PATH**: a `webserviceKey` vai embutida na URL\n *   (`/webservice/{key}/imoveis`), não em header nem query — por isso entra no\n *   `urlBase`, e não há `AuthStrategy` dedicada.\n * - **Envelope `{ data }`** (JET-001): `parseResponse` extrai `body.data`.\n * - **`readRecords` defensivo**: o `readRecords` default do `HttpStream` não\n *   trata erro de conversão — um record inválido derrubaria o batch. Aqui é\n *   sobrescrito pra pular records que falham validação Zod (loga warning),\n *   na filosofia Airbyte (bad record ≠ falha de sync).\n * - **Retry** (JET-006): a API devolve 502 transiente; `retryOptions` re-tenta.\n */\nexport class JetimobPropertyStream\n  extends HttpStream<HorizonPropertySchemaByJetimobType>\n  implements IncrementalStream<HorizonPropertySchemaByJetimobType>\n{\n  readonly name = \"properties\"\n  readonly supportedSyncModes = [SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL]\n  readonly cursorField = \"source_updated_at\"\n  readonly primaryKey = [\"reference\"]\n  override readonly requestTimeoutMs: number\n\n  /**\n   * Retry com backoff exponencial pra erros transientes (5xx/429/timeout).\n   * A API Jetimob devolve 502 Bad Gateway esporádico (JET-006). `HttpStream.doRequest`\n   * aplica este policy automaticamente; `getListing`/`fetchByRef`/`probe` aplicam via `retry()`.\n   */\n  override readonly retryOptions: RetryOptions\n\n  private readonly webserviceKey: string\n  private readonly base: string\n  private readonly pageSize: number\n\n  constructor(\n    credentials: JetimobCredentials,\n    options: JetimobPropertyStreamOptions = {},\n  ) {\n    super()\n    this.webserviceKey = credentials.webserviceKey\n    this.base = options.baseUrl ?? DEFAULT_BASE_URL\n    this.requestTimeoutMs = options.requestTimeoutMs ?? 30_000\n    this.pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE\n    this.retryOptions = httpRetryPolicy({ maxAttempts: 4 })\n  }\n\n  // ========================================\n  // HOOKS DO HttpStream\n  // ========================================\n\n  /** A `webserviceKey` é a auth — vai no path da URL base. */\n  get urlBase(): string {\n    return `${this.base}/webservice/${this.webserviceKey}/`\n  }\n\n  path(): string {\n    return \"imoveis\"\n  }\n\n  override requestParams(context: {\n    state?: SyncState\n    nextPageToken?: unknown\n  }): Record<string, string> {\n    const page = context.nextPageToken != null ? Number(context.nextPageToken) : 1\n    const params: Record<string, string> = {\n      v: \"4\",\n      page: String(page),\n      pageSize: String(this.pageSize),\n    }\n    // INCREMENTAL: ?start={unix} filtra por data de atualização server-side.\n    // Testado contra a API real — devolve só o delta. Bem mais leve que baixar tudo.\n    const cursor = context.state?.cursor\n    if (cursor != null) {\n      const unix = isoToUnix(String(cursor))\n      if (unix != null) params.start = String(unix)\n    }\n    return params\n  }\n\n  /** API v4 retorna `{ total, page, pageSize, totalPages, data: [...] }` (JET-001). */\n  parseResponse(body: unknown): unknown[] {\n    if (Array.isArray(body)) return body\n    const env = (body ?? {}) as JetimobEnvelope\n    return Array.isArray(env.data) ? env.data : []\n  }\n\n  /** Próxima página via metadados do envelope. `undefined` encerra o loop. */\n  nextPageToken(response: {\n    body: unknown\n    headers: Record<string, string>\n    status: number\n  }): unknown {\n    const env = (response.body ?? {}) as JetimobEnvelope\n    if (typeof env.page === \"number\" && typeof env.totalPages === \"number\") {\n      return env.page < env.totalPages ? env.page + 1 : undefined\n    }\n    return undefined\n  }\n\n  override convertRecord(raw: unknown): HorizonPropertySchemaByJetimobType {\n    return convertJetimobPropertyToHorizon(raw)\n  }\n\n  getJsonSchema(): Record<string, unknown> {\n    // Shape mínimo descritivo — o schema completo está em\n    // horizon-property-schema-by-jetimob.zod.ts (validação real é via Zod).\n    return {\n      type: \"object\",\n      required: [\"reference\", \"source_key\", \"sync_hash\"],\n      properties: {\n        reference: { type: \"string\" },\n        source_key: { type: \"string\" },\n        source_updated_at: { type: [\"string\", \"null\"] },\n        sync_hash: { type: \"string\" },\n      },\n    }\n  }\n\n  /** Mapeia status HTTP da Jetimob pros FailureType corretos. */\n  protected override async onHttpError(response: Response): Promise<Error> {\n    return this.buildHttpError(response, \"request\")\n  }\n\n  // ========================================\n  // iterateRaw — paginação automática (fonte única de verdade)\n  // ========================================\n\n  /**\n   * Itera os imóveis **crus** (sem conversão) página por página, seguindo a\n   * paginação automática do `HttpStream`. Base de `readRecords` e `fetchRaw`.\n   *\n   * Quando `state` é passado (INCREMENTAL), `requestParams` injeta `?start={unix}`\n   * e a própria API devolve só o delta — a paginação fica curta.\n   */\n  private async *iterateRaw(\n    state?: SyncState,\n  ): AsyncGenerator<unknown, void, undefined> {\n    let nextPageToken: unknown = undefined\n    do {\n      const url = this.buildUrl({ state, nextPageToken })\n      const init = this.buildRequestInit({ state, nextPageToken })\n      const { body, headers, status } = await this.doRequest(url, init)\n\n      for (const raw of this.parseResponse(body)) {\n        yield raw\n      }\n\n      nextPageToken = this.nextPageToken({ body, headers, status })\n    } while (nextPageToken !== undefined)\n  }\n\n  /**\n   * Retorna todos os imóveis **crus** (array, sem conversão). Útil pra\n   * profiling, debug, ou pra consumers que querem converter em lote com\n   * `parseResponseDefensive` do core. Espelha `Si9PropertyStream.fetchRaw()`.\n   */\n  async fetchRaw(): Promise<unknown[]> {\n    const all: unknown[] = []\n    for await (const raw of this.iterateRaw()) all.push(raw)\n    return all\n  }\n\n  // ========================================\n  // readRecords — DEFENSIVO + INCREMENTAL server-side via ?start\n  // ========================================\n\n  override async *readRecords(\n    syncMode: SyncMode,\n    state?: SyncState,\n  ): AsyncGenerator<HorizonPropertySchemaByJetimobType, void, undefined> {\n    const incremental = syncMode === SyncMode.INCREMENTAL\n    const cursor = incremental ? state?.cursor ?? undefined : undefined\n\n    // INCREMENTAL: passa o state adiante → requestParams injeta ?start={unix}.\n    // A API filtra server-side; aqui só convertemos o delta que já veio enxuto.\n    for await (const raw of this.iterateRaw(incremental ? state : undefined)) {\n      let record: HorizonPropertySchemaByJetimobType\n      try {\n        record = this.convertRecord(raw)\n      } catch (err) {\n        // Record inválido NÃO derruba o batch — loga e pula (filosofia Airbyte).\n        const msg = err instanceof Error ? err.message : String(err)\n        const codigo = (raw as { codigo?: unknown })?.codigo\n        console.warn(\n          `[JetimobPropertyStream] skipped record codigo=${String(codigo ?? \"?\")}: ${msg}`,\n        )\n        continue\n      }\n\n      // Cinto de segurança: ?start já filtrou server-side, mas a API é inclusiva\n      // no boundary — descarta o record exatamente igual ao cursor.\n      if (\n        cursor &&\n        record.source_updated_at &&\n        String(record.source_updated_at) <= String(cursor)\n      ) {\n        continue\n      }\n\n      yield record\n    }\n  }\n\n  /**\n   * Avança o cursor incremental a partir de um record lido.\n   * Cursor = maior `source_updated_at` visto.\n   */\n  getUpdatedState(\n    currentState: SyncState,\n    record: HorizonPropertySchemaByJetimobType,\n  ): SyncState {\n    const value = record.source_updated_at\n    if (!value) return currentState\n    const current = currentState.cursor\n    if (current != null && String(current) >= value) return currentState\n    return { ...currentState, cursor: value }\n  }\n\n  // ========================================\n  // getListing — lista leve via /imoveis-ativos\n  // ========================================\n\n  /**\n   * Lista leve `[{ ref, updatedAt }]`. Usa o endpoint **`/imoveis-ativos`**, que\n   * devolve só os `id_imovel` ativos numa única resposta (~0.3s, ~9KB).\n   *\n   * Notas (JET-002):\n   * - `ref` = `id_imovel` (não o `codigo`). É o que `/imoveis-ativos` fornece e\n   *   o que `?id=` consome. O converter expõe `id_imovel` como campo extra.\n   * - `updatedAt` é sempre `null` — `/imoveis-ativos` não traz timestamp. Pra\n   *   delta com data, use `readRecords(INCREMENTAL)` (que filtra via `?start`).\n   */\n  async getListing(): Promise<ListingEntry[]> {\n    const url = `${this.urlBase}imoveis-ativos?v=4`\n\n    const ids = await retry(async () => {\n      const response = await fetchWithTimeout(url, {\n        timeoutMs: this.requestTimeoutMs,\n      })\n      if (!response.ok) {\n        throw await this.buildHttpError(response, \"getListing(/imoveis-ativos)\")\n      }\n      return extractAtivosIds(await response.json())\n    }, this.retryOptions)\n\n    return ids.map((id) => ({ ref: String(id), updatedAt: null }))\n  }\n\n  // ========================================\n  // fetchByRef — busca individual (?id= com fallback ?codigos=)\n  // ========================================\n\n  /**\n   * Busca UM imóvel pelo `ref`. A Jetimob não tem endpoint individual — usa o\n   * filtro no endpoint de lista. Tenta `?id={ref}` primeiro (pareia com o\n   * `id_imovel` que `getListing` devolve) e, se não achar, tenta `?codigos={ref}`.\n   * Retorna `null` se nenhum dos dois encontrar.\n   */\n  async fetchByRef(ref: string): Promise<HorizonPropertySchemaByJetimobType | null> {\n    const byId = await this.fetchOne(\n      `id=${encodeURIComponent(ref)}`,\n      `fetchByRef(id=${ref})`,\n    )\n    if (byId) return byId\n    return this.fetchOne(\n      `codigos=${encodeURIComponent(ref)}`,\n      `fetchByRef(codigos=${ref})`,\n    )\n  }\n\n  /** Busca 1 imóvel por um filtro de query (`id=...` ou `codigos=...`). */\n  private async fetchOne(\n    filterParam: string,\n    context: string,\n  ): Promise<HorizonPropertySchemaByJetimobType | null> {\n    const url = `${this.urlBase}imoveis?v=4&${filterParam}&pageSize=1`\n\n    const items = await retry(async () => {\n      const response = await fetchWithTimeout(url, {\n        timeoutMs: this.requestTimeoutMs,\n      })\n      if (!response.ok) {\n        throw await this.buildHttpError(response, context)\n      }\n      return this.parseResponse(await response.json())\n    }, this.retryOptions)\n\n    if (items.length === 0) return null\n    return this.convertRecord(items[0])\n  }\n\n  /**\n   * Valida a credencial fazendo o request mais barato possível\n   * (`/imoveis-ativos`, ~9KB). Lança `SyncError` se a `webserviceKey` for\n   * inválida. Usado por `JetimobSource.check()`.\n   */\n  async probe(): Promise<void> {\n    const url = `${this.urlBase}imoveis-ativos?v=4`\n    await retry(async () => {\n      const response = await fetchWithTimeout(url, {\n        timeoutMs: this.requestTimeoutMs,\n      })\n      if (!response.ok) {\n        throw await this.buildHttpError(response, \"probe\")\n      }\n    }, this.retryOptions)\n  }\n\n  // ========================================\n  // helpers\n  // ========================================\n\n  private async buildHttpError(\n    response: Response,\n    context: string,\n  ): Promise<Error> {\n    const body = await response.text().catch(() => \"\")\n    const detail = `${response.status} ${context} ${this.base}: ${body.slice(0, 300)}`\n\n    if (response.status === 401 || response.status === 403) {\n      return SyncError.configError(\n        \"webserviceKey Jetimob inválida ou sem permissão\",\n        detail,\n      )\n    }\n    if (response.status === 429 || response.status >= 500) {\n      return SyncError.transientError(\n        \"API Jetimob temporariamente indisponível\",\n        detail,\n      )\n    }\n    return SyncError.systemError(`Erro HTTP ${response.status} em ${context}`, detail)\n  }\n}\n\n/**\n * Extrai a lista de `id_imovel` da resposta do `/imoveis-ativos`.\n * Envelope observado: `{ total, page, pageSize, totalPages, data: { total, result: [...ids] } }`.\n * Aceita também `data` como array direto, por segurança.\n */\nfunction extractAtivosIds(body: unknown): unknown[] {\n  if (Array.isArray(body)) return body\n  const env = (body ?? {}) as { data?: unknown }\n  if (Array.isArray(env.data)) return env.data\n  const inner = (env.data ?? {}) as { result?: unknown }\n  return Array.isArray(inner.result) ? inner.result : []\n}\n\n/** Converte ISO 8601 pra Unix timestamp (segundos). `null` se inválido. */\nfunction isoToUnix(iso: string): number | null {\n  const ms = new Date(iso).getTime()\n  return Number.isFinite(ms) ? Math.floor(ms / 1000) : null\n}\n","import { hashObject } from \"@horizon-js/integrations-core\"\nimport { safeValidateJetimobPropertySchema } from '../../schemas/jetimob-property-schema.zod'\nimport type { HorizonPropertySchemaByJetimobType } from '../../schemas/horizon-property-schema-by-jetimob.zod'\nimport { convertBaseFields } from './convertBaseFields'\nimport { convertExtendedFields } from './convertExtendedFields'\n\n/**\n * Converte um imóvel bruto do formato Jetimob para o formato Horizon Property.\n *\n * Valida a entrada com Zod (safe parse) e lança erro se inválida.\n * Adiciona `sync_hash` determinístico (SHA-256 64 bits) — usado pelo consumer\n * pra detectar mudanças entre syncs.\n */\nexport function convertJetimobPropertyToHorizon(rawImovel: unknown): HorizonPropertySchemaByJetimobType {\n  const validation = safeValidateJetimobPropertySchema(rawImovel)\n\n  if (!validation.success) {\n    const errors = validation.error.issues\n      .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n      .join(\"; \")\n    throw new Error(`Validação Jetimob falhou: ${errors}`)\n  }\n\n  const imovel = validation.data\n\n  const baseFields = convertBaseFields(imovel)\n  const extendedFields = convertExtendedFields(imovel)\n\n  const payload = { ...baseFields, ...extendedFields }\n\n  return {\n    ...payload,\n    sync_hash: hashObject(payload),\n  } as HorizonPropertySchemaByJetimobType\n}\n\nexport { convertBaseFields } from './convertBaseFields'\nexport { convertExtendedFields } from './convertExtendedFields'","import { z } from \"zod\"\n\n// A API Jetimob retorna null em campos opcionais — todos usam .nullish() (null | undefined)\n\nconst ruralSchema = z.object({\n  atividade_rural: z.string().nullish(),\n  rural_sedes: z.union([z.string(), z.number()]).nullish(),\n  rural_area_aravel: z.number().nullish(),\n  medida_total_area_aravel: z.string().nullish(),\n}).nullish()\n\nconst imagemSchema = z.object({\n  link: z.string(),\n  titulo: z.string().nullish(),\n  link_thumb: z.string().nullish(),\n}).passthrough()\n\nexport const JetimobPropertySchemaSchema = z.object({\n  codigo: z.string(),\n  titulo_anuncio: z.string().max(200).nullish(),\n  observacoes: z.string().nullish(),\n  descricao_anuncio: z.string().nullish(),\n  contrato: z.string().nullish(),\n  tipo: z.string().nullish(),\n  subtipo: z.string().nullish(),\n  status: z.string().nullish(),\n  situacao: z.string().nullish(),\n  destaque: z.string().nullish(),\n  destaque_fim: z.string().nullish(),\n  exclusividade: z.union([z.boolean(), z.number()]).nullish(),\n  financiavel: z.union([z.boolean(), z.number()]).nullish(),\n  permuta: z.union([z.boolean(), z.number()]).nullish(),\n  seguro_fianca: z.union([z.boolean(), z.number()]).nullish(),\n  mobiliado: z.union([z.boolean(), z.number()]).nullish(),\n\n  // Valores monetários\n  valor_venda: z.number().nullish(),\n  valor_venda_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  valor_locacao: z.number().nullish(),\n  valor_locacao_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  valor_temporada: z.number().nullish(),\n  valor_temporada_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  valor_condominio: z.number().nullish(),\n  valor_condominio_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  valor_iptu: z.number().nullish(),\n  valor_iptu_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  valor_seguro_incendio: z.number().nullish(),\n  valor_taxa_limpeza: z.number().nullish(),\n\n  // Características físicas\n  dormitorios: z.number().nullish(),\n  suites: z.number().nullish(),\n  banheiros: z.number().nullish(),\n  garagens: z.number().nullish(),\n  area_total: z.number().nullish(),\n  area_privativa: z.number().nullish(),\n  area_util: z.number().nullish(),\n  andar: z.number().nullish(),\n  andar_visivel: z.union([z.boolean(), z.number()]).nullish(),\n\n  // Endereço\n  endereco_cep: z.string().max(9).nullish(),\n  endereco_estado: z.string().nullish(),\n  endereco_estado_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_cidade: z.string().nullish(),\n  endereco_cidade_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_bairro: z.string().nullish(),\n  endereco_bairro_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_zona: z.string().nullish(),\n  endereco_logradouro: z.string().nullish(),\n  endereco_logradouro_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_numero: z.union([z.string(), z.number()]).nullish(),\n  endereco_numero_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_complemento: z.string().nullish(),\n  endereco_complemento_visivel: z.union([z.boolean(), z.number()]).nullish(),\n  endereco_referencia: z.string().nullish(),\n  endereco_referencia_visivel: z.union([z.boolean(), z.number()]).nullish(),\n\n  // Coordenadas e geolocalização\n  latitude: z.union([z.number(), z.string()]).nullish(),\n  longitude: z.union([z.number(), z.string()]).nullish(),\n  geoposicionamento_visivel: z.number().nullish(),\n\n  // IDs internos\n  id_imovel: z.number().nullish(),\n  id_estado: z.number().nullish(),\n  id_cidade: z.number().nullish(),\n  id_bairro: z.number().nullish(),\n  id_condominio: z.number().nullish(),\n  id_subcondominio: z.number().nullish(),\n  id_corretor: z.number().nullish(),\n\n  // Campos específicos\n  distancia_mar: z.number().nullish(),\n  tipo_construcao: z.string().nullish(),\n  tipo_piso: z.string().nullish(),\n  entrega_ano: z.union([z.number(), z.string()]).nullish(),\n  entrega_mes: z.union([z.number(), z.string()]).nullish(),\n  posicao: z.string().nullish(),\n  posicao_solar: z.string().nullish(),\n  tags: z.string().nullish(),\n\n  // Terreno — API às vezes envia medidas como string; converter faz Number()\n  terreno_frente: z.union([z.number(), z.string()]).nullish(),\n  terreno_fundos: z.union([z.number(), z.string()]).nullish(),\n  terreno_esquerdo: z.union([z.number(), z.string()]).nullish(),\n  terreno_direita: z.union([z.number(), z.string()]).nullish(),\n  terreno_total: z.union([z.number(), z.string()]).nullish(),\n  medida_terreno_total: z.string().nullish(),\n\n  // Pessoas e períodos\n  numero_pessoas: z.number().nullish(),\n  periodicidade_iptu: z.string().nullish(),\n\n  // Condomínio\n  condominio_fechado: z.union([z.boolean(), z.number()]).nullish(),\n  condominio_nome: z.string().nullish(),\n  condominio_tipo: z.string().nullish(),\n  condominio_comodidades: z.union([z.string(), z.array(z.string())]).nullish(),\n\n  // Características\n  imovel_comodidades: z.string().nullish(),\n\n  // Rural\n  rural: ruralSchema,\n\n  // Calendário\n  calendario_temporada: z.union([z.string(), z.array(z.any())]).nullish(),\n\n  // SEO\n  meta_description: z.string().nullish(),\n\n  // Mídia\n  imagens: z.array(imagemSchema).nullish(),\n  videos: z.array(z.any()).nullish(),\n  plantas: z.array(z.any()).nullish(),\n  tour360: z.array(z.any()).nullish(),\n\n  // Configurações\n  medida: z.string().nullish(),\n\n  // Datas\n  data_cadastro: z.string().nullish(),\n  data_update: z.string().nullish(),\n  data_atualizacao: z.string().nullish(),\n  updated_at: z.string().nullish(),\n}).passthrough()\n\nexport type JetimobPropertySchema = z.infer<typeof JetimobPropertySchemaSchema>\n\nexport const validateJetimobPropertySchema = (data: unknown): JetimobPropertySchema => {\n  return JetimobPropertySchemaSchema.parse(data)\n}\n\nexport const safeValidateJetimobPropertySchema = (data: unknown) => {\n  return JetimobPropertySchemaSchema.safeParse(data)\n}\n","import { type JetimobPropertySchema as JetimobImovel } from '../../schemas/jetimob-property-schema.zod'\nimport { type HorizonPropertySchemaByJetimobType as JetimobPropertyV3 } from '../../schemas/horizon-property-schema-by-jetimob.zod'\n\n/**\n * Converte data do formato \"YYYY-MM-DD HH:mm:ss\" para ISO.\n * Retorna null se não fornecida — NUNCA inventar datas (regra do schema base).\n */\nfunction convertToISO(dateStr?: string): string | null {\n  if (!dateStr) return null\n  if (dateStr.includes('T')) return dateStr\n  return dateStr.replace(' ', 'T') + '.000Z'\n}\n\n/**\n * Hash determinístico (FNV-1a 32-bit) de uma string. Mesmo input → mesmo output.\n */\nfunction hashSeed(seed: string): number {\n  let h = 0x811c9dc5\n  for (let i = 0; i < seed.length; i++) {\n    h ^= seed.charCodeAt(i)\n    h = Math.imul(h, 0x01000193)\n  }\n  return h >>> 0\n}\n\n/**\n * Gera coordenadas aproximadas com offset de ~500m, **determinístico** por imóvel.\n *\n * CRÍTICO: o offset é derivado de um `seed` estável (codigo/id do imóvel), NÃO de\n * `Math.random()`. Se fosse aleatório, cada conversão produziria coordenadas\n * diferentes → `sync_hash` instável → o delta acharia que TODO imóvel com\n * `geoposicionamento_visivel === 2` mudou, re-upsertando em todo sync. (JET-007)\n *\n * O resultado é \"aproximado\" no sentido de ofuscar a localização exata — não\n * precisa ser aleatório a cada chamada, só precisa ser deslocado e estável.\n */\nfunction generateApproximateCoords(\n  lat: number,\n  lng: number,\n  seed: string,\n): { lat: number; lng: number } {\n  // 1 grau ≈ 111km, então 500m ≈ 0.0045 graus\n  const offsetDegrees = 500 / 111000\n\n  const h = hashSeed(seed)\n  // Dois \"canais\" do hash → ângulo (0–2π) e distância (0–offsetDegrees), estáveis.\n  const angle = (h % 3600) / 3600 * 2 * Math.PI\n  const distance = ((h >>> 12) % 1000) / 1000 * offsetDegrees\n\n  return {\n    lat: lat + Math.sin(angle) * distance,\n    lng: lng + Math.cos(angle) * distance,\n  }\n}\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.source_key = \"jetimob-api-imoveis\"\n  result.reference = imovel.codigo\n  result.title = imovel.titulo_anuncio || \"Sem título\"\n  result.description = imovel.observacoes || \"Sem descrição\"\n\n  // ========== DATAS — vêm do CRM, nunca inventadas ==========\n  // source_published_at: Jetimob não fornece data de publicação original\n  result.source_updated_at = convertToISO(imovel.data_update ?? imovel.updated_at ?? undefined)\n\n  // ========== SEO ==========\n  // seo_title: Jetimob não tem campo específico - deixar vazio\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\n  // ========== OPERAÇÃO (obrigatório - sem fallback) ==========\n  if (imovel.contrato) {\n    const partes = imovel.contrato.split(\",\").map((s) => s.trim().toLowerCase())\n    const operacoes: Array<\"venda\" | \"locacao\" | \"temporada\"> = []\n\n    for (const parte of partes) {\n      if (parte === \"compra\" || parte === \"venda\") operacoes.push(\"venda\")\n      else if (parte === \"locação\" || parte === \"locacao\" || parte === \"aluguel\") operacoes.push(\"locacao\")\n      else if (parte === \"temporada\") operacoes.push(\"temporada\")\n    }\n\n    if (operacoes.length > 0) result.operacao = operacoes\n  }\n  // Se não tiver contrato, operacao fica undefined e validação vai falhar (obrigatório)\n\n  // ========== VALORES MONETÁRIOS COM VISIBILIDADE ==========\n  if (imovel.valor_venda && imovel.valor_venda_visivel) {\n    const valor = Number(imovel.valor_venda)\n    if (!isNaN(valor) && valor > 0) result.valor_venda = valor\n  }\n  \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 ==========\n  if (imovel.subtipo) result.tipo = imovel.subtipo\n  // Se não tiver subtipo, tipo fica undefined e validação vai falhar (obrigatório)\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  // Cada campo de endereço respeita sua flag `*_visivel` da Jetimob.\n  // A imobiliária marca no CRM o que é privado (padrão do mercado: ocultar\n  // logradouro/número/bairro pra não furar o corretor). `*_visivel` vem\n  // `true|false` ou `1|0` — truthy = mostra, falsy/ausente = oculta (privacy-first).\n  // `endereco_cep` e `endereco_zona` NÃO têm flag na Jetimob → mapeados direto.\n  if (imovel.endereco_estado && imovel.endereco_estado_visivel) result.endereco_estado = imovel.endereco_estado\n  if (imovel.endereco_cidade && imovel.endereco_cidade_visivel) result.endereco_cidade = imovel.endereco_cidade\n  if (imovel.endereco_bairro && imovel.endereco_bairro_visivel) result.endereco_bairro = imovel.endereco_bairro\n  if (imovel.endereco_logradouro && imovel.endereco_logradouro_visivel) result.endereco_logradouro = imovel.endereco_logradouro\n  if (imovel.endereco_numero && imovel.endereco_numero_visivel) result.endereco_numero = String(imovel.endereco_numero).slice(0, 20)\n  if (imovel.endereco_complemento && imovel.endereco_complemento_visivel) result.endereco_complemento = imovel.endereco_complemento\n  if (imovel.endereco_referencia && imovel.endereco_referencia_visivel) result.endereco_referencia = imovel.endereco_referencia\n  if (imovel.endereco_zona) result.endereco_zona = imovel.endereco_zona\n\n  // ========== COORDENADAS COM GEOPOSICIONAMENTO ==========\n  // geoposicionamento_visivel: 0 = Não visível, 1 = Exato, 2 = Aproximado\n  if (imovel.latitude && imovel.longitude) {\n    const lat = Number(imovel.latitude)\n    const lng = Number(imovel.longitude)\n\n    if (!isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0) {\n      const geoVisivel = Number(imovel.geoposicionamento_visivel)\n\n      if (geoVisivel === 1) {\n        // Mostrar localização exata\n        result.lat = lat\n        result.lng = lng\n      } else if (geoVisivel === 2) {\n        // Mostrar localização aproximada (offset ~500m, determinístico por imóvel)\n        result.geo_aproximado = generateApproximateCoords(\n          lat,\n          lng,\n          String(imovel.codigo ?? imovel.id_imovel ?? `${lat},${lng}`),\n        )\n      }\n      // geoVisivel === 0: não mostra nada (lat/lng e geo_aproximado ficam undefined)\n    }\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 (array vazio se não tiver)\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  } else {\n    result.images = []\n  }\n\n  // Vídeos — caso exotic: Jetimob armazena só ID YouTube (sem URL completa).\n  // Conversor reconstrói URL completa pra cumprir contrato universal do schema\n  // base (v3.18+) que pede { url: string } válido. Frontend Horizon usa\n  // react-player que detecta o formato e renderiza.\n  // Se Jetimob expandir pra outros providers no futuro, ajustar aqui (mapa local\n  // dentro deste conversor — peculiaridade desta integration, não shared).\n  if (imovel.videos && imovel.videos.length > 0) {\n    result.videos = imovel.videos\n      .map((video: { link?: string; titulo?: string }) => ({\n        url: video.link ? `https://youtube.com/watch?v=${video.link}` : null,\n      }))\n      .filter((v): v is { url: string } => Boolean(v.url))\n  } else {\n    result.videos = []\n  }\n\n  // Tours virtuais (obrigatório - array vazio se não tiver)\n  if (imovel.tour360 && imovel.tour360.length > 0) {\n    result.virtual_tours = imovel.tour360.map((tour: { link?: string; url?: string } | string) => {\n      // Pode vir como objeto { link: \"url\" } ou string direta\n      const embedUrl = typeof tour === 'string' ? tour : (tour.link || tour.url || '')\n      return { embed_url: embedUrl }\n    }).filter(t => t.embed_url)\n  } else {\n    result.virtual_tours = []\n  }\n\n  return result\n}","import { type JetimobPropertySchema as JetimobImovel } from '../../schemas/jetimob-property-schema.zod'\nimport { type HorizonPropertySchemaByJetimobType } from '../../schemas/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  // Respeita `andar_visivel` — a imobiliária pode marcar o andar como privado\n  // no CRM. `truthy` = mostra; `falsy`/ausente = oculta (privacy-first, JET-009).\n  if (imovel.andar && imovel.andar_visivel) 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  // ========== MOBILIADO ==========\n  if (String(imovel.mobiliado) === \"1\" || String(imovel.mobiliado) === \"true\") {\n    result.mobiliado = true\n  }\n\n  // ========== COMODIDADES/CARACTERÍSTICAS ==========\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  // ========== PLANTAS ==========\n  if (imovel.plantas && imovel.plantas.length > 0) {\n    result.plantas = imovel.plantas.map((planta: { link?: string } | string) => {\n      // Pode vir como objeto { link: \"url\" } ou string direta\n      return typeof planta === 'string' ? planta : (planta.link || '')\n    }).filter(Boolean)\n  }\n\n  // ========== CAMPOS ESPECÍFICOS JETIMOB ==========\n  // id_imovel: ID interno da Jetimob. Pareia com ListingEntry.ref (/imoveis-ativos)\n  // e com o filtro ?id=. Distinto de `reference` (que é o `codigo`).\n  if (imovel.id_imovel != null) result.id_imovel = String(imovel.id_imovel)\n  if (imovel.tipo) result.finalidade = imovel.tipo\n  if (imovel.situacao) result.situacao = imovel.situacao\n  if (imovel.distancia_mar) result.distancia_mar = Number(imovel.distancia_mar)\n  if (imovel.status) result.status = imovel.status\n  if (imovel.posicao) result.posicao = imovel.posicao\n\n  // posicao_solar é multi-valor — a Jetimob serializa \"Sul,Leste\" numa string.\n  // Vira array (igual caracteristicas/condominio_comodidades) → pesquisável no banco.\n  if (imovel.posicao_solar) {\n    const arr = String(imovel.posicao_solar)\n      .split(',')\n      .map(p => p.trim())\n      .filter(p => p.length > 0)\n    if (arr.length > 0) result.posicao_solar = arr\n  }\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    const comodidadesCondArray = String(imovel.condominio_comodidades)\n      .split(',')\n      .map(c => c.trim())\n      .filter(c => c.length > 0)\n    if (comodidadesCondArray.length > 0) {\n      result.condominio_comodidades = comodidadesCondArray\n    }\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\n  // tipo_piso é multi-valor — \"Porcelanato,Mármore\" numa string. Vira array.\n  if (imovel.tipo_piso) {\n    const arr = String(imovel.tipo_piso)\n      .split(',')\n      .map(p => p.trim())\n      .filter(p => p.length > 0)\n    if (arr.length > 0) result.tipo_piso = arr\n  }\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_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 { Source, CheckResult, Stream } from \"@horizon-js/integrations-core\"\nimport type { JetimobCredentials } from \"./types\"\nimport { jetimobManifest } from \"./manifest\"\nimport { jetimobSpec } from \"./spec\"\nimport { JetimobPropertyStream } from \"./streams/JetimobPropertyStream\"\n\nexport interface JetimobSourceOptions {\n  /** URL base da API. Default: `https://api.jetimob.com`. */\n  readonly baseUrl?: string\n}\n\n/**\n * Source da Jetimob — implementação do contrato `Source<JetimobCredentials>`\n * do `@horizon-js/integrations-core`.\n *\n * Expõe:\n * - `manifest` — cartão declarativo (metadata, capabilities, knownIssues, streams)\n * - `spec` — JSON Schema das credenciais\n * - `check(config)` — valida a `webserviceKey` com o request mais barato possível\n * - `streams(config)` — retorna `[JetimobPropertyStream]`\n *\n * A Jetimob é só-leitura (por enquanto) — não implementa `writers()`.\n *\n * ## Uso\n *\n * ```ts\n * import { JetimobSource } from \"@horizon-integrations/jetimob-crm\"\n * import { SyncMode } from \"@horizon-js/integrations-core\"\n *\n * const source = new JetimobSource()\n *\n * // 1. Valida credenciais\n * const { ok } = await source.check({ webserviceKey: \"...\" })\n * if (!ok) throw new Error(\"webserviceKey inválida\")\n *\n * // 2. Lê imóveis (streaming, paginação automática)\n * const [stream] = source.streams({ webserviceKey: \"...\" })\n * for await (const property of stream.readRecords(SyncMode.FULL_REFRESH)) {\n *   await db.properties.upsert(property)\n * }\n * ```\n *\n * Pra uso de alto nível (sem mexer com streams), veja as funções de\n * conveniência `fetchAll` / `getListing` / `fetchByRef` exportadas pelo pacote.\n */\nexport class JetimobSource implements Source<JetimobCredentials> {\n  readonly name = \"jetimob\"\n  readonly manifest = jetimobManifest\n  readonly spec = jetimobSpec\n\n  constructor(private readonly options: JetimobSourceOptions = {}) {}\n\n  async check(config: JetimobCredentials): Promise<CheckResult> {\n    if (!config?.webserviceKey || typeof config.webserviceKey !== \"string\") {\n      return { ok: false, message: \"webserviceKey ausente ou inválida\" }\n    }\n    try {\n      const stream = new JetimobPropertyStream(config, {\n        baseUrl: this.options.baseUrl,\n      })\n      await stream.probe()\n      return { ok: true }\n    } catch (err) {\n      const msg = err instanceof Error ? err.message : String(err)\n      return { ok: false, message: msg }\n    }\n  }\n\n  streams(config: JetimobCredentials): Stream<unknown>[] {\n    return [\n      new JetimobPropertyStream(config, {\n        baseUrl: this.options.baseUrl,\n      }) as Stream<unknown>,\n    ]\n  }\n}\n","/**\n * PropertyDownloader — **thin wrapper** sobre `JetimobSource` / `JetimobPropertyStream`.\n *\n * A implementação real (auth, paginação, conversão, streaming) vive em\n * `src/source.ts` + `src/streams/JetimobPropertyStream.ts`, seguindo o contrato\n * `Source` / `Stream<T>` do `@horizon-js/integrations-core` (padrão Airbyte).\n *\n * Estas funções de conveniência existem pra DX de alto nível — mesmos nomes em\n * todos os pacotes `@horizon-integrations/*` (`fetchAll`, `getListing`,\n * `fetchByRef`). Pra código novo que precisa de streaming/state, prefira usar\n * `JetimobSource` direto:\n *\n * ```ts\n * import { JetimobSource } from \"@horizon-integrations/jetimob-crm\"\n * import { SyncMode } from \"@horizon-js/integrations-core\"\n *\n * const [stream] = new JetimobSource().streams({ webserviceKey })\n * for await (const property of stream.readRecords(SyncMode.FULL_REFRESH)) {\n *   await db.upsert(property)\n * }\n * ```\n */\nimport { parseResponseDefensive } from \"@horizon-js/integrations-core\"\nimport type { HorizonPropertySchemaByJetimobType } from \"../schemas/horizon-property-schema-by-jetimob.zod\"\nimport type { JetimobCredentials } from \"../types\"\nimport { convertJetimobPropertyToHorizon } from \"./PropertyConverter\"\nimport { JetimobPropertyStream } from \"../streams/JetimobPropertyStream\"\n\n// Re-export pra conveniência dos consumers.\nexport type { JetimobCredentials } from \"../types\"\n\nexport interface FetchConfig {\n  credentials: JetimobCredentials\n  /** URL base da API. Default: `https://api.jetimob.com`. */\n  baseUrl?: string\n  /** Tamanho de página. Default: `100`. */\n  pageSize?: number\n}\n\nexport interface FetchAllResult {\n  properties: HorizonPropertySchemaByJetimobType[]\n  /** Imóveis que falharam validação Zod — não derrubam o batch. */\n  errors: string[]\n}\n\nexport interface ListingEntry {\n  ref: string\n  /** Data de última atualização no CRM (ISO 8601), ou `null` se ausente. */\n  updatedAt: string | null\n}\n\nfunction buildStream(config: FetchConfig): JetimobPropertyStream {\n  return new JetimobPropertyStream(config.credentials, {\n    baseUrl: config.baseUrl,\n    pageSize: config.pageSize,\n  })\n}\n\n/**\n * Baixa todos os imóveis da conta Jetimob e converte pro formato Horizon.\n * Imóveis que falharem validação Zod ficam em `errors` — não derrubam o batch.\n */\nexport async function fetchAll(config: FetchConfig): Promise<FetchAllResult> {\n  const stream = buildStream(config)\n  const rawItems = await stream.fetchRaw()\n\n  const { valid, errors } = parseResponseDefensive(\n    rawItems,\n    convertJetimobPropertyToHorizon,\n    (raw) => String((raw as { codigo?: unknown })?.codigo ?? \"?\"),\n  )\n\n  return {\n    properties: valid,\n    errors: errors.map((e) => `${e.ref ?? `#${e.index}`}: ${e.message}`),\n  }\n}\n\n/**\n * Retorna a lista leve `{ ref, updatedAt }[]` de todos os imóveis.\n * Usado pelo orquestrador pra calcular delta sem baixar o payload completo.\n */\nexport async function getListing(config: FetchConfig): Promise<ListingEntry[]> {\n  return buildStream(config).getListing()\n}\n\n/**\n * Busca um imóvel específico pelo código (`ref`). Retorna `null` se não existir.\n */\nexport async function fetchByRef(\n  config: FetchConfig,\n  ref: string,\n): Promise<HorizonPropertySchemaByJetimobType | null> {\n  return buildStream(config).fetchByRef(ref)\n}\n\n// ========================================\n// CLASSE CLIENTE (reuso de config entre chamadas)\n// ========================================\n\nexport interface PropertyDownloaderConfig {\n  credentials: JetimobCredentials\n  baseUrl?: string\n  pageSize?: number\n}\n\n/**\n * Cliente com config reusável entre chamadas. Wrapper fino sobre as funções\n * `fetchAll` / `getListing` / `fetchByRef`.\n */\nexport class PropertyDownloader {\n  private readonly config: FetchConfig\n\n  constructor(config: PropertyDownloaderConfig) {\n    this.config = config\n  }\n\n  fetchAll(): Promise<FetchAllResult> {\n    return fetchAll(this.config)\n  }\n\n  getListing(): Promise<ListingEntry[]> {\n    return getListing(this.config)\n  }\n\n  fetchByRef(ref: string): Promise<HorizonPropertySchemaByJetimobType | null> {\n    return fetchByRef(this.config, ref)\n  }\n}\n","/**\n * Jetimob Extended Schema - v2.3.0\n *\n * Schema estendido do Horizon Base com campos específicos do Jetimob CRM\n * Formato Entity Schema v2.0.0 com tipagens completas\n *\n * Total: 86 campos (47 base Horizon + 39 extras Jetimob)\n * - Campos base: importados de @horizon-js/property-domain-schema\n * - Campos extras: específicos do Jetimob CRM\n *\n * ⚠️ Este arquivo DEVE espelhar horizon-property-schema-by-jetimob.zod.ts —\n * todo campo validado no Zod precisa estar declarado aqui. O teste\n * __dev__/tests/schema-consistency.test.ts trava essa regra.\n */\n\nimport type { EntitySchema } from \"@horizon-js/property-domain-schema\";\nimport { horizonPropertySchemaBase } from \"@horizon-js/property-domain-schema\";\n\nexport const HorizonPropertySchemaByJetimob: EntitySchema = {\n\tentity: \"property\",\n\tversion: \"2.3.0\",\n\tdescription: \"Schema estendido Jetimob CRM - 86 campos (47 base + 39 extras)\",\n\tfields: [\n\t\t// ========================================\n\t\t// 📦 53 CAMPOS BASE HORIZON V3 (importados)\n\t\t// ========================================\n\t\t...horizonPropertySchemaBase.fields,\n\n\t\t// ========================================\n\t\t// 🔧 39 CAMPOS ADICIONAIS JETIMOB\n\t\t// ========================================\n\t\t{\n\t\t\tkey: \"tags\",\n\t\t\ttype: \"String[]\",\n\t\t\tdb: { type: \"jsonb\", index: \"gin\" },\n\t\t\tcategories: [\"ficha-tecnica\"],\n\t\t\tui: { label: \"Tags\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"numero_pessoas\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"count\",\n\t\t\tvalidation: { min: 0 },\n\t\t\tcategories: [\"comercial\"],\n\t\t\trules: { conditions: [\"operacao.contains:temporada\"] },\n\t\t\tui: { label: \"Número de pessoas\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"valor_diaria\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"currency\",\n\t\t\tunit: \"BRL\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"valores\"],\n\t\t\trules: { conditions: [\"operacao.contains:temporada\"] },\n\t\t\tui: { label: \"Valor da diária\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"geo_aproximado\",\n\t\t\ttype: \"Json\",\n\t\t\tdb: { type: \"jsonb\" },\n\t\t\tcategories: [\"localizacao\"],\n\t\t\tui: { label: \"Localização aproximada\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"id_imovel\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"sistema\"],\n\t\t\tui: { label: \"ID interno Jetimob\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"plantas\",\n\t\t\ttype: \"String[]\",\n\t\t\tdb: { type: \"jsonb\", index: \"gin\" },\n\t\t\tcategories: [\"ficha-tecnica\"],\n\t\t\tui: { label: \"Plantas\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"caracteristicas\",\n\t\t\ttype: \"String[]\",\n\t\t\tcategories: [\"ficha-tecnica\"],\n\t\t\tdb: {\n\t\t\t\ttype: \"jsonb\",\n\t\t\t\tindex: \"gin\",\n\t\t\t},\n\t\t\tui: {\n\t\t\t\tlabel: \"Características\",\n\t\t\t},\n\t\t\taudit: {\n\t\t\t\torigin: \"provider-extra\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tkey: \"finalidade\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"ficha-tecnica\"],\n\t\t\tui: {\n\t\t\t\tlabel: \"Finalidade\",\n\t\t\t},\n\t\t\taudit: {\n\t\t\t\torigin: \"provider-extra\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tkey: \"mobiliado\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"ficha-tecnica\"],\n\t\t\tui: {\n\t\t\t\tlabel: \"Mobiliado\",\n\t\t\t},\n\t\t\taudit: {\n\t\t\t\torigin: \"provider-extra\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tkey: \"valor_seguro_incendio\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"currency\",\n\t\t\tunit: \"BRL\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"valores\"],\n\t\t\tui: { label: \"Valor do seguro incêndio\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"valor_taxa_limpeza\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"currency\",\n\t\t\tunit: \"BRL\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"valores\"],\n\t\t\tui: { label: \"Valor da taxa de limpeza\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"andar\",\n\t\t\ttype: \"Number\",\n\t\t\tcategories: [\"endereco\"],\n\t\t\tui: { label: \"Andar\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"financiavel\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\tui: { label: \"Financiável\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"exclusividade\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\tui: { label: \"Exclusividade\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"permuta\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\trules: { conditions: [\"operacao.contains:venda\"] },\n\t\t\tui: { label: \"Aceita permuta\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"seguro_fianca\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\trules: { conditions: [\"operacao.contains:locacao\"] },\n\t\t\tui: { label: \"Seguro fiança\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"situacao\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"situacoes\"],\n\t\t\tui: { label: \"Situação de ocupação\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"distancia_mar\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"distance\",\n\t\t\tunit: \"m\",\n\t\t\tvalidation: { min: 0 },\n\t\t\tcategories: [\"localizacao\"],\n\t\t\tui: { label: \"Distância do mar\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"posicao\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"estrutura\"],\n\t\t\tui: { label: \"Posição do imóvel no terreno\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"posicao_solar\",\n\t\t\ttype: \"String[]\",\n\t\t\tdb: { type: \"jsonb\", index: \"gin\" },\n\t\t\tcategories: [\"estrutura\"],\n\t\t\tui: { label: \"Posição solar\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"status\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\tdb: { default: \"ativo\" },\n\t\t\tui: { label: \"Status do imóvel\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"calendario_temporada\",\n\t\t\ttype: \"Json\",\n\t\t\tcategories: [\"comercial\"],\n\t\t\tdb: { type: \"jsonb\" },\n\t\t\trules: { conditions: [\"operacao.contains:temporada\"] },\n\t\t\tui: { label: \"Calendário temporada\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"condominio_comodidades\",\n\t\t\ttype: \"String[]\",\n\t\t\tcategories: [\"condominio\"],\n\t\t\tdb: { type: \"jsonb\", index: \"gin\" },\n\t\t\tui: { label: \"Comodidades do condomínio\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"condominio_tipo\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"condominio\"],\n\t\t\tui: { label: \"Tipo do condomínio\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"subcondominio_id\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"condominio\"],\n\t\t\tui: { label: \"ID do subcondomínio\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"condominio_fechado\",\n\t\t\ttype: \"Boolean\",\n\t\t\tcategories: [\"condominio\"],\n\t\t\tui: { label: \"Condomínio fechado\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"entrega_ano\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"year\",\n\t\t\tcategories: [\"cronograma\"],\n\t\t\tui: { label: \"Ano de entrega\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"entrega_mes\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"month\",\n\t\t\tvalidation: { min: 1, max: 12 },\n\t\t\tcategories: [\"cronograma\"],\n\t\t\trules: { conditions: [\"entrega_ano.exists:true\"] },\n\t\t\tui: { label: \"Mês de entrega\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"tipo_construcao\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"estrutura\"],\n\t\t\tui: { label: \"Tipo de construção\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"tipo_piso\",\n\t\t\ttype: \"String[]\",\n\t\t\tdb: { type: \"jsonb\", index: \"gin\" },\n\t\t\tcategories: [\"estrutura\"],\n\t\t\tui: { label: \"Tipo de piso\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"periodicidade_iptu\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"valores\"],\n\t\t\tui: { label: \"Periodicidade do IPTU\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"terreno_frente\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"distance\",\n\t\t\tunit: \"m\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"medidas\"],\n\t\t\tui: { label: \"Frente do terreno\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"terreno_fundos\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"distance\",\n\t\t\tunit: \"m\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"medidas\"],\n\t\t\tui: { label: \"Fundos do terreno\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"terreno_esquerdo\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"distance\",\n\t\t\tunit: \"m\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"medidas\"],\n\t\t\tui: { label: \"Lateral esquerda\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"terreno_direita\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"distance\",\n\t\t\tunit: \"m\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"medidas\"],\n\t\t\tui: { label: \"Lateral direita\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"terreno_total\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"area\",\n\t\t\tunit: \"m2\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"medidas\"],\n\t\t\tui: { label: \"Área total do terreno\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"rural_area_aravel\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"area\",\n\t\t\tunit: \"hectare\",\n\t\t\tvalidation: { min: 0, precision: 2 },\n\t\t\tcategories: [\"rural\"],\n\t\t\tui: { label: \"Área arável\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"rural_sedes\",\n\t\t\ttype: \"Number\",\n\t\t\tformat: \"count\",\n\t\t\tvalidation: { min: 0 },\n\t\t\tcategories: [\"rural\"],\n\t\t\tui: { label: \"Número de sedes\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t\t{\n\t\t\tkey: \"rural_atividade\",\n\t\t\ttype: \"String\",\n\t\t\tcategories: [\"rural\"],\n\t\t\tui: { label: \"Atividade rural\" },\n\t\t\taudit: { origin: \"provider-extra\" },\n\t\t},\n\t],\n};\n\nexport default HorizonPropertySchemaByJetimob;\n","import { z } from \"zod\"\nimport { HorizonPropertySchemaBaseZod } from \"@horizon-js/property-domain-schema\"\n\n// Schema Horizon para Jetimob CRM\n// Herda do base e adiciona campos específicos do Jetimob\n\n// ========================================\n// SCHEMAS DE MÍDIA (override para opcional)\n// ========================================\nconst ImageSchema = z.object({\n  md: z.string().optional(),\n  sm: z.string().optional(),\n  full: z.string().optional(),\n  cover: z.boolean().optional()\n}).passthrough()\n\nconst VideoSchema = z.object({\n  url: z.string().optional(),\n}).passthrough()\n\nconst VirtualTourSchema = z.object({\n  embed_url: z.string().optional()\n}).passthrough()\n\nconst MainImageSchema = z.object({\n  md: z.string().optional(),\n  sm: z.string().optional(),\n  full: z.string().optional()\n}).passthrough()\n\nexport const HorizonPropertySchemaByJetimobZod = HorizonPropertySchemaBaseZod\n  .omit({ images: true, videos: true, virtual_tours: true, main_image: true })\n  .extend({\n  // ========================================\n  // JETIMOB EXTRAS\n  // ========================================\n\n  // Campos que saíram do base (agora são extras)\n  tags: z.array(z.string()).describe(\"Tags do imóvel\").optional(),\n  numero_pessoas: z.number().min(0).describe(\"Número de pessoas (temporada)\").optional(),\n  valor_diaria: z.number().describe(\"Valor da diária (temporada)\").optional(),\n  geo_aproximado: z.object({\n    lat: z.number().min(-90).max(90),\n    lng: z.number().min(-180).max(180),\n  }).describe(\"Coordenadas aproximadas (offset ~500m)\").optional(),\n\n  // Campos específicos Jetimob\n  id_imovel: z\n    .string()\n    .describe(\n      \"ID interno do imóvel na Jetimob (id_imovel). É o que /imoveis-ativos lista e o que ?id= consome — pareia com ListingEntry.ref. Distinto de `reference`, que é o `codigo`.\",\n    )\n    .optional(),\n  finalidade: z.string().describe(\"Finalidade\").optional(),\n  mobiliado: z.boolean().describe(\"Mobiliado\").optional(),\n  caracteristicas: z.array(z.string()).describe(\"Características/Comodidades\").optional(),\n  plantas: z.array(z.string()).describe(\"URLs das plantas\").optional(),\n\n  // Valores adicionais\n  valor_seguro_incendio: z\n    .number()\n    .min(0)\n    .describe(\"Valor do seguro incêndio\")\n    .optional(),\n  valor_taxa_limpeza: z\n    .number()\n    .min(0)\n    .describe(\"Valor da taxa de limpeza\")\n    .optional(),\n\n  // Estrutura\n  andar: z.number().describe(\"Andar\").optional(),\n\n  // Comercial\n  financiavel: z.boolean().describe(\"Financiável\").optional(),\n  exclusividade: z.boolean().describe(\"Exclusividade\").optional(),\n  permuta: z.boolean().describe(\"Aceita permuta\").optional(),\n  seguro_fianca: z.boolean().describe(\"Seguro fiança\").optional(),\n  situacao: z.string().describe(\"Situação de ocupação\").optional(),\n  status: z.string().describe(\"Status do imóvel\").optional(),\n\n  // Localização\n  distancia_mar: z.number().min(0).describe(\"Distância do mar\").optional(),\n  posicao: z.string().describe(\"Posição do imóvel no terreno\").optional(),\n  posicao_solar: z\n    .array(z.string())\n    .describe(\"Posição solar — multi-valor (Norte, Leste, ...)\")\n    .optional(),\n\n  // Temporada\n  calendario_temporada: z.any().describe(\"Calendário temporada\").optional(),\n\n  // Condomínio estendido\n  condominio_comodidades: z\n    .array(z.string())\n    .describe(\"Comodidades do condomínio\")\n    .optional(),\n  condominio_tipo: z.string().describe(\"Tipo do condomínio\").optional(),\n  subcondominio_id: z.string().describe(\"ID do subcondomínio\").optional(),\n  condominio_fechado: z.boolean().describe(\"Condomínio fechado\").optional(),\n\n  // Construção\n  entrega_ano: z.number().describe(\"Ano de entrega\").optional(),\n  entrega_mes: z.number().min(1).max(12).describe(\"Mês de entrega\").optional(),\n  tipo_construcao: z.string().describe(\"Tipo de construção\").optional(),\n  tipo_piso: z\n    .array(z.string())\n    .describe(\"Tipo de piso — multi-valor (Porcelanato, Mármore, ...)\")\n    .optional(),\n\n  // Períodos\n  periodicidade_iptu: z.string().describe(\"Periodicidade do IPTU\").optional(),\n\n  // Terreno\n  terreno_frente: z.number().min(0).describe(\"Frente do terreno\").optional(),\n  terreno_fundos: z.number().min(0).describe(\"Fundos do terreno\").optional(),\n  terreno_esquerdo: z.number().min(0).describe(\"Lateral esquerda\").optional(),\n  terreno_direita: z.number().min(0).describe(\"Lateral direita\").optional(),\n  terreno_total: z.number().min(0).describe(\"Área total do terreno\").optional(),\n\n  // Rural\n  rural_area_aravel: z.number().min(0).describe(\"Área arável\").optional(),\n  rural_sedes: z.number().min(0).describe(\"Número de sedes\").optional(),\n  rural_atividade: z.string().describe(\"Atividade rural\").optional(),\n}).passthrough()\n\n// Tipo inferido a partir do schema\nexport type HorizonPropertySchemaByJetimobType = z.infer<\n  typeof HorizonPropertySchemaByJetimobZod\n>\n\n// Função helper para validação\nexport const validateHorizonPropertySchemaByJetimob = (\n  data: unknown\n): HorizonPropertySchemaByJetimobType => {\n  return HorizonPropertySchemaByJetimobZod.parse(data)\n}\n\n// Função helper para validação safe\nexport const safeValidateHorizonPropertySchemaByJetimob = (data: unknown) => {\n  return HorizonPropertySchemaByJetimobZod.safeParse(data)\n}\n\n// Função helper para validação parcial\nexport const validatePartialHorizonPropertySchemaByJetimob = (data: unknown) => {\n  return HorizonPropertySchemaByJetimobZod.partial().parse(data)\n}\n"],"mappings":"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","names":["SyncMode","SyncMode","z"]}