@horizon-integrations/nifb-vrsync-client
v1.0.0
Published
Client HTTP tipado pra consumir a API do horizon-integrations-hub (rotas /api/providers/nifb-vrsync/v1/*). Instalado nos sites das imobiliárias pra puxar imóveis do feed NIFB via hub, preservando Anti-Corruption Layer.
Maintainers
Readme
@horizon-integrations/nifb-vrsync-client
Client HTTP tipado pra consumir a API do horizon-integrations-hub (rotas /api/providers/nifb-vrsync/v1/*). Instalado nos sites das imobiliárias pra puxar imóveis do feed NIFB via hub — preservando Anti-Corruption Layer (DDD).
Arquitetura
┌────────────────────┐ ┌──────────────────┐ ┌───────────────┐
│ Site Horizon │ HTTP │ hub │ HTTP │ Feed NIFB XML │
│ @horizon- │───────▶│ @horizon- │───────▶│ (público) │
│ integrations/ │ │ integrations/ │ │ │
│ nifb-vrsync-client │ │ nifb-vrsync │ │ │
└────────────────────┘ └──────────────────┘ └───────────────┘Site consome só o client (este pacote, leve). Hub consome o runtime (@horizon-integrations/nifb-vrsync). Client e runtime são pacotes separados — sem bloat no bundle do site.
Instalação
pnpm add @horizon-integrations/nifb-vrsync-clientUso básico
import { NifbVrsyncClient } from "@horizon-integrations/nifb-vrsync-client"
const nifb = new NifbVrsyncClient({
baseUrl: process.env.HUB_URL!, // https://hub.horizonintegrations.com
authToken: process.env.HUB_TOKEN!, // x-api-key do hub
tenantConfig: { // opcional — feed é público
filter: {
excludeIds: ["31", "237"],
includeCities: ["FRANCISCO BELTRAO"],
},
},
})
// Streaming de imóveis
for await (const property of nifb.properties.streamAll()) {
await db.properties.upsert(property)
}
// Listing leve — só refs + PublishDate único do feed
const { index } = await nifb.properties.getListing()
// Validar conectividade (hub + feed)
const check = await nifb.check()
if (!check.ok) throw new Error(check.message)Delta via sync_hash
Records vêm com sync_hash (SHA-256 truncado). Pra detectar mudanças sem re-inserir tudo:
for await (const p of nifb.properties.streamAll()) {
const existing = await db.properties.findUnique({ where: { reference: p.reference } })
if (existing?.sync_hash === p.sync_hash) continue // sem mudança
await db.properties.upsert({
where: { reference: p.reference },
create: p,
update: p,
})
}Por que sync_hash em vez de source_updated_at? NIFB tem único PublishDate pra todo o feed (ver NIFB-001 no manifest do runtime) — não dá pra comparar timestamp individual. O hash resolve isso.
Capabilities
nifb.capabilities.individualFetch // false — sem fetchByRef
nifb.capabilities.writes.sendLead // false — feed é read-only
nifb.capabilities.pagination // false — feed é atômico
nifb.capabilities.nativeTimestamp // true — PublishDate do headerLimitações documentadas
Ver knownIssues do manifest runtime (@horizon-integrations/nifb-vrsync@^2.0.0):
- NIFB-001 — sem timestamp por record (use
sync_hash) - NIFB-002 — feed atômico (sem fetchByRef, sem paginação)
- NIFB-003 — feed pode conter múltiplas imobiliárias (use
filter)
Relacionado
@horizon-integrations/nifb-vrsync— runtime (Source/Stream/converter/schemas) consumido pelo hub@horizon-js/integrations-core— contratos (Client, ListingEntry, SourceCapabilities)client-sdk-pattern.md— doc canônico no core
