@horizon-integrations/jetimob-crm
Version:
Adapter de integração com o CRM Jetimob — padrão Airbyte (@horizon-js/integrations-core)
112 lines (79 loc) • 3.89 kB
Markdown
# @horizon-integrations/jetimob-crm
Adapter de integração com o **CRM Jetimob** para o ecossistema Horizon. Cumpre o
contrato canônico do `@horizon-js/integrations-core` — padrão Airbyte CDK,
TypeScript-first (Hexagonal Architecture + Anti-Corruption Layer).
Converte os imóveis da API Jetimob para o formato `HorizonProperty`
(`@horizon-js/property-domain-schema`).
## Instalação
```bash
pnpm add @horizon-integrations/jetimob-crm
```
## Credenciais
A autenticação da Jetimob é uma única **`webserviceKey`** — ela vai embutida no
path da URL (`/webservice/{webserviceKey}/imoveis`). Obtida no painel Jetimob da
imobiliária.
```ts
const credentials = { webserviceKey: "sua-chave-webservice" }
```
## Uso
### Camada 1 — Núcleo Airbyte (`Source` / `Stream`)
Forma canônica. Use quando precisar de streaming, sync incremental ou state.
```ts
import { JetimobSource } from "@horizon-integrations/jetimob-crm"
import { SyncMode } from "@horizon-js/integrations-core"
const source = new JetimobSource()
// valida a credencial (request barato no /imoveis-ativos)
const { ok, message } = await source.check(credentials)
if (!ok) throw new Error(message)
// lê os imóveis convertidos (paginação automática)
const [stream] = source.streams(credentials)
for await (const property of stream.readRecords(SyncMode.FULL_REFRESH)) {
await db.properties.upsert(property)
}
// sync incremental — filtra server-side via ?start={unix}, traz só o delta
const state = { cursor: "2026-05-01T00:00:00.000Z" }
for await (const property of stream.readRecords(SyncMode.INCREMENTAL, state)) {
await db.properties.upsert(property)
}
```
### Camada 2 — Funções de conveniência
DX de alto nível — mesmos nomes em todos os pacotes `@horizon-integrations/*`.
```ts
import { fetchAll, getListing, fetchByRef } from "@horizon-integrations/jetimob-crm"
// baixa + converte todos os imóveis em memória
const { properties, errors } = await fetchAll({ credentials })
// lista leve { ref, updatedAt }[] — usa /imoveis-ativos (~0.3s)
const listing = await getListing({ credentials })
// um imóvel pelo id_imovel (ou codigo)
const property = await fetchByRef({ credentials }, "6570922")
```
### Camada 3 — Conversão + schemas
```ts
import { convertJetimobPropertyToHorizon } from "@horizon-integrations/jetimob-crm"
const horizonProperty = convertJetimobPropertyToHorizon(rawJetimobImovel)
```
## A API Jetimob — o que importa saber
Tudo isto está testado contra a API real e declarado em `jetimobManifest`:
| Recurso | Endpoint / Param | Comportamento |
|---|---|---|
| Dump completo | `GET /imoveis?v=4&page=&pageSize=` | Envelope `{ total, page, pageSize, totalPages, data: [...] }`. ~96 campos por imóvel |
| **Lista leve** | `GET /imoveis-ativos?v=4` | Só os `id_imovel` ativos, numa tacada (~0.3s). É o que `getListing()` usa |
| **Incremental** | `?start={unix}` / `?end={unix}` | Filtra por data de atualização **server-side**. Unix timestamp (segundos) |
| Busca individual | `?id={id_imovel}` ou `?codigos={codigo}` | `id` ≠ `codigo` — `fetchByRef` aceita os dois |
| Seleção de campos | — | **Não existe.** `/imoveis` sempre devolve os ~96 campos |
`id_imovel` vs `codigo`: `reference` no formato Horizon é o **`codigo`**. O
`id_imovel` é exposto como campo extra (`id_imovel`) — é o que `/imoveis-ativos`
lista e o que `getListing().ref` devolve.
## Documentação
- [`docs/API_REFERENCE.md`](./docs/API_REFERENCE.md) — métodos públicos do pacote
- [`docs/FICHA_TECNICA_INTEGRACAO.md`](./docs/FICHA_TECNICA_INTEGRACAO.md) — mapeamento campo-a-campo Jetimob → Horizon
- [`docs/API_JETIMOB.md`](./docs/API_JETIMOB.md) — referência da API externa Jetimob
- [`CHANGELOG.md`](./CHANGELOG.md)
- [`examples/`](./examples/) — scripts de exemplo
## Build
```bash
pnpm install
pnpm typecheck
pnpm test
pnpm build
```