# API Reference — @horizon-integrations/jetimob-crm

Referência dos exports públicos do pacote. Três camadas.

---

## Camada 1 — Núcleo Airbyte

### `JetimobSource`

Implementa `Source<JetimobCredentials>` do `@horizon-js/integrations-core`.

```ts
new JetimobSource(options?: { baseUrl?: string })
```

| Membro | Tipo | Descrição |
|---|---|---|
| `name` | `"jetimob"` | Slug do source |
| `manifest` | `SourceManifest` | Cartão declarativo (capabilities, knownIssues, streams) |
| `spec` | `SourceSpec` | JSON Schema das credenciais |
| `check(config)` | `Promise<CheckResult>` | Valida a `webserviceKey` (request barato no `/imoveis-ativos`) |
| `streams(config)` | `Stream<unknown>[]` | Retorna `[JetimobPropertyStream]` |

### `JetimobPropertyStream`

Implementa `Stream<HorizonProperty>` + `IncrementalStream`. Estende `HttpStream`.

```ts
new JetimobPropertyStream(credentials, options?: {
  baseUrl?: string
  requestTimeoutMs?: number   // default 30_000
  pageSize?: number           // default 200
})
```

| Método | Retorno | Descrição |
|---|---|---|
| `readRecords(syncMode, state?)` | `AsyncGenerator<HorizonProperty>` | Stream de imóveis convertidos. `INCREMENTAL` + `state.cursor` → filtra server-side via `?start={unix}`. Defensivo: record que falha validação Zod é pulado com warning, não derruba o batch |
| `streamAll()` | `AsyncGenerator<HorizonProperty>` | Herdado do `HttpStream` — delega pra `readRecords(FULL_REFRESH)` |
| `getListing()` | `Promise<ListingEntry[]>` | Lista leve via `/imoveis-ativos`. `ref` = `id_imovel`, `updatedAt` = `null` |
| `fetchByRef(ref)` | `Promise<HorizonProperty \| null>` | Um imóvel. Tenta `?id={ref}`, fallback `?codigos={ref}` |
| `fetchRaw()` | `Promise<unknown[]>` | Todos os imóveis crus (sem conversão) — pra profiling/debug |
| `getUpdatedState(state, record)` | `SyncState` | Avança o cursor incremental (maior `source_updated_at`) |
| `probe()` | `Promise<void>` | Valida credencial. Lança `SyncError` se inválida |

Propriedades: `name="properties"`, `supportedSyncModes=[FULL_REFRESH, INCREMENTAL]`,
`cursorField="source_updated_at"`, `primaryKey=["reference"]`, `retryOptions` (backoff 4×).

### `jetimobManifest` / `jetimobSpec`

Objetos declarativos. `jetimobManifest.capabilities` e `jetimobManifest.knownIssues`
descrevem a API externa sem precisar ler código.

### `JetimobCredentials`

```ts
interface JetimobCredentials { webserviceKey: string }
```

---

## Camada 2 — Funções de conveniência

Thin wrappers sobre `JetimobSource` / `JetimobPropertyStream`.

### `fetchAll(config)`

```ts
fetchAll(config: FetchConfig): Promise<{ properties: HorizonProperty[]; errors: string[] }>
```

Baixa + converte todos os imóveis em memória. Records que falham validação Zod
ficam em `errors` (formato `"{ref}: {mensagem}"`), não derrubam o batch.

### `getListing(config)`

```ts
getListing(config: FetchConfig): Promise<ListingEntry[]>
```

Lista leve `{ ref, updatedAt }[]` via `/imoveis-ativos` (~0.3s). `ref` = `id_imovel`,
`updatedAt` = `null` (esse endpoint não traz timestamp).

### `fetchByRef(config, ref)`

```ts
fetchByRef(config: FetchConfig, ref: string): Promise<HorizonProperty | null>
```

Um imóvel pelo `id_imovel` (ou `codigo` como fallback). `null` se não existir.

### `PropertyDownloader`

Classe cliente com config reusável: `new PropertyDownloader(config)` →
`.fetchAll()`, `.getListing()`, `.fetchByRef(ref)`.

### `FetchConfig`

```ts
interface FetchConfig {
  credentials: JetimobCredentials
  baseUrl?: string
  pageSize?: number   // default 200
}
```

---

## Camada 3 — Conversão + schemas

| Export | Descrição |
|---|---|
| `convertJetimobPropertyToHorizon(raw)` | Valida (Zod) + converte um imóvel cru + adiciona `sync_hash`. Lança erro se inválido |
| `convertBaseFields(imovel)` / `convertExtendedFields(imovel)` | Partes do conversor (campos base / extras Jetimob) |
| `JetimobPropertySchemaZod` + `validateJetimobPropertySchema` + `safeValidateJetimobPropertySchema` | Schema Zod do imóvel **cru** (entrada da API) |
| `HorizonPropertySchemaByJetimobZod` + validators | Schema Zod do imóvel **convertido** (saída Horizon + extras Jetimob) |
| `HorizonPropertySchemaByJetimob` | `EntitySchema` declarativo (base + 32 extras Jetimob) |
| `HorizonPropertySchemaByJetimobType` | Tipo TypeScript do imóvel convertido |

---

## Exemplos

Ver [`examples/`](../examples/): `fetch-all.ts`, `get-listing.ts`, `fetch-by-ref.ts`.
