Appearance
Integración SAP → BigQuery → Acoustic Connect
🎯 Objetivo general
Establecer un flujo de integración que permita utilizar los datos replicados desde SAP S/4HANA (vía Aercorsoft) hacia BigQuery, y preparar dichos datos para su conexión con Acoustic Connect, garantizando gobierno, trazabilidad y cumplimiento normativo.
🧱 Situación actual
- Proyecto:
minuto-verde-cortex-poc - Dataset origen:
CDC_SAP - Fuente: replicación de SAP S/4HANA vía Aercorsoft
- Tablas disponibles:
acdoca, adr6, adrc, adrct, adrt, afko, afpo, aufk, bkpf, bsad_bck, bseg, but000, but020, cepc, cepct, ckmlcr, ckmlhd, csks, cskt, dd03l, ekbe, ekes, eket, ekkn, ekko, ekpo, finsc_ld_cmp, finsc_ledger, finsc_ledger_rep, finsc_ledger_t, hrrp_directory, hrrp_node, hrrp_nodet, jest, kna1, knb1, knvp, knvv, lfa1, likp, lips, makt, mara, marc, mard, mast, matdoc, mbew, mbewh, mch1, mcha, mkol, mska, msku, mslb, prcd_elements, rbco, rbkp, rseg, sethanahier0101, sethanahier0106, setheader, setheadert, setleaf, setnode, ska1, skat, stas, stko, stpo, t001, t001k, t001l, t001w, t002, t005, t005k, t005s, t005t, t006, t006a, t006t, t009, t009b, t023, t023t, t024, t024e, t134, t134t, t148t, t156t, t157e, t161, t161t, t179, t179t, t881, t881t, tcurc, tcurf, tcurr, tcurt, tcurx, temp_bseg251010130509_13, tj02t, tka02, tspa, tspat, tvarvc, tvfst, tvko, tvkot, tvlst, tvtw, tvtwt, vbak, vbap, vbep, vbfa, vbpa, vbrk, vbrp.
🧩 Estrategia de arquitectura en BigQuery
Capas recomendadas
| Capa | Descripción | Ejemplo |
|---|---|---|
| Raw (bronze) | Datos replicados directamente desde SAP (solo lectura, sin transformación). | CDC_SAP (ya existe) |
| Curado / Marketing (gold) | Dataset con vistas transformadas y unificadas, listas para exportar a Acoustic. | mkt_curated |
Evita duplicar datos: usa vistas (
CREATE VIEW) sobreCDC_SAPy sólo materializa tablas cuando sea necesario para exportación o delta.
🧾 Estructura de datasets y vistas
Creación de un nuevo dataset curado:
sql
CREATE SCHEMA IF NOT EXISTS `minuto-verde-cortex-poc.mkt_curated`;
Base de clientes (KNA1 + ADR6 + ADRC)
Usa los datos maestros de clientes (kna1), correos electrónicos (adr6) y direcciones (adrc):
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_base_v` AS
SELECT
SAFE_CAST(k.kunnr AS STRING) AS customer_id,
LOWER(TRIM(a6.smtp_addr)) AS email,
TRIM(k.name1) AS first_name,
TRIM(k.name2) AS last_name,
TRIM(k.telf1) AS phone,
TRIM(addr.nation) AS country,
TRIM(addr.region) AS region,
TRIM(addr.city1) AS city,
TRIM(addr.street) AS address,
SAFE_CAST(k.erdat AS DATE) AS created_at,
IFNULL(k.sperr, '') AS status_raw
FROM `minuto-verde-cortex-poc.CDC_SAP.kna1` k
LEFT JOIN `minuto-verde-cortex-poc.CDC_SAP.adr6` a6
ON a6.addrnumber = k.adrnr
LEFT JOIN `minuto-verde-cortex-poc.CDC_SAP.adrc` addr
ON addr.addrnumber = k.adrnr;
Datos comerciales y financieros
Organización de ventas (knvv):
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_sales_v` AS
SELECT
SAFE_CAST(kunnr AS STRING) AS customer_id,
vkorg, vtweg, spart, kdgrp, konda
FROM `minuto-verde-cortex-poc.CDC_SAP.knvv`;
Datos contables (knb1):
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_finance_v` AS
SELECT
SAFE_CAST(kunnr AS STRING) AS customer_id,
bukrs, zterm, loevm
FROM `minuto-verde-cortex-poc.CDC_SAP.knb1`;
Comportamiento y KPIs
Actividad financiera (bkpf + bseg)
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_behavior_fin_v` AS
WITH ar AS (
SELECT
SAFE_CAST(bseg.kunnr AS STRING) AS customer_id,
MAX(bkpf.budat) AS last_doc_date,
COUNT(*) AS ar_postings,
SUM(CAST(bseg.dmbtr AS NUMERIC)) AS total_amount_local
FROM `minuto-verde-cortex-poc.CDC_SAP.bseg` bseg
JOIN `minuto-verde-cortex-poc.CDC_SAP.bkpf` bkpf
ON bkpf.bukrs = bseg.bukrs
AND bkpf.gjahr = bseg.gjahr
AND bkpf.belnr = bseg.belnr
WHERE bseg.koart = 'D'
GROUP BY customer_id
)
SELECT * FROM ar;
Entregas (likp + lips)
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_behavior_deliv_v` AS
WITH deliv AS (
SELECT
SAFE_CAST(likp.kunnr AS STRING) AS customer_id,
MAX(likp.erdat) AS last_delivery_date,
COUNT(DISTINCT likp.vbeln) AS deliveries_count
FROM `minuto-verde-cortex-poc.CDC_SAP.likp` likp
GROUP BY customer_id
)
SELECT * FROM deliv;
Datos de consentimiento (opt-in)
Como no existen tablas de consentimiento en SAP, se crea una tabla de control:
sql
CREATE OR REPLACE TABLE `minuto-verde-cortex-poc.mkt_curated.customer_consent` (
customer_id STRING NOT NULL,
consent_email BOOL NOT NULL,
consent_date TIMESTAMP,
source_system STRING
);
(Puede poblarse desde CRM, web forms o sistemas externos.)
Vista final para Acoustic Connect
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.acoustic_profiles_v` AS
SELECT
b.email AS Email,
b.first_name AS FirstName,
b.last_name AS LastName,
b.customer_id AS CustomerID,
b.phone AS Phone,
b.country AS Country,
b.region AS Region,
b.city AS City,
b.address AS Address,
b.created_at AS CreatedAt,
COALESCE(c.consent_email, FALSE) AS Consent,
c.consent_date AS ConsentDate,
c.source_system AS SourceSystem,
f.last_doc_date AS LastDocDate_AR,
f.ar_postings AS ARPostings,
f.total_amount_local AS TotalAmountLocal,
d.last_delivery_date AS LastDeliveryDate,
d.deliveries_count AS DeliveriesCount
FROM `minuto-verde-cortex-poc.mkt_curated.customers_base_v` b
LEFT JOIN `minuto-verde-cortex-poc.mkt_curated.customer_consent` c
ON c.customer_id = b.customer_id
LEFT JOIN `minuto-verde-cortex-poc.mkt_curated.customers_behavior_fin_v` f
ON f.customer_id = b.customer_id
LEFT JOIN `minuto-verde-cortex-poc.mkt_curated.customers_behavior_deliv_v` d
ON d.customer_id = b.customer_id;
Exportación a Acoustic Connect
Opción A — CSV en Cloud Storage
sql
EXPORT DATA OPTIONS(
uri='gs://minuto-verde-data/acoustic/acoustic_profiles_*.csv',
format='CSV',
overwrite=true
) AS
SELECT * FROM `minuto-verde-cortex-poc.mkt_curated.acoustic_profiles_v`
WHERE Email IS NOT NULL;
Opción B — API upsert (flujo continuo)
- Usa Cloud Functions o Cloud Run para leer los cambios de
acoustic_profiles_v. - Envía los datos al endpoint de Acoustic (
/api/importContactso similar).
Consideraciones técnicas y de gobierno
- Particiona tablas materializadas por
run_tsomodified_at. - Clusteriza por
EmailoCustomerIDpara mejorar rendimiento. - Normaliza emails con
LOWER(TRIM(email)). - Deduplica con
ROW_NUMBER() OVER(PARTITION BY email ORDER BY modified_at DESC). - Enmascara PII con Data Catalog o políticas de acceso por columna.
- Usa Scheduled Queries o Cloud Composer para orquestación.
Siguientes pasos
- Confirmar el campo o fuente real de email (
ADR6,Z_EMAIL, CRM). - Validar los IDs de cliente (
KUNNR) y su correspondencia en BigQuery. - Poblar tabla
customer_consentcon datos de opt-in. - Crear vista final
acoustic_profiles_v. - Testear exportación a Acoustic (CSV o API).
💡 Nota técnica
En este entorno, las tablas replicadas de SAP se encuentran dentro del dataset CDC_SAP (en mayúsculas), mientras que los datasets creados manualmente (mkt_curated) se mantienen en minúsculas.
BigQuery puede diferenciar mayúsculas y minúsculas cuando los objetos fueron creados con comillas dobles en el DDL de origen (como hace Aercorsoft), por lo que se deben consultar respetando el case exacto.
📘 Anexo técnico: Vista mkt_curated
Para el detalle técnico completo de la vista base de clientes (estructura, origen de datos, limpieza y propósito dentro del flujo curado), consulta el documento: