Conocimiento
Construir productos de datos con dbt
dbt es una de las herramientas más populares para transformar datos. Así estructuramos los proyectos dbt como productos de datos, con propiedad clara, Output Ports, Data Contracts y tests de calidad. Y te enseñamos cómo usamos coding agents para implementar los productos de datos de forma automática.
¿Por qué dbt para productos de datos?
dbt (data build tool) es un framework de transformación SQL-first que funciona sobre data warehouses como Snowflake, BigQuery, Databricks, AWS Athena y DuckDB. Trae al mundo de los datos las buenas prácticas de la ingeniería de software: control de versiones, modularidad, testing y documentación.
Esas propiedades hacen que dbt encaje de forma natural a la hora de implementar productos de datos. Un proyecto dbt puede representar un producto de datos: tiene entradas claras, lógica de transformación, modelos de salida, tests y documentación, todo en un único repositorio Git con un equipo propietario.
Empieza por un Data Contract
Vamos con un ejemplo real: un producto de datos que en Entropy Data usamos internamente para customer success, y que nos ayuda a entender cómo usan nuestros clientes la aplicación y si podemos apoyarles de forma proactiva para que construyan mejores productos de datos con Data Contracts.
Antes de escribir ningún modelo dbt, empezamos definiendo un Data Contract para el producto de datos objetivo (o, más exactamente, para su Output Port). El Data Contract describe qué datos vas a tener que proporcionar, su esquema, sus garantías de calidad y sus condiciones de uso. Piensa en él como la especificación de requisitos de nuestro producto de datos.
Al diseñar primero el contrato, nos ponemos de acuerdo sobre qué información hace falta realmente antes de invertir tiempo en la implementación. Eso mantiene el producto de datos pequeño y manejable. Este enfoque contract-first evita construir conjuntos de datos que nadie usa o que no cumplen nuestras expectativas.
El Data Contract se escribe en formato ODCS y se guarda junto al SQL que gobierna, en models/output_ports/v1/:
# models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
apiVersion: v3.1.0
kind: DataContract
id: entropydata-customer-activity-v1
name: Customer Activity
version: 1.0.0
status: draft
description:
usage: analytics
purpose: Customer activity within Entropy Data for customer success.
schema:
- name: customer_activity
physicalType: table
properties:
- name: organization_id
description: Unique identifier of the organization.
logicalType: string
required: true
primaryKey: true
examples:
- 550e8400-e29b-41d4-a716-446655440000
- name: organization_vanity_url
description: Vanity URL of the organization.
logicalType: string
examples:
- acme-corp
- name: organization_created_by
description: Email address of the user that created the organization.
logicalType: string
examples:
- admin@acme.com
- name: organization_created_at
description: Timestamp when the organization was created.
logicalType: timestamp
examples:
- "2024-03-15T10:00:00Z"
- name: users_total
description: Total number of users in the organization.
logicalType: integer
required: true
examples:
- 12
- name: users_added_30d
description: Number of users added in the last 30 days.
logicalType: integer
required: true
examples:
- 3
- name: users_last_signed_up_at
description: Timestamp when the last user signed up.
logicalType: timestamp
examples:
- "2024-09-10T14:22:00Z"
- name: dataproducts_total
description: Total number of data products in the organization.
logicalType: integer
required: true
examples:
- 42
- name: dataproducts_added_30d
description: Number of data products added in the last 30 days.
logicalType: integer
required: true
examples:
- 5
- name: dataproducts_outputports_total
description: Total number of output ports across all data products.
logicalType: integer
required: true
examples:
- 58
- name: dataproducts_outputports_with_datacontract_percentage
description: Percentage of output ports that have an active data contract.
logicalType: number
required: true
examples:
- 72.5
- name: dataproducts_outputports_with_testresults_percentage
description: Percentage of output ports that have test results.
logicalType: number
required: true
examples:
- 65.0
- name: dataproducts_last_updated_at
description: Timestamp when the last data product was updated.
logicalType: timestamp
examples:
- "2024-09-14T09:30:00Z"
- name: assets_total
description: Total number of assets in the organization.
logicalType: integer
required: true
examples:
- 87
- name: data_platform
description: The data contract / output port type used for most data products.
logicalType: string
examples:
- bigquery
- snowflake
- s3
- name: updated_at
description: Timestamp when this record was written by the dbt execution.
logicalType: timestamp
required: true
examples:
- "2024-09-16T06:05:23Z"
team:
name: customer-success
servers:
- server: production
type: databricks
catalog: entropy_data_prod
schema: dp_entropydata_customer_activity_v1
roles:
- role: customer_success
access: read
Un producto de datos que cumpla esta especificación ayudaría a nuestro equipo de customer success a identificar la actividad de un cliente y a saber de un vistazo cuál es su plataforma de datos objetivo.
En Entropy Data, el Data Contract se puede editar y gestionar desde el Data Contract Editor:
Con el contrato ya definido, la implementación en dbt es directa: construir los modelos que lo cumplen.
Diseño del producto de datos
Nuestro producto de datos Customer Activity está alineado con el consumo: toma datos operacionales en bruto, los transforma y los sirve para un caso de uso concreto, customer success.
Los datos van desde nuestra aplicación Entropy Data Cloud (la base de datos operacional Postgres) a un producto de datos en bruto alineado con la fuente que extrae los datos de Postgres a Databricks (con dlt), y de ahí al producto de datos Customer Activity que queremos construir ahora con dbt.
Un proyecto dbt por producto de datos
Nuestro enfoque recomendado es un proyecto dbt por producto de datos. Cada proyecto pertenece a un equipo y vive en su propio repositorio Git, de forma que cada producto de datos se puede implementar y desplegar de manera independiente. Una buena práctica que aprendimos con los Self-contained Systems. Así se garantizan una propiedad clara y la autonomía, principios centrales del Data Mesh.
La estructura típica de un proyecto dbt de producto de datos es esta:
dp_entropydata_customer_activity/
├── dbt_project.yml
├── dp_entropydata_customer_activity.odps.yaml # Data product spec (ODPS)
├── openlineage.yml # OpenLineage transport config
├── profiles.yml.example
├── .github/workflows/data-product.yml # CI: build, test, publish
├── models/
│ ├── input_ports/ # External sources this product reads from
│ │ ├── _models.yml
│ │ ├── <provider-output-port-id>.source.yaml # One file per active access agreement
│ │ └── <provider-output-port-id>.odcs.yaml # Cached snapshot of upstream contract
│ ├── staging/ # Internal: 1:1 cleaned views over input ports
│ │ ├── _models.yml
│ │ ├── stg_organizations.sql
│ │ ├── stg_members.sql
│ │ ├── stg_data_products.sql
│ │ └── stg_assets.sql
│ ├── intermediate/ # Internal: joined/shaped views with business logic
│ │ ├── _models.yml
│ │ └── int_customer_activity.sql
│ └── output_ports/v1/ # Public: versioned output port models
│ ├── _models.yml
│ ├── customer_activity.sql
│ └── entropydata-customer-activity-v1.odcs.yaml # Data contract (ODCS), colocated with the SQL
├── tests/ # Custom data tests
│ └── assert_users_total_non_negative.sql
├── analyses/
├── macros/
├── seeds/
└── snapshots/
La idea clave: los modelos de input_ports/, staging/ e intermediate/ son internos al producto de datos.
Solo los modelos de output_ports/ forman la interfaz pública que consumen otros equipos.
Los Output Ports están versionados (v1/, v2/, ...) y el contrato ODCS se guarda en el mismo directorio que el modelo SQL que lo implementa, así que el contrato vive junto al código que gobierna.
Mantenemos esta estructura como un conjunto de skills para coding agents en el plugin dataproduct-builder-dbt, de modo que Claude Code, Codex o Copilot CLI pueden generar el esqueleto de un proyecto nuevo, crear los modelos a partir de un Data Contract y sincronizarlo todo con Entropy Data.
Output Ports como modelos dbt
Los modelos de Output Port se implementan normalmente como vistas SQL o tablas materializadas que actúan como la API estable del producto de datos. Abstraen la lógica interna de staging y transformación y permiten cambiar la implementación sin afectar a los Data Consumers.
En lugar de escribir a mano las definiciones de los modelos dbt, la Data Contract CLI puede generarlas directamente a partir del Data Contract:
datacontract export dbt-models --output models/output_ports/v1/_models.yml models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
Esto genera el YAML del modelo dbt con columnas, descripciones y tipos de datos:
# models/output_ports/v1/_models.yml (generated)
version: 2
models:
- name: customer_activity
description: Customer activity within Entropy Data for customer success.
config:
meta:
data_contract:
id: entropydata-customer-activity-v1
file: models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
owner: customer-success
materialized: table
contract:
enforced: true
columns:
- name: organization_id
description: Unique identifier of the organization.
data_type: STRING
constraints:
- type: not_null
- type: unique
- name: organization_vanity_url
description: Vanity URL of the organization.
data_type: STRING
- name: organization_created_by
description: Email address of the user that created the organization.
data_type: STRING
- name: organization_created_at
description: Timestamp when the organization was created.
data_type: TIMESTAMP
- name: users_total
description: Total number of users in the organization.
data_type: BIGINT
constraints:
- type: not_null
- name: users_added_30d
description: Number of users added in the last 30 days.
data_type: BIGINT
constraints:
- type: not_null
- name: users_last_signed_up_at
description: Timestamp when the last user signed up.
data_type: TIMESTAMP
- name: dataproducts_total
description: Total number of data products in the organization.
data_type: BIGINT
constraints:
- type: not_null
- name: dataproducts_added_30d
description: Number of data products added in the last 30 days.
data_type: BIGINT
constraints:
- type: not_null
- name: dataproducts_outputports_total
description: Total number of output ports across all data products.
data_type: BIGINT
constraints:
- type: not_null
- name: dataproducts_outputports_with_datacontract_percentage
description: Percentage of output ports that have an active data contract.
data_type: DOUBLE
constraints:
- type: not_null
- name: dataproducts_outputports_with_testresults_percentage
description: Percentage of output ports that have test results.
data_type: DOUBLE
constraints:
- type: not_null
- name: dataproducts_last_updated_at
description: Timestamp when the last data product was updated.
data_type: TIMESTAMP
- name: assets_total
description: Total number of assets in the organization.
data_type: BIGINT
constraints:
- type: not_null
- name: data_platform
description: The data contract / output port type used for most data products.
data_type: STRING
- name: updated_at
description: Timestamp when this record was written by the dbt execution.
data_type: TIMESTAMP
constraints:
- type: not_null
Generar el archivo del modelo dbt suele ser una operación puntual.
A partir de ahí puedes guardar el modelo en Git y añadirle los detalles que necesites.
Ahora toca implementar la lógica de transformación SQL de cada modelo de salida:
-- models/output_ports/v1/customer_activity.sql
-- Governed by entropydata-customer-activity-v1.odcs.yaml (ODCS id: entropydata-customer-activity-v1)
{{ config(
materialized='table',
schema='op_v1'
) }}
select
organization_id,
organization_vanity_url,
organization_created_by,
organization_created_at,
users_total,
users_added_30d,
users_last_signed_up_at,
dataproducts_total,
dataproducts_added_30d,
dataproducts_outputports_total,
dataproducts_outputports_with_datacontract_percentage,
dataproducts_outputports_with_testresults_percentage,
dataproducts_last_updated_at,
assets_total,
data_platform
from {{ ref('int_customer_activity') }}
Input Ports
Un producto de datos suele consumir datos de sistemas operacionales o de otros productos de datos. En el nuestro usamos datos extraídos con dlt desde nuestra base de datos operacional Postgres hacia un producto de datos en bruto, alineado con la fuente, en la plataforma de datos (Databricks).
En dbt, las entradas se modelan como sources.
Cada Data Contract activo que consumimos se convierte en un archivo dentro de models/input_ports/, con el nombre del id del Output Port del proveedor.
Junto a él cacheamos el contrato ODCS del proveedor upstream como instantánea de confianza, así git log muestra cuándo cambió por debajo un esquema o una regla de calidad upstream:
# models/input_ports/op_entropydata_postgres.source.yaml
version: 2
sources:
- name: dp_entropydata_postgres_op_entropydata_postgres
description: Operational database of the Entropy Data platform, extracted to Databricks via dlt.
database: entropy_data_prod
schema: entropydata_postgres
config:
meta:
data_contract:
id: entropydata-postgres-v1
file: models/input_ports/op_entropydata_postgres.odcs.yaml
tables:
- name: organization
- name: organization_member
- name: data_product
- name: asset
El sources[].name combina <provider-data-product-id>_<provider-output-port-id> para que dos acuerdos con el mismo proveedor pero distintos Output Ports nunca colisionen.
El op_entropydata_postgres.odcs.yaml cacheado se guarda junto al archivo de source y se actualiza volviendo a ejecutar entropy-data datacontracts get, nunca a mano.
Transformación
Entre la entrada y la salida, los modelos internos hacen el trabajo de transformación con la lógica de negocio. No se exponen a los Data Consumers.
Los modelos de staging limpian y normalizan los datos brutos de origen: deduplican quedándose con la última versión, convierten tipos y renombran columnas.
-- models/staging/stg_organizations.sql
with source as (
select *,
row_number() over (partition by organization_id order by version desc) as _row_num
from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'organization') }}
)
select
organization_id,
vanity_url as organization_vanity_url,
created_by as organization_created_by,
cast(created_at as timestamp) as organization_created_at
from source
where _row_num = 1
-- models/staging/stg_members.sql
with source as (
select *,
row_number() over (partition by organization_member_id order by version desc) as _row_num
from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'organization_member') }}
)
select
organization_member_id,
organization_id,
user_id,
role,
cast(created_at as timestamp) as created_at
from source
where _row_num = 1
-- models/staging/stg_data_products.sql
with source as (
select *,
row_number() over (partition by data_product_id order by version desc) as _row_num
from {{ source('dp_entropydata_postgres_op_entropydata_postgres', 'data_product') }}
)
select
data_product_id,
organization_id,
name,
status,
specification_type,
cast(created_at as timestamp) as created_at,
cast(updated_at as timestamp) as updated_at
from source
where _row_num = 1
Los modelos intermediate aplican la lógica de negocio: unen tablas, enriquecen con datos maestros y calculan campos derivados.
-- models/intermediate/int_customer_activity.sql
with members_per_org as (
select
organization_id,
count(*) as users_total,
count(case when created_at >= date_sub(current_date(), 30) then 1 end) as users_added_30d,
max(created_at) as users_last_signed_up_at
from {{ ref('stg_members') }}
group by organization_id
),
data_products_per_org as (
select
organization_id,
count(*) as dataproducts_total,
count(case when created_at >= date_sub(current_date(), 30) then 1 end) as dataproducts_added_30d,
-- TODO: add output_port source table to compute these metrics
cast(0 as bigint) as dataproducts_outputports_total,
cast(0 as double) as dataproducts_outputports_with_datacontract_percentage,
cast(0 as double) as dataproducts_outputports_with_testresults_percentage,
max(updated_at) as dataproducts_last_updated_at,
first(specification_type) as data_platform
from {{ ref('stg_data_products') }}
group by organization_id
),
assets_per_org as (
select
organization_id,
count(*) as assets_total
from {{ ref('stg_assets') }}
group by organization_id
)
select
o.organization_id,
o.organization_vanity_url,
o.organization_created_by,
o.organization_created_at,
coalesce(m.users_total, 0) as users_total,
coalesce(m.users_added_30d, 0) as users_added_30d,
m.users_last_signed_up_at,
coalesce(dp.dataproducts_total, 0) as dataproducts_total,
coalesce(dp.dataproducts_added_30d, 0) as dataproducts_added_30d,
coalesce(dp.dataproducts_outputports_total, 0) as dataproducts_outputports_total,
coalesce(dp.dataproducts_outputports_with_datacontract_percentage, 0) as dataproducts_outputports_with_datacontract_percentage,
coalesce(dp.dataproducts_outputports_with_testresults_percentage, 0) as dataproducts_outputports_with_testresults_percentage,
dp.dataproducts_last_updated_at,
coalesce(a.assets_total, 0) as assets_total,
dp.data_platform
from {{ ref('stg_organizations') }} o
left join members_per_org m on o.organization_id = m.organization_id
left join data_products_per_org dp on o.organization_id = dp.organization_id
left join assets_per_org a on o.organization_id = a.organization_id
Construir el producto de datos
Cuando ejecutamos dbt run, dbt materializa todos los modelos y crea la tabla de salida en Databricks.
El resultado es una tabla customer_activity en el esquema dp_entropydata_customer_activity_op_v1, lista para que la consuma el equipo de customer success.
Testing
El testing es lo que convierte un proyecto dbt en un producto de datos fiable. Sin tests, los Data Consumers no tienen motivos para confiar en los datos: se montarán sus propias comprobaciones, duplicarán lógica o directamente evitarán usar el producto de datos. Los tests automáticos hacen visible la calidad y dan a los Data Consumers la confianza de que los datos de los que dependen son correctos y completos.
Testear un producto de datos funciona en dos niveles: tests unitarios que verifican la implementación interna y tests de contrato que verifican la salida desde el punto de vista del Data Consumer.
Tests unitarios
Los tests de dbt verifican pasos concretos a lo largo del pipeline de datos. Están muy acoplados a la implementación y cambian según evolucionan los modelos dbt.
Los tests de esquema se declaran en los archivos YAML y validan not_null, unique, accepted_values y relationships en cada modelo.
Los tests de datos personalizados son consultas SQL en la carpeta tests/ que comprueban reglas de negocio:
-- tests/assert_users_total_non_negative.sql
select organization_id
from {{ ref('customer_activity') }}
where users_total < 0
Si la consulta devuelve alguna fila, el test falla.
Además, los contracts de dbt (desde dbt 1.5) fuerzan los nombres de columna y los tipos de datos en tiempo de build.
El modelo dbt generado ya incluye contract.enforced: true.
Tests de contrato
La Data Contract CLI testea el Output Port desde el punto de vista del Data Consumer, contra el Data Contract. Es un test de aceptación: se conecta a la plataforma de datos real, consulta las tablas de salida y comprueba el esquema, el número de filas y las reglas de calidad definidas en el contrato.
datacontract test models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
Los tests de contrato son más estables que los tests de dbt. No cambian cuando refactorizas los modelos internos de staging o intermediate. Mientras el Output Port siga cumpliendo el contrato, los tests pasan. Eso los hace ideales para los pipelines de CI/CD y para generar confianza en los Data Consumers.
Data lineage con OpenLineage
El wrapper de dbt de OpenLineage (dbt-ol) emite eventos de data lineage al final de cada ejecución de dbt.
Entropy Data los ingiere y dibuja un grafo interactivo de data lineage en la página del producto de datos, mostrando cómo las tablas de entrada en bruto fluyen por los modelos de staging, intermediate y de salida.
Configura el transporte en un openlineage.yml en la raíz del proyecto, codificando los identificadores del producto de datos y del Output Port como parámetros de consulta en el endpoint:
# openlineage.yml
transport:
type: http
url: https://api.entropy-data.com
endpoint: api/v1/lineage?dataProductId=dp_entropydata_customer_activity&outputPortId=customer_activity
auth:
type: api_key
La apiKey se omite del archivo a propósito (no admite plantillas con variables de entorno) y se inyecta en tiempo de ejecución mediante OPENLINEAGE__TRANSPORT__AUTH__APIKEY, así el secreto nunca acaba en el control de versiones.
Pipeline de CI/CD
Cada producto de datos tiene su propio pipeline de CI/CD, que se ejecuta en cada push y de forma periódica:
dbt-ol runmaterializa todos los modelos y emite eventos OpenLineage a Entropy Datadbt testejecuta todos los tests de esquema y los tests de datos personalizados- Se publican el producto de datos y el Data Contract en Entropy Data
datacontract testejecuta los tests de contrato contra el Output Port
Para esto usamos un workflow de GitHub Actions:
# .github/workflows/data-product.yml
name: Customer Activity Data Product
on:
push:
branches: [main]
schedule:
- cron: "0 6 * * *"
env:
API: https://api.entropy-data.com/api
DBT_DATABRICKS_HOST: ${{ secrets.DBT_DATABRICKS_HOST }}
DBT_DATABRICKS_HTTP_PATH: ${{ secrets.DBT_DATABRICKS_HTTP_PATH }}
DBT_DATABRICKS_TOKEN: ${{ secrets.DBT_DATABRICKS_TOKEN }}
DATACONTRACT_DATABRICKS_TOKEN: ${{ secrets.DBT_DATABRICKS_TOKEN }}
DATACONTRACT_DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DBT_DATABRICKS_HOST }}
DATACONTRACT_DATABRICKS_HTTP_PATH: ${{ secrets.DBT_DATABRICKS_HTTP_PATH }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install dbt-databricks openlineage-dbt datacontract-cli[databricks] entropy-data
- name: Create profiles.yml
run: |
mkdir -p ~/.dbt
cat > ~/.dbt/profiles.yml <<EOF
dp_entropydata_customer_activity:
target: prod
outputs:
prod:
type: databricks
catalog: entropy_data_prod
schema: dp_entropydata_customer_activity
host: ${DBT_DATABRICKS_HOST}
http_path: ${DBT_DATABRICKS_HTTP_PATH}
token: ${DBT_DATABRICKS_TOKEN}
threads: 4
EOF
- name: dbt deps
run: dbt deps
- name: dbt run
run: dbt-ol run --target prod
env:
OPENLINEAGE__TRANSPORT__AUTH__APIKEY: ${{ secrets.ENTROPY_DATA_API_KEY }}
- name: dbt test
run: dbt test --target prod
- name: Publish data product
run: entropy-data dataproducts put dp_entropydata_customer_activity --file dp_entropydata_customer_activity.odps.yaml
env:
ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}
- name: Publish data contract
run: entropy-data datacontracts put entropydata-customer-activity-v1 --file models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml
env:
ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}
- name: Data contract test
run: |
datacontract test models/output_ports/v1/entropydata-customer-activity-v1.odcs.yaml \
--server production \
--publish $API/test-results
env:
ENTROPY_DATA_API_KEY: ${{ secrets.ENTROPY_DATA_API_KEY }}
dbt-ol run materializa los modelos y envía los eventos OpenLineage a Entropy Data; dbt test ejecuta los tests unitarios.
Después se publican los metadatos del producto de datos y del Data Contract con la CLI entropy-data, que envuelve la API REST de la plataforma y lee la API key de la variable de entorno ENTROPY_DATA_API_KEY.
Por último, datacontract test valida el Output Port desde la perspectiva del Data Consumer.
Entropy Data
Entropy Data es un marketplace de productos de datos que gestiona productos de datos, Data Contracts y solicitudes de acceso. Se integra sin fricción para ofrecer una experiencia completa de producto de datos:
- Descubrimiento: los Data Consumers exploran y encuentran productos de datos en un marketplace self-service
- Gestión de accesos: los Data Consumers solicitan acceso y las aprobaciones pueden disparar el aprovisionamiento RBAC en la plataforma de datos
- Gobernanza: seguimiento de la propiedad, la calidad y el data lineage en todos los productos de datos
Así se ve nuestro producto de datos Customer Activity en el marketplace de Entropy Data:
Usa el Data Product Builder para implementarlo con coding agents
Toda la estructura descrita en este artículo (la organización del proyecto dbt, los contratos de Input Port y Output Port, el workflow de CI, la publicación de data lineage y de resultados de tests) se puede generar automáticamente con el Data Product Builder.
Empieza por un Data Contract. Pásaselo a Claude Code, OpenAI Codex o GitHub Copilot CLI. El agente genera exactamente este proyecto dbt, rellena los modelos, prepara los tests, configura el workflow de despliegue y cablea la integración con Entropy Data. La estructura sigue siendo personalizable: si prefieres Airflow en lugar de GitHub Actions, o convenciones de nombres distintas, haz un fork de la plantilla y el agente usará tu fork.
Esta página explica qué produce ese esqueleto, cómo encaja cada pieza y cómo ampliarlo con las convenciones de tu organización.
Valor de negocio
Con este producto de datos en marcha, nuestro equipo de customer success (que en realidad son nuestros co-founders...) puede consultar la tabla customer_activity directamente en Databricks para entender el nivel de actividad de cada cliente:
cuántos usuarios tiene, si está añadiendo productos de datos de forma activa y qué plataforma de datos usa.
Eso permite contactar de forma proactiva con los clientes que están creciendo, detectar pronto las cuentas inactivas y priorizar el soporte con datos.
Sirve además de apoyo a las actividades de CRM y alimenta agentes de IA que identifican de forma proactiva dónde podemos ayudar a los clientes a construir mejores productos de datos o a montar integraciones.
El Data Contract garantiza el esquema y la calidad, así que pueden construir dashboards, agentes y automatizaciones encima con total confianza.
Regístrate gratis ahora o explora la demo interactiva de Entropy Data.