Skip to content

Airbyte · Lightfield (CRM comercial)

Replica el CRM Lightfield (reemplazo de HubSpot desde 2026-10) a solvento-data-prod.lightfield.* con un conector custom de Airbyte (Connector Builder) y lo modela en dbt-etls hacia solvento-adv-analytics-prod.lightfield.*.

Reemplaza a Airbyte · Hubspot

Lo nuevo del CRM vive acá. Airbyte · Hubspot sigue sincronizando hubspot.* mientras la cuenta esté activa y queda como historia previa al corte: solo se migró una parte de los deals (ver cobertura). La tabla de equivalencias dice qué tabla nueva reemplaza a cada una de HubSpot.

¿Llegaste hasta acá desde…?

Si ves… Eso sale de… La lógica está en…
Oportunidades / funnel por pipeline y etapa del CRM solvento-adv-analytics-prod.lightfield.lightfield_opportunities dbt-etls → models/advanced_analytics/lightfield/lightfield_opportunities.sql
Ids como pd_… / opt_… en vez de nombres …lightfield.stg_lightfield_select_options dbt-etls → …/stg_lightfield_select_options.sql (sale del stream definitions)
Cuentas (empresas) del CRM, RFC, línea de crédito, LOC …lightfield.stg_lightfield_accounts dbt-etls → …/stg_lightfield_accounts.sql
Owner / responsable comercial …lightfield.stg_lightfield_members dbt-etls → …/stg_lightfield_members.sql
Fecha de entrada a cada etapa de un deal migrado …lightfield.stg_lightfield_opportunity_hubspot_stage_dates dbt-etls → …/stg_lightfield_opportunity_hubspot_stage_dates.sql
Un registro crudo con fields / relationships en JSON solvento-data-prod.lightfield.* (RAW) Airbyte (sin lógica de negocio); ver "Paso a paso"
Campo Valor
Origen API REST de Lightfield (https://api.lightfield.app/v1, header Lightfield-Version: 2026-03-01)
Patrón Airbyte con conector custom (Connector Builder, manifest declarativo) — sin lógica de negocio en la ingesta
Destino RAW solvento-data-prod.lightfield.* (5 tablas)
Destino dbt solvento-adv-analytics-prod.lightfield.* (6 tablas, tag:lightfield)
Frecuencia Airbyte cada 6 h (confirmar en Airbyte; es lo que muestra _airbyte_extracted_at) · dbt-etls con el job diario de dbt Cloud
Criticidad 🟢 Baja hoy (todavía nadie lee de producción); sube a 🟡 Media cuando crédito migre
Dueño Martin (conector y dbt-etls) · consumo en crédito y analytics: Diego
Repos dbt-etls · manifest del conector en lightfield-airbyte (pendiente de subir a GitLab)

Diagrama de linaje

graph LR
    SRC[["📇 Lightfield<br/>API REST v1"]]

    subgraph ing["1 · Ingesta (sin lógica de negocio)"]
        AB["Airbyte<br/>conector custom<br/>(Connector Builder)"]
        RAW[("solvento-data-prod.lightfield<br/>accounts · contacts · opportunities<br/>members · definitions")]
    end

    subgraph logica["2 · Lógica · dbt-etls (tag:lightfield)"]
        STG[("adv-analytics.lightfield<br/>stg_lightfield_* (5)<br/>JSON → columnas")]
        OPP[("adv-analytics.lightfield<br/>lightfield_opportunities<br/>labels · owner · RFC")]
    end

    CONS["📈 Funnels · crédito (DSCR) · Meowth<br/>(migrando desde hubspot.*)"]

    SRC -->|"Bearer · 25 por página<br/>$updatedAt · cada 6 h"| AB --> RAW --> STG --> OPP --> CONS

    classDef src fill:#fde68a,stroke:#b45309,color:#000;
    classDef store fill:#bfdbfe,stroke:#1e40af,color:#000;
    class SRC src;
    class RAW,STG,OPP store;

Paso a paso

1 · Ingesta (mueve datos, no aplica lógica de negocio)

  1. Lightfield expone el CRM por API REST. La key está en Secret Manager como lightfield_api_key y se configura en el conector, no en código.
  2. Airbyte corre un conector custom armado en el Connector Builder (manifest declarativo). Las decisiones salen de un probe de la API (2026-10-02):
    • Paginación por offset con limit=25, que es el máximo (26 da 400 limit_too_large). El orden es fijo por createdAt descendente y estable entre requests.
    • Incremental server-side con $updatedAt[greaterThan]. El $ es obligatorio: sin él la API responde 400 "Unknown filter field". Lookback de 1 h para no perder updates en vuelo.
    • Streams: accounts, contacts y opportunities en Incremental | Append + Deduped por id; members y definitions en Full refresh | Overwrite.
    • Rate limit: 25 req/s por categoría y organización; ~1,4 s por página. Una sync completa de accounts (~19.000 registros) tarda del orden de 18 min (estimado: ~750 páginas × 1,4 s).
  3. Cada registro llega con fields en JSON ({slug: {valueType, value}}) y relationships en JSON ({slug: {cardinality, objectType, values}}). Un campo nuevo en Lightfield entra solo dentro del JSON, sin tocar el esquema.
  4. definitions trae una fila por objeto (accounts, contacts, opportunities) con fieldDefinitions y relationshipDefinitions. Es la única fuente de los labels: los registros traen los selects como ids (pd_… para pipelines, opt_… para etapas y opciones).

2 · Lógica de negocio (dbt — aquí están las reglas) → repo dbt-etls

Todo en models/advanced_analytics/lightfield/, materializado como table en solvento-adv-analytics-prod.lightfield. El tag es por carpeta en dbt_project.yml: dbt build --select tag:lightfield.

  1. stg_lightfield_opportunities — una fila por oportunidad. Deja afuera el texto generado por IA ($opportunityStatus) y las relaciones que vienen vacías.
  2. stg_lightfield_accounts — una fila por cuenta. is_from_hubspot (tiene hubspot-company-id) y has_captured_activity (correos o reuniones capturados por Lightfield) separan lo útil del ruido.
  3. stg_lightfield_members — los owners, con nombre y email.
  4. stg_lightfield_select_options — catálogo de opciones de todos los selects; option_order es el orden de Lightfield.
  5. stg_lightfield_opportunity_hubspot_stage_dates — las fechas hs-v2-date-entered-<id> importadas de HubSpot, en formato largo. El grano (oportunidad, etapa) se verifica en tests/test_lightfield_stage_dates_grain_unique.sql.
  6. lightfield_opportunities — la tabla de uso: pipeline y etapa con label, stage_order dentro del pipeline, producto y origen con label, owner con nombre y rfc de la oportunidad o, si falta, de la cuenta (rfc_source).

3 · Consumo

  • Al 2026-10-05 no hay consumidores productivos. Diego migra los procesos de crédito (DSCR) y los funnels que leen de hubspot.*; la tabla de equivalencias de abajo es el punto de partida.

Tablas que alimenta

Tabla Contenido Cómo se carga
lightfield.accounts (RAW) Cuentas (empresas) Airbyte (incremental + dedup)
lightfield.contacts (RAW) Contactos (sin modelo dbt todavía) Airbyte (incremental + dedup)
lightfield.opportunities (RAW) Oportunidades (deals) Airbyte (incremental + dedup)
lightfield.members (RAW) Usuarios del workspace Airbyte (full refresh)
lightfield.definitions (RAW) Definiciones de campos y relaciones por objeto Airbyte (full refresh)
adv-analytics.lightfield.stg_lightfield_opportunities 1 oportunidad por fila, con ids dbt-etls (table)
adv-analytics.lightfield.stg_lightfield_accounts 1 cuenta por fila dbt-etls (table)
adv-analytics.lightfield.stg_lightfield_members 1 usuario por fila dbt-etls (table)
adv-analytics.lightfield.stg_lightfield_select_options 1 opción de select por fila dbt-etls (table)
adv-analytics.lightfield.stg_lightfield_opportunity_hubspot_stage_dates 1 fila por oportunidad y etapa de HubSpot dbt-etls (table)
adv-analytics.lightfield.lightfield_opportunities Tabla de uso. Oportunidades con labels, owner y RFC dbt-etls (table)

Equivalencias con HubSpot

HubSpot (solvento-data-prod.hubspot / dbt-analytics) Lightfield (solvento-adv-analytics-prod.lightfield) Notas
hubspot.deals · stg_hubspot__deals · int_hubspot_deals stg_lightfield_opportunities (ids) · lightfield_opportunities (labels) hubspot_deal_id une con la historia de HubSpot
stg_hubspot__funnel_deals · int_funnel_deals_adela / _qp · fct_funnel_* lightfield_opportunities filtrando pipeline_label stage_order es la posición dentro del pipeline
hs_v2_date_entered_* en deals stg_lightfield_opportunity_hubspot_stage_dates Foto de la migración; ver limitaciones
hubspot.deal_pipelines · int_pipeline_stages stg_lightfield_select_options (field_key = $pipeline / $stage) Los ids cambian (pd_…, opt_…); parent_option_id = pipeline
hubspot.company · stg_hubspot__company · int_hubspot_company stg_lightfield_accounts hubspot_company_id une con HubSpot; rfc ya normalizado
hubspot.deal_company · stg_hubspot__deals_company account_id en las tablas de oportunidades Una cuenta por oportunidad
hubspot.owners stg_lightfield_members
hubspot.contact · stg_hubspot__contacts — (RAW solvento-data-prod.lightfield.contacts) Sin modelo dbt todavía
company_property_history · deal_property_history — El historial de campos de Lightfield no se replica

La clasificación new / cli / renewal de int_hubspot_deals no se traslada sola

Se arma con ids de etapa de HubSpot. En Lightfield los ids son otros, así que hay que redefinirla por pipeline y etapa. cli corresponde al pipeline Customer Request (318 de 453 deals migrados) y renewal a Renovaciones (227 deals, ninguno migrado: el pipeline existe en Lightfield pero sin oportunidades).

Cobertura de la migración

Medido el 2026-10-05: 2.917 de 13.109 deals de HubSpot están en Lightfield, todos con hubspot_deal_id. Lo no migrado sigue disponible solo en hubspot.*.

Pipeline en HubSpot Deals en HubSpot Migrados %
Adela 9.424 749 7,9 %
QuickPay / Working Capital 1.652 1.623 98,2 %
Customer Success 2 501 0 0 %
Customer Request 455 319 70,1 %
Renovaciones 254 0 0 %
SAAS Pipeline 203 0 0 %
Carriers factoring 181 168 92,8 %
Nuevas condiciones 73 0 0 %
Brokers & Partners 65 0 0 %
Brokers 64 58 90,6 %
Otros (Partnerships, Solvento Paga Collab, pipelines sin nombre) 237 0 0 %

Lightfield tiene 12 pipelines; hoy solo 5 tienen oportunidades (Adela, QuickPay / Working Capital, Customer Request, Carriers factoring y Brokers).

Limitaciones que hay que conocer

  1. Los borrados no se propagan. La key no tiene acceso a la papelera (status=trashed da 403), así que un registro borrado en Lightfield sigue en la tabla deduplicada. Opciones: un Refresh periódico con remoción de registros, o detectarlos comparando contra un recorrido completo.
  2. Las listas inversas de una cuenta pueden quedar desactualizadas. Vincular una oportunidad no siempre cambia el updatedAt de la cuenta, y si no cambia el incremental no la vuelve a traer. Tras la carga del 2026-10-04, 31 de las 2.486 cuentas con oportunidades quedaron con la lista $opportunity incompleta (34 oportunidades). Lo mismo puede pasar con $contact, $mail y $meeting. Por eso los modelos usan el vínculo del lado del hijo (account_id de la oportunidad) y no cuentan oportunidades desde la cuenta. Un Refresh conservando registros de accounts y contacts corrige las listas.
  3. No hay fechas de cambio de etapa después del corte. entered_current_stage_at y stg_lightfield_opportunity_hubspot_stage_dates son campos importados de HubSpot: Lightfield no los actualiza cuando una oportunidad cambia de etapa. La historia de etapas de Lightfield existe en el endpoint /opportunities/{id}/fields/{key}/history, pero es una llamada por oportunidad y no se replica. Afecta cualquier funnel por fecha de entrada a etapa.
  4. Los selects dependen de definitions. Si se crea un pipeline o etapa nueva, el label aparece en la siguiente sync. Los tests not_null de pipeline_label y stage_label avisan (warn) si falta.
  5. Ruido en cuentas. ~7.100 cuentas creadas el 2026-10-04 no vienen de HubSpot ni tienen actividad capturada (todas con owner). Filtrar con is_from_hubspot / has_captured_activity y revisar su origen con Comercial antes de usarlas.
  6. Frescura. El RAW tiene hasta ~6 h de atraso; las tablas de adv-analytics dependen del job diario de dbt-etls (hasta ~1 día). Para más frecuencia, un job de dbt Cloud con dbt build --select tag:lightfield.
  7. El destino de BigQuery descarta columnas no declaradas en el esquema del stream (por eso members llegó sin fields en la v1 del conector). Dentro de fields y relationships no aplica: ahí entra todo.

Si falla 🛠️

Impacto: 🟢 bajo mientras nadie lea en producción. Cuando crédito migre: los procesos que usan el CRM quedan con datos del día anterior; no bloquea operación ni producto.

Síntoma Dónde mirar Acción
lightfield.* no se actualiza UI de Airbyte → conexión de Lightfield (estado y hora del último sync) Revisar logs y reintentar el sync
401 / 403 Secret Manager lightfield_api_key y la key en Lightfield (Settings → API keys) Regenerar la key, actualizar el secreto y la configuración del conector
400 "Unknown filter field" o limit_too_large Manifest del conector El filtro necesita el $ ($updatedAt[greaterThan]); limit ≤ 25
429 Logs del sync El conector reintenta con Retry-After; si persiste, bajar la frecuencia
pipeline_label / stage_label en NULL (test en warn) solvento-data-prod.lightfield.definitions Correr la sync (definitions es full refresh); suele ser un pipeline o etapa nuevos
owner_name en NULL solvento-data-prod.lightfield.members Correr la sync o refrescar el stream members
adv-analytics.lightfield.* vieja con el RAW al día Job de dbt Cloud de dbt-etls Re-ejecutar dbt build --select tag:lightfield
Un registro borrado en Lightfield sigue en BigQuery — Limitación conocida (ver arriba)

Escalación: conector de Airbyte y dbt-etls → Martin · consumo en crédito y analytics (dbt-analytics, Metabase) → Diego · configuración del CRM (campos, pipelines, cargas) → administración de Lightfield en Comercial.

Enlaces

  • 📊 Estado en vivo: dashboard "Data Processes" (Cloud Monitoring)
  • ⚙️ Ingesta: Airbyte → conexión de Lightfield (conector custom del Connector Builder); manifest en lightfield-airbyte (pendiente de subir a GitLab)
  • 🧮 Lógica: dbt-etls — models/advanced_analytics/lightfield/
  • 🔗 Relacionado: Airbyte · Hubspot (historia previa al corte) · Capa dbt

Última actualización: 2026-10-05 · Pendientes: subir el manifest a GitLab; definir la frecuencia de dbt para tag:lightfield; borrados; historial de etapas posterior al corte. Si cambia el flujo o un modelo dbt, actualizar esta ficha en el mismo MR.