[{"data":1,"prerenderedAt":3153},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fes\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack":13},{"i18nKey":4,"paths":5},"data-002-2026-06",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fdbt-bigquery-moderner-marketing-data-stack","\u002Fen\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","\u002Fes\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","\u002Ffr\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","\u002Fit\u002Fdata\u002Fdbt-bigquery-modern-pazarlama-data-stack","\u002Fru\u002Fdata\u002Fdbt-bigquery-sovremenniy-marketing-data-stack","\u002Ftr\u002Fdata\u002Fdbt-bigquery-ile-modern-pazarlama-data-stack",{"_path":8,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":3147,"_id":3148,"_source":3149,"_file":3150,"_stem":3151,"_extension":3152},"data",false,"","dbt + BigQuery: Modern Stack de Datos para Marketing","Desde el mapeo de fuentes hasta la semantic layer: cómo convertir datos de marketing en decisiones. Modelado con dbt, definiciones de KPI y arquitectura de pipeline en producción.","2026-06-14",[21,22,23,24,25],"dbt","bigquery","data-modeling","semantic-layer","marketing-analytics",8,"Roibase",{"type":29,"children":30,"toc":3137},"root",[31,39,46,84,350,379,400,406,419,702,715,1044,1103,1109,1121,1484,1489,1521,1527,1547,1751,1779,1792,1899,1904,1910,1923,2200,2213,2226,2488,2509,2515,2520,2773,2778,2791,2965,2970,2976,2988,2993,2998,3101,3106,3112,3131],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":37,"value":38},"text","Los equipos de marketing en 2026 no luchan contra los datos; toman decisiones basadas en datos. GA4, Meta Ads, Google Ads, CRM, CDP, server-side GTM — cada uno deja caer información en tablas separadas. El equipo está armando spreadsheets manualmente, los números cambian cada semana, nadie confía en nada. Este caos desaparece con un stack de datos moderno: BigQuery como fuente, capa de transformación con dbt, semantic layer como red de indicadores. Versionas el código en repositorio, cada cambio se prueba, las métricas vienen de una única fuente de verdad. Este artículo muestra cómo dbt + BigQuery convierte el pipeline de datos de marketing en algo production-grade.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"mapeo-de-fuentes-estandarizar-rutas-de-datos-crudos",[44],{"type":37,"value":45},"Mapeo de fuentes: Estandarizar rutas de datos crudos",{"type":32,"tag":33,"props":47,"children":48},{},[49,51,58,60,66,68,74,76,82],{"type":37,"value":50},"La primera tarea de dbt es mapear fuentes — ajustar datos crudos de sistemas diferentes al mismo esquema. En BigQuery, la tabla ",{"type":32,"tag":52,"props":53,"children":55},"code",{"className":54},[],[56],{"type":37,"value":57},"analytics_123456.events_*",{"type":37,"value":59}," viene de GA4, ",{"type":32,"tag":52,"props":61,"children":63},{"className":62},[],[64],{"type":37,"value":65},"facebook_ads.ads_insights",{"type":37,"value":67}," de la API de Meta, ",{"type":32,"tag":52,"props":69,"children":71},{"className":70},[],[72],{"type":37,"value":73},"crm.transactions",{"type":37,"value":75}," de Shopify. Cada una tiene formato de timestamp diferente, identificador de usuario distinto, columna de moneda propia. En el archivo ",{"type":32,"tag":52,"props":77,"children":79},{"className":78},[],[80],{"type":37,"value":81},"sources.yml",{"type":37,"value":83}," de dbt defines estas tablas crudas:",{"type":32,"tag":85,"props":86,"children":90},"pre",{"className":87,"code":88,"language":89,"meta":16,"style":16},"language-yaml shiki shiki-themes github-dark","version: 2\nsources:\n  - name: ga4\n    database: analytics_123456\n    tables:\n      - name: events_\n        identifier: \"events_*\"\n        loaded_at_field: event_timestamp\n  - name: meta_ads\n    database: facebook_ads\n    schema: public\n    tables:\n      - name: ads_insights\n        loaded_at_field: date_start\n","yaml",[91],{"type":32,"tag":52,"props":92,"children":93},{"__ignoreMap":16},[94,118,132,156,174,187,209,227,244,265,282,300,312,333],{"type":32,"tag":95,"props":96,"children":99},"span",{"class":97,"line":98},"line",1,[100,106,112],{"type":32,"tag":95,"props":101,"children":103},{"style":102},"--shiki-default:#85E89D",[104],{"type":37,"value":105},"version",{"type":32,"tag":95,"props":107,"children":109},{"style":108},"--shiki-default:#E1E4E8",[110],{"type":37,"value":111},": ",{"type":32,"tag":95,"props":113,"children":115},{"style":114},"--shiki-default:#79B8FF",[116],{"type":37,"value":117},"2\n",{"type":32,"tag":95,"props":119,"children":121},{"class":97,"line":120},2,[122,127],{"type":32,"tag":95,"props":123,"children":124},{"style":102},[125],{"type":37,"value":126},"sources",{"type":32,"tag":95,"props":128,"children":129},{"style":108},[130],{"type":37,"value":131},":\n",{"type":32,"tag":95,"props":133,"children":135},{"class":97,"line":134},3,[136,141,146,150],{"type":32,"tag":95,"props":137,"children":138},{"style":108},[139],{"type":37,"value":140},"  - ",{"type":32,"tag":95,"props":142,"children":143},{"style":102},[144],{"type":37,"value":145},"name",{"type":32,"tag":95,"props":147,"children":148},{"style":108},[149],{"type":37,"value":111},{"type":32,"tag":95,"props":151,"children":153},{"style":152},"--shiki-default:#9ECBFF",[154],{"type":37,"value":155},"ga4\n",{"type":32,"tag":95,"props":157,"children":159},{"class":97,"line":158},4,[160,165,169],{"type":32,"tag":95,"props":161,"children":162},{"style":102},[163],{"type":37,"value":164},"    database",{"type":32,"tag":95,"props":166,"children":167},{"style":108},[168],{"type":37,"value":111},{"type":32,"tag":95,"props":170,"children":171},{"style":152},[172],{"type":37,"value":173},"analytics_123456\n",{"type":32,"tag":95,"props":175,"children":177},{"class":97,"line":176},5,[178,183],{"type":32,"tag":95,"props":179,"children":180},{"style":102},[181],{"type":37,"value":182},"    tables",{"type":32,"tag":95,"props":184,"children":185},{"style":108},[186],{"type":37,"value":131},{"type":32,"tag":95,"props":188,"children":190},{"class":97,"line":189},6,[191,196,200,204],{"type":32,"tag":95,"props":192,"children":193},{"style":108},[194],{"type":37,"value":195},"      - ",{"type":32,"tag":95,"props":197,"children":198},{"style":102},[199],{"type":37,"value":145},{"type":32,"tag":95,"props":201,"children":202},{"style":108},[203],{"type":37,"value":111},{"type":32,"tag":95,"props":205,"children":206},{"style":152},[207],{"type":37,"value":208},"events_\n",{"type":32,"tag":95,"props":210,"children":212},{"class":97,"line":211},7,[213,218,222],{"type":32,"tag":95,"props":214,"children":215},{"style":102},[216],{"type":37,"value":217},"        identifier",{"type":32,"tag":95,"props":219,"children":220},{"style":108},[221],{"type":37,"value":111},{"type":32,"tag":95,"props":223,"children":224},{"style":152},[225],{"type":37,"value":226},"\"events_*\"\n",{"type":32,"tag":95,"props":228,"children":229},{"class":97,"line":26},[230,235,239],{"type":32,"tag":95,"props":231,"children":232},{"style":102},[233],{"type":37,"value":234},"        loaded_at_field",{"type":32,"tag":95,"props":236,"children":237},{"style":108},[238],{"type":37,"value":111},{"type":32,"tag":95,"props":240,"children":241},{"style":152},[242],{"type":37,"value":243},"event_timestamp\n",{"type":32,"tag":95,"props":245,"children":247},{"class":97,"line":246},9,[248,252,256,260],{"type":32,"tag":95,"props":249,"children":250},{"style":108},[251],{"type":37,"value":140},{"type":32,"tag":95,"props":253,"children":254},{"style":102},[255],{"type":37,"value":145},{"type":32,"tag":95,"props":257,"children":258},{"style":108},[259],{"type":37,"value":111},{"type":32,"tag":95,"props":261,"children":262},{"style":152},[263],{"type":37,"value":264},"meta_ads\n",{"type":32,"tag":95,"props":266,"children":268},{"class":97,"line":267},10,[269,273,277],{"type":32,"tag":95,"props":270,"children":271},{"style":102},[272],{"type":37,"value":164},{"type":32,"tag":95,"props":274,"children":275},{"style":108},[276],{"type":37,"value":111},{"type":32,"tag":95,"props":278,"children":279},{"style":152},[280],{"type":37,"value":281},"facebook_ads\n",{"type":32,"tag":95,"props":283,"children":285},{"class":97,"line":284},11,[286,291,295],{"type":32,"tag":95,"props":287,"children":288},{"style":102},[289],{"type":37,"value":290},"    schema",{"type":32,"tag":95,"props":292,"children":293},{"style":108},[294],{"type":37,"value":111},{"type":32,"tag":95,"props":296,"children":297},{"style":152},[298],{"type":37,"value":299},"public\n",{"type":32,"tag":95,"props":301,"children":303},{"class":97,"line":302},12,[304,308],{"type":32,"tag":95,"props":305,"children":306},{"style":102},[307],{"type":37,"value":182},{"type":32,"tag":95,"props":309,"children":310},{"style":108},[311],{"type":37,"value":131},{"type":32,"tag":95,"props":313,"children":315},{"class":97,"line":314},13,[316,320,324,328],{"type":32,"tag":95,"props":317,"children":318},{"style":108},[319],{"type":37,"value":195},{"type":32,"tag":95,"props":321,"children":322},{"style":102},[323],{"type":37,"value":145},{"type":32,"tag":95,"props":325,"children":326},{"style":108},[327],{"type":37,"value":111},{"type":32,"tag":95,"props":329,"children":330},{"style":152},[331],{"type":37,"value":332},"ads_insights\n",{"type":32,"tag":95,"props":334,"children":336},{"class":97,"line":335},14,[337,341,345],{"type":32,"tag":95,"props":338,"children":339},{"style":102},[340],{"type":37,"value":234},{"type":32,"tag":95,"props":342,"children":343},{"style":108},[344],{"type":37,"value":111},{"type":32,"tag":95,"props":346,"children":347},{"style":152},[348],{"type":37,"value":349},"date_start\n",{"type":32,"tag":33,"props":351,"children":352},{},[353,355,361,363,369,371,377],{"type":37,"value":354},"Esta definición le dice a dbt \"estas tablas vienen de upstream, yo no las toco pero pruebo su frescura\". El comando ",{"type":32,"tag":52,"props":356,"children":358},{"className":357},[],[359],{"type":37,"value":360},"dbt source freshness",{"type":37,"value":362}," verifica cuándo llegó el último dato — si la API de Meta se retrasa, genera alertas. Sin mapeo de fuentes, cada modelo escribe directo ",{"type":32,"tag":52,"props":364,"children":366},{"className":365},[],[367],{"type":37,"value":368},"SELECT * FROM analytics_123456.events_20260614",{"type":37,"value":370},", y cuando el nombre de tabla cambia, 40 modelos se rompen. Con mapping, la referencia es ",{"type":32,"tag":52,"props":372,"children":374},{"className":373},[],[375],{"type":37,"value":376},"{{ source('ga4', 'events_') }}",{"type":37,"value":378},", el cambio se propaga desde un único punto.",{"type":32,"tag":33,"props":380,"children":381},{},[382,384,390,392,398],{"type":37,"value":383},"GA4 usa event_timestamp en microsegundos Unix, Meta Ads usa date_start en string ISO, CRM usa created_at en datetime UTC — cada formato diferente. En el mapeo de fuentes, extraes una columna timestamp estándar: ",{"type":32,"tag":52,"props":385,"children":387},{"className":386},[],[388],{"type":37,"value":389},"TIMESTAMP_MICROS(event_timestamp) AS event_time",{"type":37,"value":391}," en GA4, ",{"type":32,"tag":52,"props":393,"children":395},{"className":394},[],[396],{"type":37,"value":397},"PARSE_TIMESTAMP('%Y-%m-%d', date_start) AS event_time",{"type":37,"value":399}," en Meta. Esta normalización proporciona entrada limpia a los modelos downstream.",{"type":32,"tag":40,"props":401,"children":403},{"id":402},"capa-de-modelado-staging-intermediate-mart",[404],{"type":37,"value":405},"Capa de modelado: Staging, intermediate, mart",{"type":32,"tag":33,"props":407,"children":408},{},[409,411,417],{"type":37,"value":410},"La potencia de dbt está en el modelado en capas — staging, intermediate, mart. Los modelos de staging extraen 1:1 de la fuente, solo hacen renombrado y casting de tipos. ",{"type":32,"tag":52,"props":412,"children":414},{"className":413},[],[415],{"type":37,"value":416},"stg_ga4_events.sql",{"type":37,"value":418},":",{"type":32,"tag":85,"props":420,"children":424},{"className":421,"code":422,"language":423,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","SELECT\n  TIMESTAMP_MICROS(event_timestamp) AS event_time,\n  user_pseudo_id AS anonymous_id,\n  event_name,\n  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'session_id') AS session_id,\n  geo.country,\n  device.category AS device_category\nFROM {{ source('ga4', 'events_') }}\nWHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY))\n  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n","sql",[425],{"type":32,"tag":52,"props":426,"children":427},{"__ignoreMap":16},[428,437,455,472,480,552,574,601,634,681],{"type":32,"tag":95,"props":429,"children":430},{"class":97,"line":98},[431],{"type":32,"tag":95,"props":432,"children":434},{"style":433},"--shiki-default:#F97583",[435],{"type":37,"value":436},"SELECT\n",{"type":32,"tag":95,"props":438,"children":439},{"class":97,"line":120},[440,445,450],{"type":32,"tag":95,"props":441,"children":442},{"style":108},[443],{"type":37,"value":444},"  TIMESTAMP_MICROS(event_timestamp) ",{"type":32,"tag":95,"props":446,"children":447},{"style":433},[448],{"type":37,"value":449},"AS",{"type":32,"tag":95,"props":451,"children":452},{"style":108},[453],{"type":37,"value":454}," event_time,\n",{"type":32,"tag":95,"props":456,"children":457},{"class":97,"line":134},[458,463,467],{"type":32,"tag":95,"props":459,"children":460},{"style":108},[461],{"type":37,"value":462},"  user_pseudo_id ",{"type":32,"tag":95,"props":464,"children":465},{"style":433},[466],{"type":37,"value":449},{"type":32,"tag":95,"props":468,"children":469},{"style":108},[470],{"type":37,"value":471}," anonymous_id,\n",{"type":32,"tag":95,"props":473,"children":474},{"class":97,"line":158},[475],{"type":32,"tag":95,"props":476,"children":477},{"style":108},[478],{"type":37,"value":479},"  event_name,\n",{"type":32,"tag":95,"props":481,"children":482},{"class":97,"line":176},[483,488,493,498,503,508,513,518,523,528,533,538,543,547],{"type":32,"tag":95,"props":484,"children":485},{"style":108},[486],{"type":37,"value":487},"  (",{"type":32,"tag":95,"props":489,"children":490},{"style":433},[491],{"type":37,"value":492},"SELECT",{"type":32,"tag":95,"props":494,"children":495},{"style":114},[496],{"type":37,"value":497}," value",{"type":32,"tag":95,"props":499,"children":500},{"style":108},[501],{"type":37,"value":502},".",{"type":32,"tag":95,"props":504,"children":505},{"style":114},[506],{"type":37,"value":507},"string_value",{"type":32,"tag":95,"props":509,"children":510},{"style":433},[511],{"type":37,"value":512}," FROM",{"type":32,"tag":95,"props":514,"children":515},{"style":108},[516],{"type":37,"value":517}," UNNEST(event_params) ",{"type":32,"tag":95,"props":519,"children":520},{"style":433},[521],{"type":37,"value":522},"WHERE",{"type":32,"tag":95,"props":524,"children":525},{"style":433},[526],{"type":37,"value":527}," key",{"type":32,"tag":95,"props":529,"children":530},{"style":433},[531],{"type":37,"value":532}," =",{"type":32,"tag":95,"props":534,"children":535},{"style":152},[536],{"type":37,"value":537}," 'session_id'",{"type":32,"tag":95,"props":539,"children":540},{"style":108},[541],{"type":37,"value":542},") ",{"type":32,"tag":95,"props":544,"children":545},{"style":433},[546],{"type":37,"value":449},{"type":32,"tag":95,"props":548,"children":549},{"style":108},[550],{"type":37,"value":551}," session_id,\n",{"type":32,"tag":95,"props":553,"children":554},{"class":97,"line":189},[555,560,564,569],{"type":32,"tag":95,"props":556,"children":557},{"style":114},[558],{"type":37,"value":559},"  geo",{"type":32,"tag":95,"props":561,"children":562},{"style":108},[563],{"type":37,"value":502},{"type":32,"tag":95,"props":565,"children":566},{"style":114},[567],{"type":37,"value":568},"country",{"type":32,"tag":95,"props":570,"children":571},{"style":108},[572],{"type":37,"value":573},",\n",{"type":32,"tag":95,"props":575,"children":576},{"class":97,"line":211},[577,582,586,591,596],{"type":32,"tag":95,"props":578,"children":579},{"style":114},[580],{"type":37,"value":581},"  device",{"type":32,"tag":95,"props":583,"children":584},{"style":108},[585],{"type":37,"value":502},{"type":32,"tag":95,"props":587,"children":588},{"style":114},[589],{"type":37,"value":590},"category",{"type":32,"tag":95,"props":592,"children":593},{"style":433},[594],{"type":37,"value":595}," AS",{"type":32,"tag":95,"props":597,"children":598},{"style":108},[599],{"type":37,"value":600}," device_category\n",{"type":32,"tag":95,"props":602,"children":603},{"class":97,"line":26},[604,609,614,619,624,629],{"type":32,"tag":95,"props":605,"children":606},{"style":433},[607],{"type":37,"value":608},"FROM",{"type":32,"tag":95,"props":610,"children":611},{"style":108},[612],{"type":37,"value":613}," {{ source(",{"type":32,"tag":95,"props":615,"children":616},{"style":152},[617],{"type":37,"value":618},"'ga4'",{"type":32,"tag":95,"props":620,"children":621},{"style":108},[622],{"type":37,"value":623},", ",{"type":32,"tag":95,"props":625,"children":626},{"style":152},[627],{"type":37,"value":628},"'events_'",{"type":32,"tag":95,"props":630,"children":631},{"style":108},[632],{"type":37,"value":633},") }}\n",{"type":32,"tag":95,"props":635,"children":636},{"class":97,"line":246},[637,641,646,651,656,661,666,671,676],{"type":32,"tag":95,"props":638,"children":639},{"style":433},[640],{"type":37,"value":522},{"type":32,"tag":95,"props":642,"children":643},{"style":108},[644],{"type":37,"value":645}," _TABLE_SUFFIX ",{"type":32,"tag":95,"props":647,"children":648},{"style":433},[649],{"type":37,"value":650},"BETWEEN",{"type":32,"tag":95,"props":652,"children":653},{"style":108},[654],{"type":37,"value":655}," FORMAT_DATE(",{"type":32,"tag":95,"props":657,"children":658},{"style":152},[659],{"type":37,"value":660},"'%Y%m%d'",{"type":32,"tag":95,"props":662,"children":663},{"style":108},[664],{"type":37,"value":665},", DATE_SUB(CURRENT_DATE(), INTERVAL ",{"type":32,"tag":95,"props":667,"children":668},{"style":114},[669],{"type":37,"value":670},"90",{"type":32,"tag":95,"props":672,"children":673},{"style":433},[674],{"type":37,"value":675}," DAY",{"type":32,"tag":95,"props":677,"children":678},{"style":108},[679],{"type":37,"value":680},"))\n",{"type":32,"tag":95,"props":682,"children":683},{"class":97,"line":267},[684,689,693,697],{"type":32,"tag":95,"props":685,"children":686},{"style":433},[687],{"type":37,"value":688},"  AND",{"type":32,"tag":95,"props":690,"children":691},{"style":108},[692],{"type":37,"value":655},{"type":32,"tag":95,"props":694,"children":695},{"style":152},[696],{"type":37,"value":660},{"type":32,"tag":95,"props":698,"children":699},{"style":108},[700],{"type":37,"value":701},", CURRENT_DATE())\n",{"type":32,"tag":33,"props":703,"children":704},{},[705,707,713],{"type":37,"value":706},"El staging proporciona datos limpios pero sin lógica de negocio. Los modelos intermediate agregan lógica de negocio: sesionización, atribución, pasos de funnel. En ",{"type":32,"tag":52,"props":708,"children":710},{"className":709},[],[711],{"type":37,"value":712},"int_sessions.sql",{"type":37,"value":714}," agrupas eventos de GA4 por sesión:",{"type":32,"tag":85,"props":716,"children":718},{"className":421,"code":717,"language":423,"meta":16,"style":16},"WITH session_events AS (\n  SELECT\n    session_id,\n    MIN(event_time) AS session_start,\n    MAX(event_time) AS session_end,\n    COUNT(DISTINCT CASE WHEN event_name = 'page_view' THEN event_time END) AS pageviews,\n    MAX(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) AS converted\n  FROM {{ ref('stg_ga4_events') }}\n  GROUP BY session_id\n)\nSELECT\n  *,\n  TIMESTAMP_DIFF(session_end, session_start, SECOND) AS duration_seconds\nFROM session_events\n",[719],{"type":32,"tag":52,"props":720,"children":721},{"__ignoreMap":16},[722,744,752,760,782,803,874,944,966,979,987,994,1006,1032],{"type":32,"tag":95,"props":723,"children":724},{"class":97,"line":98},[725,730,735,739],{"type":32,"tag":95,"props":726,"children":727},{"style":433},[728],{"type":37,"value":729},"WITH",{"type":32,"tag":95,"props":731,"children":732},{"style":108},[733],{"type":37,"value":734}," session_events ",{"type":32,"tag":95,"props":736,"children":737},{"style":433},[738],{"type":37,"value":449},{"type":32,"tag":95,"props":740,"children":741},{"style":108},[742],{"type":37,"value":743}," (\n",{"type":32,"tag":95,"props":745,"children":746},{"class":97,"line":120},[747],{"type":32,"tag":95,"props":748,"children":749},{"style":433},[750],{"type":37,"value":751},"  SELECT\n",{"type":32,"tag":95,"props":753,"children":754},{"class":97,"line":134},[755],{"type":32,"tag":95,"props":756,"children":757},{"style":108},[758],{"type":37,"value":759},"    session_id,\n",{"type":32,"tag":95,"props":761,"children":762},{"class":97,"line":158},[763,768,773,777],{"type":32,"tag":95,"props":764,"children":765},{"style":114},[766],{"type":37,"value":767},"    MIN",{"type":32,"tag":95,"props":769,"children":770},{"style":108},[771],{"type":37,"value":772},"(event_time) ",{"type":32,"tag":95,"props":774,"children":775},{"style":433},[776],{"type":37,"value":449},{"type":32,"tag":95,"props":778,"children":779},{"style":108},[780],{"type":37,"value":781}," session_start,\n",{"type":32,"tag":95,"props":783,"children":784},{"class":97,"line":176},[785,790,794,798],{"type":32,"tag":95,"props":786,"children":787},{"style":114},[788],{"type":37,"value":789},"    MAX",{"type":32,"tag":95,"props":791,"children":792},{"style":108},[793],{"type":37,"value":772},{"type":32,"tag":95,"props":795,"children":796},{"style":433},[797],{"type":37,"value":449},{"type":32,"tag":95,"props":799,"children":800},{"style":108},[801],{"type":37,"value":802}," session_end,\n",{"type":32,"tag":95,"props":804,"children":805},{"class":97,"line":189},[806,811,816,821,826,831,836,841,846,851,856,861,865,869],{"type":32,"tag":95,"props":807,"children":808},{"style":114},[809],{"type":37,"value":810},"    COUNT",{"type":32,"tag":95,"props":812,"children":813},{"style":108},[814],{"type":37,"value":815},"(",{"type":32,"tag":95,"props":817,"children":818},{"style":433},[819],{"type":37,"value":820},"DISTINCT",{"type":32,"tag":95,"props":822,"children":823},{"style":433},[824],{"type":37,"value":825}," CASE",{"type":32,"tag":95,"props":827,"children":828},{"style":433},[829],{"type":37,"value":830}," WHEN",{"type":32,"tag":95,"props":832,"children":833},{"style":108},[834],{"type":37,"value":835}," event_name ",{"type":32,"tag":95,"props":837,"children":838},{"style":433},[839],{"type":37,"value":840},"=",{"type":32,"tag":95,"props":842,"children":843},{"style":152},[844],{"type":37,"value":845}," 'page_view'",{"type":32,"tag":95,"props":847,"children":848},{"style":433},[849],{"type":37,"value":850}," THEN",{"type":32,"tag":95,"props":852,"children":853},{"style":108},[854],{"type":37,"value":855}," event_time ",{"type":32,"tag":95,"props":857,"children":858},{"style":433},[859],{"type":37,"value":860},"END",{"type":32,"tag":95,"props":862,"children":863},{"style":108},[864],{"type":37,"value":542},{"type":32,"tag":95,"props":866,"children":867},{"style":433},[868],{"type":37,"value":449},{"type":32,"tag":95,"props":870,"children":871},{"style":108},[872],{"type":37,"value":873}," pageviews,\n",{"type":32,"tag":95,"props":875,"children":876},{"class":97,"line":211},[877,881,885,890,894,898,902,907,911,916,921,926,931,935,939],{"type":32,"tag":95,"props":878,"children":879},{"style":114},[880],{"type":37,"value":789},{"type":32,"tag":95,"props":882,"children":883},{"style":108},[884],{"type":37,"value":815},{"type":32,"tag":95,"props":886,"children":887},{"style":433},[888],{"type":37,"value":889},"CASE",{"type":32,"tag":95,"props":891,"children":892},{"style":433},[893],{"type":37,"value":830},{"type":32,"tag":95,"props":895,"children":896},{"style":108},[897],{"type":37,"value":835},{"type":32,"tag":95,"props":899,"children":900},{"style":433},[901],{"type":37,"value":840},{"type":32,"tag":95,"props":903,"children":904},{"style":152},[905],{"type":37,"value":906}," 'purchase'",{"type":32,"tag":95,"props":908,"children":909},{"style":433},[910],{"type":37,"value":850},{"type":32,"tag":95,"props":912,"children":913},{"style":114},[914],{"type":37,"value":915}," 1",{"type":32,"tag":95,"props":917,"children":918},{"style":433},[919],{"type":37,"value":920}," ELSE",{"type":32,"tag":95,"props":922,"children":923},{"style":114},[924],{"type":37,"value":925}," 0",{"type":32,"tag":95,"props":927,"children":928},{"style":433},[929],{"type":37,"value":930}," END",{"type":32,"tag":95,"props":932,"children":933},{"style":108},[934],{"type":37,"value":542},{"type":32,"tag":95,"props":936,"children":937},{"style":433},[938],{"type":37,"value":449},{"type":32,"tag":95,"props":940,"children":941},{"style":108},[942],{"type":37,"value":943}," converted\n",{"type":32,"tag":95,"props":945,"children":946},{"class":97,"line":26},[947,952,957,962],{"type":32,"tag":95,"props":948,"children":949},{"style":433},[950],{"type":37,"value":951},"  FROM",{"type":32,"tag":95,"props":953,"children":954},{"style":108},[955],{"type":37,"value":956}," {{ ref(",{"type":32,"tag":95,"props":958,"children":959},{"style":152},[960],{"type":37,"value":961},"'stg_ga4_events'",{"type":32,"tag":95,"props":963,"children":964},{"style":108},[965],{"type":37,"value":633},{"type":32,"tag":95,"props":967,"children":968},{"class":97,"line":246},[969,974],{"type":32,"tag":95,"props":970,"children":971},{"style":433},[972],{"type":37,"value":973},"  GROUP BY",{"type":32,"tag":95,"props":975,"children":976},{"style":108},[977],{"type":37,"value":978}," session_id\n",{"type":32,"tag":95,"props":980,"children":981},{"class":97,"line":267},[982],{"type":32,"tag":95,"props":983,"children":984},{"style":108},[985],{"type":37,"value":986},")\n",{"type":32,"tag":95,"props":988,"children":989},{"class":97,"line":284},[990],{"type":32,"tag":95,"props":991,"children":992},{"style":433},[993],{"type":37,"value":436},{"type":32,"tag":95,"props":995,"children":996},{"class":97,"line":302},[997,1002],{"type":32,"tag":95,"props":998,"children":999},{"style":433},[1000],{"type":37,"value":1001},"  *",{"type":32,"tag":95,"props":1003,"children":1004},{"style":108},[1005],{"type":37,"value":573},{"type":32,"tag":95,"props":1007,"children":1008},{"class":97,"line":314},[1009,1014,1019,1023,1027],{"type":32,"tag":95,"props":1010,"children":1011},{"style":108},[1012],{"type":37,"value":1013},"  TIMESTAMP_DIFF(session_end, session_start, ",{"type":32,"tag":95,"props":1015,"children":1016},{"style":433},[1017],{"type":37,"value":1018},"SECOND",{"type":32,"tag":95,"props":1020,"children":1021},{"style":108},[1022],{"type":37,"value":542},{"type":32,"tag":95,"props":1024,"children":1025},{"style":433},[1026],{"type":37,"value":449},{"type":32,"tag":95,"props":1028,"children":1029},{"style":108},[1030],{"type":37,"value":1031}," duration_seconds\n",{"type":32,"tag":95,"props":1033,"children":1034},{"class":97,"line":335},[1035,1039],{"type":32,"tag":95,"props":1036,"children":1037},{"style":433},[1038],{"type":37,"value":608},{"type":32,"tag":95,"props":1040,"children":1041},{"style":108},[1042],{"type":37,"value":1043}," session_events\n",{"type":32,"tag":33,"props":1045,"children":1046},{},[1047,1049,1055,1057,1063,1064,1070,1071,1077,1079,1085,1087,1093,1095,1101],{"type":37,"value":1048},"Los modelos mart son la capa final de consumo — BI tool, Looker, dashboards internos miran aquí. ",{"type":32,"tag":52,"props":1050,"children":1052},{"className":1051},[],[1053],{"type":37,"value":1054},"fct_marketing_performance.sql",{"type":37,"value":1056}," une todos los canales, calcula spend + revenue + ROAS. Cada modelo mart se enfoca en una entidad de negocio única: ",{"type":32,"tag":52,"props":1058,"children":1060},{"className":1059},[],[1061],{"type":37,"value":1062},"dim_customers",{"type":37,"value":623},{"type":32,"tag":52,"props":1065,"children":1067},{"className":1066},[],[1068],{"type":37,"value":1069},"fct_orders",{"type":37,"value":623},{"type":32,"tag":52,"props":1072,"children":1074},{"className":1073},[],[1075],{"type":37,"value":1076},"fct_sessions",{"type":37,"value":1078},". La convención de nombres es crítica — ",{"type":32,"tag":52,"props":1080,"children":1082},{"className":1081},[],[1083],{"type":37,"value":1084},"dim_",{"type":37,"value":1086}," para dimensión (cliente, producto), ",{"type":32,"tag":52,"props":1088,"children":1090},{"className":1089},[],[1091],{"type":37,"value":1092},"fct_",{"type":37,"value":1094}," para hecho (transacción, evento), ",{"type":32,"tag":52,"props":1096,"children":1098},{"className":1097},[],[1099],{"type":37,"value":1100},"rpt_",{"type":37,"value":1102}," para reporte agregado.",{"type":32,"tag":40,"props":1104,"children":1106},{"id":1105},"semantic-layer-definiciones-de-kpi-como-código",[1107],{"type":37,"value":1108},"Semantic layer: Definiciones de KPI como código",{"type":32,"tag":33,"props":1110,"children":1111},{},[1112,1114,1120],{"type":37,"value":1113},"La semantic layer lleva definiciones de métricas dentro de dbt — qué es \"revenue\", cómo se calcula \"CAC\" ya no está en spreadsheet sino en YAML. Con dbt v1.6+ defines el árbol de indicadores en ",{"type":32,"tag":52,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":37,"value":1119},"metrics.yml",{"type":37,"value":418},{"type":32,"tag":85,"props":1122,"children":1124},{"className":87,"code":1123,"language":89,"meta":16,"style":16},"version: 2\nmetrics:\n  - name: revenue\n    label: Revenue\n    model: ref('fct_orders')\n    calculation_method: sum\n    expression: order_amount\n    timestamp: order_date\n    time_grains: [day, week, month, quarter]\n    dimensions:\n      - channel\n      - country\n      - device_category\n\n  - name: cac\n    label: Customer Acquisition Cost\n    calculation_method: derived\n    expression: \"{{ metric('ad_spend') }} \u002F {{ metric('new_customers') }}\"\n    timestamp: acquisition_date\n    time_grains: [month, quarter]\n",[1125],{"type":32,"tag":52,"props":1126,"children":1127},{"__ignoreMap":16},[1128,1143,1155,1175,1192,1209,1226,1243,1260,1310,1322,1334,1346,1358,1367,1388,1405,1422,1439,1456],{"type":32,"tag":95,"props":1129,"children":1130},{"class":97,"line":98},[1131,1135,1139],{"type":32,"tag":95,"props":1132,"children":1133},{"style":102},[1134],{"type":37,"value":105},{"type":32,"tag":95,"props":1136,"children":1137},{"style":108},[1138],{"type":37,"value":111},{"type":32,"tag":95,"props":1140,"children":1141},{"style":114},[1142],{"type":37,"value":117},{"type":32,"tag":95,"props":1144,"children":1145},{"class":97,"line":120},[1146,1151],{"type":32,"tag":95,"props":1147,"children":1148},{"style":102},[1149],{"type":37,"value":1150},"metrics",{"type":32,"tag":95,"props":1152,"children":1153},{"style":108},[1154],{"type":37,"value":131},{"type":32,"tag":95,"props":1156,"children":1157},{"class":97,"line":134},[1158,1162,1166,1170],{"type":32,"tag":95,"props":1159,"children":1160},{"style":108},[1161],{"type":37,"value":140},{"type":32,"tag":95,"props":1163,"children":1164},{"style":102},[1165],{"type":37,"value":145},{"type":32,"tag":95,"props":1167,"children":1168},{"style":108},[1169],{"type":37,"value":111},{"type":32,"tag":95,"props":1171,"children":1172},{"style":152},[1173],{"type":37,"value":1174},"revenue\n",{"type":32,"tag":95,"props":1176,"children":1177},{"class":97,"line":158},[1178,1183,1187],{"type":32,"tag":95,"props":1179,"children":1180},{"style":102},[1181],{"type":37,"value":1182},"    label",{"type":32,"tag":95,"props":1184,"children":1185},{"style":108},[1186],{"type":37,"value":111},{"type":32,"tag":95,"props":1188,"children":1189},{"style":152},[1190],{"type":37,"value":1191},"Revenue\n",{"type":32,"tag":95,"props":1193,"children":1194},{"class":97,"line":176},[1195,1200,1204],{"type":32,"tag":95,"props":1196,"children":1197},{"style":102},[1198],{"type":37,"value":1199},"    model",{"type":32,"tag":95,"props":1201,"children":1202},{"style":108},[1203],{"type":37,"value":111},{"type":32,"tag":95,"props":1205,"children":1206},{"style":152},[1207],{"type":37,"value":1208},"ref('fct_orders')\n",{"type":32,"tag":95,"props":1210,"children":1211},{"class":97,"line":189},[1212,1217,1221],{"type":32,"tag":95,"props":1213,"children":1214},{"style":102},[1215],{"type":37,"value":1216},"    calculation_method",{"type":32,"tag":95,"props":1218,"children":1219},{"style":108},[1220],{"type":37,"value":111},{"type":32,"tag":95,"props":1222,"children":1223},{"style":152},[1224],{"type":37,"value":1225},"sum\n",{"type":32,"tag":95,"props":1227,"children":1228},{"class":97,"line":211},[1229,1234,1238],{"type":32,"tag":95,"props":1230,"children":1231},{"style":102},[1232],{"type":37,"value":1233},"    expression",{"type":32,"tag":95,"props":1235,"children":1236},{"style":108},[1237],{"type":37,"value":111},{"type":32,"tag":95,"props":1239,"children":1240},{"style":152},[1241],{"type":37,"value":1242},"order_amount\n",{"type":32,"tag":95,"props":1244,"children":1245},{"class":97,"line":26},[1246,1251,1255],{"type":32,"tag":95,"props":1247,"children":1248},{"style":102},[1249],{"type":37,"value":1250},"    timestamp",{"type":32,"tag":95,"props":1252,"children":1253},{"style":108},[1254],{"type":37,"value":111},{"type":32,"tag":95,"props":1256,"children":1257},{"style":152},[1258],{"type":37,"value":1259},"order_date\n",{"type":32,"tag":95,"props":1261,"children":1262},{"class":97,"line":246},[1263,1268,1273,1278,1282,1287,1291,1296,1300,1305],{"type":32,"tag":95,"props":1264,"children":1265},{"style":102},[1266],{"type":37,"value":1267},"    time_grains",{"type":32,"tag":95,"props":1269,"children":1270},{"style":108},[1271],{"type":37,"value":1272},": [",{"type":32,"tag":95,"props":1274,"children":1275},{"style":152},[1276],{"type":37,"value":1277},"day",{"type":32,"tag":95,"props":1279,"children":1280},{"style":108},[1281],{"type":37,"value":623},{"type":32,"tag":95,"props":1283,"children":1284},{"style":152},[1285],{"type":37,"value":1286},"week",{"type":32,"tag":95,"props":1288,"children":1289},{"style":108},[1290],{"type":37,"value":623},{"type":32,"tag":95,"props":1292,"children":1293},{"style":152},[1294],{"type":37,"value":1295},"month",{"type":32,"tag":95,"props":1297,"children":1298},{"style":108},[1299],{"type":37,"value":623},{"type":32,"tag":95,"props":1301,"children":1302},{"style":152},[1303],{"type":37,"value":1304},"quarter",{"type":32,"tag":95,"props":1306,"children":1307},{"style":108},[1308],{"type":37,"value":1309},"]\n",{"type":32,"tag":95,"props":1311,"children":1312},{"class":97,"line":267},[1313,1318],{"type":32,"tag":95,"props":1314,"children":1315},{"style":102},[1316],{"type":37,"value":1317},"    dimensions",{"type":32,"tag":95,"props":1319,"children":1320},{"style":108},[1321],{"type":37,"value":131},{"type":32,"tag":95,"props":1323,"children":1324},{"class":97,"line":284},[1325,1329],{"type":32,"tag":95,"props":1326,"children":1327},{"style":108},[1328],{"type":37,"value":195},{"type":32,"tag":95,"props":1330,"children":1331},{"style":152},[1332],{"type":37,"value":1333},"channel\n",{"type":32,"tag":95,"props":1335,"children":1336},{"class":97,"line":302},[1337,1341],{"type":32,"tag":95,"props":1338,"children":1339},{"style":108},[1340],{"type":37,"value":195},{"type":32,"tag":95,"props":1342,"children":1343},{"style":152},[1344],{"type":37,"value":1345},"country\n",{"type":32,"tag":95,"props":1347,"children":1348},{"class":97,"line":314},[1349,1353],{"type":32,"tag":95,"props":1350,"children":1351},{"style":108},[1352],{"type":37,"value":195},{"type":32,"tag":95,"props":1354,"children":1355},{"style":152},[1356],{"type":37,"value":1357},"device_category\n",{"type":32,"tag":95,"props":1359,"children":1360},{"class":97,"line":335},[1361],{"type":32,"tag":95,"props":1362,"children":1364},{"emptyLinePlaceholder":1363},true,[1365],{"type":37,"value":1366},"\n",{"type":32,"tag":95,"props":1368,"children":1370},{"class":97,"line":1369},15,[1371,1375,1379,1383],{"type":32,"tag":95,"props":1372,"children":1373},{"style":108},[1374],{"type":37,"value":140},{"type":32,"tag":95,"props":1376,"children":1377},{"style":102},[1378],{"type":37,"value":145},{"type":32,"tag":95,"props":1380,"children":1381},{"style":108},[1382],{"type":37,"value":111},{"type":32,"tag":95,"props":1384,"children":1385},{"style":152},[1386],{"type":37,"value":1387},"cac\n",{"type":32,"tag":95,"props":1389,"children":1391},{"class":97,"line":1390},16,[1392,1396,1400],{"type":32,"tag":95,"props":1393,"children":1394},{"style":102},[1395],{"type":37,"value":1182},{"type":32,"tag":95,"props":1397,"children":1398},{"style":108},[1399],{"type":37,"value":111},{"type":32,"tag":95,"props":1401,"children":1402},{"style":152},[1403],{"type":37,"value":1404},"Customer Acquisition Cost\n",{"type":32,"tag":95,"props":1406,"children":1408},{"class":97,"line":1407},17,[1409,1413,1417],{"type":32,"tag":95,"props":1410,"children":1411},{"style":102},[1412],{"type":37,"value":1216},{"type":32,"tag":95,"props":1414,"children":1415},{"style":108},[1416],{"type":37,"value":111},{"type":32,"tag":95,"props":1418,"children":1419},{"style":152},[1420],{"type":37,"value":1421},"derived\n",{"type":32,"tag":95,"props":1423,"children":1425},{"class":97,"line":1424},18,[1426,1430,1434],{"type":32,"tag":95,"props":1427,"children":1428},{"style":102},[1429],{"type":37,"value":1233},{"type":32,"tag":95,"props":1431,"children":1432},{"style":108},[1433],{"type":37,"value":111},{"type":32,"tag":95,"props":1435,"children":1436},{"style":152},[1437],{"type":37,"value":1438},"\"{{ metric('ad_spend') }} \u002F {{ metric('new_customers') }}\"\n",{"type":32,"tag":95,"props":1440,"children":1442},{"class":97,"line":1441},19,[1443,1447,1451],{"type":32,"tag":95,"props":1444,"children":1445},{"style":102},[1446],{"type":37,"value":1250},{"type":32,"tag":95,"props":1448,"children":1449},{"style":108},[1450],{"type":37,"value":111},{"type":32,"tag":95,"props":1452,"children":1453},{"style":152},[1454],{"type":37,"value":1455},"acquisition_date\n",{"type":32,"tag":95,"props":1457,"children":1459},{"class":97,"line":1458},20,[1460,1464,1468,1472,1476,1480],{"type":32,"tag":95,"props":1461,"children":1462},{"style":102},[1463],{"type":37,"value":1267},{"type":32,"tag":95,"props":1465,"children":1466},{"style":108},[1467],{"type":37,"value":1272},{"type":32,"tag":95,"props":1469,"children":1470},{"style":152},[1471],{"type":37,"value":1295},{"type":32,"tag":95,"props":1473,"children":1474},{"style":108},[1475],{"type":37,"value":623},{"type":32,"tag":95,"props":1477,"children":1478},{"style":152},[1479],{"type":37,"value":1304},{"type":32,"tag":95,"props":1481,"children":1482},{"style":108},[1483],{"type":37,"value":1309},{"type":32,"tag":33,"props":1485,"children":1486},{},[1487],{"type":37,"value":1488},"Con la semantic layer, no es la herramienta BI quien calcula CAC, lo hace dbt. Cuando Looker pide \"dame CAC\", dbt devuelve SQL compilado, une la tabla de spend y la tabla de nuevos clientes, divide. La definición es código, por lo que el historial de git registra \"quién cambió el cálculo de CAC, y por qué\". La fórmula en spreadsheet no se pierde, hay control de versiones.",{"type":32,"tag":33,"props":1490,"children":1491},{},[1492,1494,1503,1505,1511,1513,1519],{"type":37,"value":1493},"En proyectos de Roibase, la semantic layer se construye como parte de ",{"type":32,"tag":1495,"props":1496,"children":1500},"a",{"href":1497,"rel":1498},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Fverianalizi",[1499],"nofollow",[1501],{"type":37,"value":1502},"análisis de datos e ingeniería de insights",{"type":37,"value":1504}," — no solo definición de métrica, sino mapeo de árbol de KPI, jerarquía de dimensiones, estandarización de granularidad. Por ejemplo: la métrica \"revenue\" es la suma de ",{"type":32,"tag":52,"props":1506,"children":1508},{"className":1507},[],[1509],{"type":37,"value":1510},"fct_orders.order_amount",{"type":37,"value":1512},", pero \"recognized_revenue\" filtra la misma tabla por timestamp ",{"type":32,"tag":52,"props":1514,"children":1516},{"className":1515},[],[1517],{"type":37,"value":1518},"recognized_at",{"type":37,"value":1520}," (modelo de suscripción SaaS). Una tabla, dos métricas, lógica de negocio diferente.",{"type":32,"tag":40,"props":1522,"children":1524},{"id":1523},"exposures-hacer-visibles-las-dependencias-downstream",[1525],{"type":37,"value":1526},"Exposures: Hacer visibles las dependencias downstream",{"type":32,"tag":33,"props":1528,"children":1529},{},[1530,1532,1538,1540,1546],{"type":37,"value":1531},"Exposure es la respuesta de dbt a la pregunta \"quién usa este modelo\". Si un dashboard de Looker mira la tabla ",{"type":32,"tag":52,"props":1533,"children":1535},{"className":1534},[],[1536],{"type":37,"value":1537},"fct_marketing_performance",{"type":37,"value":1539},", lo defines en ",{"type":32,"tag":52,"props":1541,"children":1543},{"className":1542},[],[1544],{"type":37,"value":1545},"exposures.yml",{"type":37,"value":418},{"type":32,"tag":85,"props":1548,"children":1550},{"className":87,"code":1549,"language":89,"meta":16,"style":16},"version: 2\nexposures:\n  - name: marketing_dashboard\n    type: dashboard\n    maturity: high\n    owner:\n      name: Growth Team\n      email: growth@company.com\n    depends_on:\n      - ref('fct_marketing_performance')\n      - ref('dim_customers')\n    description: \"Dashboard de marketing ejecutivo — actualización diaria, ventana móvil 90 días\"\n    url: https:\u002F\u002Flooker.company.com\u002Fdashboards\u002F123\n",[1551],{"type":32,"tag":52,"props":1552,"children":1553},{"__ignoreMap":16},[1554,1569,1581,1601,1618,1635,1647,1664,1681,1693,1705,1717,1734],{"type":32,"tag":95,"props":1555,"children":1556},{"class":97,"line":98},[1557,1561,1565],{"type":32,"tag":95,"props":1558,"children":1559},{"style":102},[1560],{"type":37,"value":105},{"type":32,"tag":95,"props":1562,"children":1563},{"style":108},[1564],{"type":37,"value":111},{"type":32,"tag":95,"props":1566,"children":1567},{"style":114},[1568],{"type":37,"value":117},{"type":32,"tag":95,"props":1570,"children":1571},{"class":97,"line":120},[1572,1577],{"type":32,"tag":95,"props":1573,"children":1574},{"style":102},[1575],{"type":37,"value":1576},"exposures",{"type":32,"tag":95,"props":1578,"children":1579},{"style":108},[1580],{"type":37,"value":131},{"type":32,"tag":95,"props":1582,"children":1583},{"class":97,"line":134},[1584,1588,1592,1596],{"type":32,"tag":95,"props":1585,"children":1586},{"style":108},[1587],{"type":37,"value":140},{"type":32,"tag":95,"props":1589,"children":1590},{"style":102},[1591],{"type":37,"value":145},{"type":32,"tag":95,"props":1593,"children":1594},{"style":108},[1595],{"type":37,"value":111},{"type":32,"tag":95,"props":1597,"children":1598},{"style":152},[1599],{"type":37,"value":1600},"marketing_dashboard\n",{"type":32,"tag":95,"props":1602,"children":1603},{"class":97,"line":158},[1604,1609,1613],{"type":32,"tag":95,"props":1605,"children":1606},{"style":102},[1607],{"type":37,"value":1608},"    type",{"type":32,"tag":95,"props":1610,"children":1611},{"style":108},[1612],{"type":37,"value":111},{"type":32,"tag":95,"props":1614,"children":1615},{"style":152},[1616],{"type":37,"value":1617},"dashboard\n",{"type":32,"tag":95,"props":1619,"children":1620},{"class":97,"line":176},[1621,1626,1630],{"type":32,"tag":95,"props":1622,"children":1623},{"style":102},[1624],{"type":37,"value":1625},"    maturity",{"type":32,"tag":95,"props":1627,"children":1628},{"style":108},[1629],{"type":37,"value":111},{"type":32,"tag":95,"props":1631,"children":1632},{"style":152},[1633],{"type":37,"value":1634},"high\n",{"type":32,"tag":95,"props":1636,"children":1637},{"class":97,"line":189},[1638,1643],{"type":32,"tag":95,"props":1639,"children":1640},{"style":102},[1641],{"type":37,"value":1642},"    owner",{"type":32,"tag":95,"props":1644,"children":1645},{"style":108},[1646],{"type":37,"value":131},{"type":32,"tag":95,"props":1648,"children":1649},{"class":97,"line":211},[1650,1655,1659],{"type":32,"tag":95,"props":1651,"children":1652},{"style":102},[1653],{"type":37,"value":1654},"      name",{"type":32,"tag":95,"props":1656,"children":1657},{"style":108},[1658],{"type":37,"value":111},{"type":32,"tag":95,"props":1660,"children":1661},{"style":152},[1662],{"type":37,"value":1663},"Growth Team\n",{"type":32,"tag":95,"props":1665,"children":1666},{"class":97,"line":26},[1667,1672,1676],{"type":32,"tag":95,"props":1668,"children":1669},{"style":102},[1670],{"type":37,"value":1671},"      email",{"type":32,"tag":95,"props":1673,"children":1674},{"style":108},[1675],{"type":37,"value":111},{"type":32,"tag":95,"props":1677,"children":1678},{"style":152},[1679],{"type":37,"value":1680},"growth@company.com\n",{"type":32,"tag":95,"props":1682,"children":1683},{"class":97,"line":246},[1684,1689],{"type":32,"tag":95,"props":1685,"children":1686},{"style":102},[1687],{"type":37,"value":1688},"    depends_on",{"type":32,"tag":95,"props":1690,"children":1691},{"style":108},[1692],{"type":37,"value":131},{"type":32,"tag":95,"props":1694,"children":1695},{"class":97,"line":267},[1696,1700],{"type":32,"tag":95,"props":1697,"children":1698},{"style":108},[1699],{"type":37,"value":195},{"type":32,"tag":95,"props":1701,"children":1702},{"style":152},[1703],{"type":37,"value":1704},"ref('fct_marketing_performance')\n",{"type":32,"tag":95,"props":1706,"children":1707},{"class":97,"line":284},[1708,1712],{"type":32,"tag":95,"props":1709,"children":1710},{"style":108},[1711],{"type":37,"value":195},{"type":32,"tag":95,"props":1713,"children":1714},{"style":152},[1715],{"type":37,"value":1716},"ref('dim_customers')\n",{"type":32,"tag":95,"props":1718,"children":1719},{"class":97,"line":302},[1720,1725,1729],{"type":32,"tag":95,"props":1721,"children":1722},{"style":102},[1723],{"type":37,"value":1724},"    description",{"type":32,"tag":95,"props":1726,"children":1727},{"style":108},[1728],{"type":37,"value":111},{"type":32,"tag":95,"props":1730,"children":1731},{"style":152},[1732],{"type":37,"value":1733},"\"Dashboard de marketing ejecutivo — actualización diaria, ventana móvil 90 días\"\n",{"type":32,"tag":95,"props":1735,"children":1736},{"class":97,"line":314},[1737,1742,1746],{"type":32,"tag":95,"props":1738,"children":1739},{"style":102},[1740],{"type":37,"value":1741},"    url",{"type":32,"tag":95,"props":1743,"children":1744},{"style":108},[1745],{"type":37,"value":111},{"type":32,"tag":95,"props":1747,"children":1748},{"style":152},[1749],{"type":37,"value":1750},"https:\u002F\u002Flooker.company.com\u002Fdashboards\u002F123\n",{"type":32,"tag":33,"props":1752,"children":1753},{},[1754,1756,1761,1763,1769,1771,1777],{"type":37,"value":1755},"Sin definición de exposure, cuando cambias ",{"type":32,"tag":52,"props":1757,"children":1759},{"className":1758},[],[1760],{"type":37,"value":1537},{"type":37,"value":1762},", no sabes qué dashboard se rompe. Después de ",{"type":32,"tag":52,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":37,"value":1768},"dbt run",{"type":37,"value":1770},", Looker muestra métricas cero, pasas 2 horas debuggeando. Con exposure, el comando ",{"type":32,"tag":52,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":37,"value":1776},"dbt compile --select +exposure:marketing_dashboard",{"type":37,"value":1778}," muestra todos los modelos upstream, haces análisis de impacto antes del cambio.",{"type":32,"tag":33,"props":1780,"children":1781},{},[1782,1784,1790],{"type":37,"value":1783},"Exposure no es solo para herramientas BI — también para reverse ETL (Hightouch, Census). Si sincronizas la tabla ",{"type":32,"tag":52,"props":1785,"children":1787},{"className":1786},[],[1788],{"type":37,"value":1789},"customers",{"type":37,"value":1791}," a Meta CAPI:",{"type":32,"tag":85,"props":1793,"children":1795},{"className":87,"code":1794,"language":89,"meta":16,"style":16},"exposures:\n  - name: meta_capi_sync\n    type: application\n    maturity: high\n    depends_on:\n      - ref('dim_customers')\n    description: \"Meta Conversion API — eventos de cliente incrementales, retraso 5 minutos\"\n",[1796],{"type":32,"tag":52,"props":1797,"children":1798},{"__ignoreMap":16},[1799,1810,1830,1846,1861,1872,1883],{"type":32,"tag":95,"props":1800,"children":1801},{"class":97,"line":98},[1802,1806],{"type":32,"tag":95,"props":1803,"children":1804},{"style":102},[1805],{"type":37,"value":1576},{"type":32,"tag":95,"props":1807,"children":1808},{"style":108},[1809],{"type":37,"value":131},{"type":32,"tag":95,"props":1811,"children":1812},{"class":97,"line":120},[1813,1817,1821,1825],{"type":32,"tag":95,"props":1814,"children":1815},{"style":108},[1816],{"type":37,"value":140},{"type":32,"tag":95,"props":1818,"children":1819},{"style":102},[1820],{"type":37,"value":145},{"type":32,"tag":95,"props":1822,"children":1823},{"style":108},[1824],{"type":37,"value":111},{"type":32,"tag":95,"props":1826,"children":1827},{"style":152},[1828],{"type":37,"value":1829},"meta_capi_sync\n",{"type":32,"tag":95,"props":1831,"children":1832},{"class":97,"line":134},[1833,1837,1841],{"type":32,"tag":95,"props":1834,"children":1835},{"style":102},[1836],{"type":37,"value":1608},{"type":32,"tag":95,"props":1838,"children":1839},{"style":108},[1840],{"type":37,"value":111},{"type":32,"tag":95,"props":1842,"children":1843},{"style":152},[1844],{"type":37,"value":1845},"application\n",{"type":32,"tag":95,"props":1847,"children":1848},{"class":97,"line":158},[1849,1853,1857],{"type":32,"tag":95,"props":1850,"children":1851},{"style":102},[1852],{"type":37,"value":1625},{"type":32,"tag":95,"props":1854,"children":1855},{"style":108},[1856],{"type":37,"value":111},{"type":32,"tag":95,"props":1858,"children":1859},{"style":152},[1860],{"type":37,"value":1634},{"type":32,"tag":95,"props":1862,"children":1863},{"class":97,"line":176},[1864,1868],{"type":32,"tag":95,"props":1865,"children":1866},{"style":102},[1867],{"type":37,"value":1688},{"type":32,"tag":95,"props":1869,"children":1870},{"style":108},[1871],{"type":37,"value":131},{"type":32,"tag":95,"props":1873,"children":1874},{"class":97,"line":189},[1875,1879],{"type":32,"tag":95,"props":1876,"children":1877},{"style":108},[1878],{"type":37,"value":195},{"type":32,"tag":95,"props":1880,"children":1881},{"style":152},[1882],{"type":37,"value":1716},{"type":32,"tag":95,"props":1884,"children":1885},{"class":97,"line":211},[1886,1890,1894],{"type":32,"tag":95,"props":1887,"children":1888},{"style":102},[1889],{"type":37,"value":1724},{"type":32,"tag":95,"props":1891,"children":1892},{"style":108},[1893],{"type":37,"value":111},{"type":32,"tag":95,"props":1895,"children":1896},{"style":152},[1897],{"type":37,"value":1898},"\"Meta Conversion API — eventos de cliente incrementales, retraso 5 minutos\"\n",{"type":32,"tag":33,"props":1900,"children":1901},{},[1902],{"type":37,"value":1903},"Esta definición advierte \"si cambias el esquema de dim_customers, rompes el schema de evento que va a Meta\". En producción, evita la cadena: actualizar modelo → error de sincronización CAPI → pérdida de datos de atribución.",{"type":32,"tag":40,"props":1905,"children":1907},{"id":1906},"pipeline-en-producción-builds-incrementales-y-cobertura-de-pruebas",[1908],{"type":37,"value":1909},"Pipeline en producción: Builds incrementales y cobertura de pruebas",{"type":32,"tag":33,"props":1911,"children":1912},{},[1913,1915,1921],{"type":37,"value":1914},"En producción, dbt no hace refresh completo cada día — usa modelos incrementales. ",{"type":32,"tag":52,"props":1916,"children":1918},{"className":1917},[],[1919],{"type":37,"value":1920},"fct_orders.sql",{"type":37,"value":1922}," solo reprocesa los últimos 3 días:",{"type":32,"tag":85,"props":1924,"children":1926},{"className":421,"code":1925,"language":423,"meta":16,"style":16},"{{ config(\n    materialized='incremental',\n    unique_key='order_id',\n    partition_by={'field': 'order_date', 'data_type': 'date'},\n    cluster_by=['customer_id', 'channel']\n) }}\n\nSELECT\n  order_id,\n  customer_id,\n  order_date,\n  order_amount,\n  channel\nFROM {{ ref('stg_shopify_orders') }}\n\n{% if is_incremental() %}\nWHERE order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 3 DAY)\n{% endif %}\n",[1927],{"type":32,"tag":52,"props":1928,"children":1929},{"__ignoreMap":16},[1930,1938,1959,1980,2034,2051,2058,2065,2072,2080,2088,2096,2104,2112,2132,2139,2157,2192],{"type":32,"tag":95,"props":1931,"children":1932},{"class":97,"line":98},[1933],{"type":32,"tag":95,"props":1934,"children":1935},{"style":108},[1936],{"type":37,"value":1937},"{{ config(\n",{"type":32,"tag":95,"props":1939,"children":1940},{"class":97,"line":120},[1941,1946,1950,1955],{"type":32,"tag":95,"props":1942,"children":1943},{"style":108},[1944],{"type":37,"value":1945},"    materialized",{"type":32,"tag":95,"props":1947,"children":1948},{"style":433},[1949],{"type":37,"value":840},{"type":32,"tag":95,"props":1951,"children":1952},{"style":152},[1953],{"type":37,"value":1954},"'incremental'",{"type":32,"tag":95,"props":1956,"children":1957},{"style":108},[1958],{"type":37,"value":573},{"type":32,"tag":95,"props":1960,"children":1961},{"class":97,"line":134},[1962,1967,1971,1976],{"type":32,"tag":95,"props":1963,"children":1964},{"style":108},[1965],{"type":37,"value":1966},"    unique_key",{"type":32,"tag":95,"props":1968,"children":1969},{"style":433},[1970],{"type":37,"value":840},{"type":32,"tag":95,"props":1972,"children":1973},{"style":152},[1974],{"type":37,"value":1975},"'order_id'",{"type":32,"tag":95,"props":1977,"children":1978},{"style":108},[1979],{"type":37,"value":573},{"type":32,"tag":95,"props":1981,"children":1982},{"class":97,"line":158},[1983,1988,1992,1997,2002,2006,2011,2015,2020,2024,2029],{"type":32,"tag":95,"props":1984,"children":1985},{"style":108},[1986],{"type":37,"value":1987},"    partition_by",{"type":32,"tag":95,"props":1989,"children":1990},{"style":433},[1991],{"type":37,"value":840},{"type":32,"tag":95,"props":1993,"children":1994},{"style":108},[1995],{"type":37,"value":1996},"{",{"type":32,"tag":95,"props":1998,"children":1999},{"style":152},[2000],{"type":37,"value":2001},"'field'",{"type":32,"tag":95,"props":2003,"children":2004},{"style":108},[2005],{"type":37,"value":111},{"type":32,"tag":95,"props":2007,"children":2008},{"style":152},[2009],{"type":37,"value":2010},"'order_date'",{"type":32,"tag":95,"props":2012,"children":2013},{"style":108},[2014],{"type":37,"value":623},{"type":32,"tag":95,"props":2016,"children":2017},{"style":152},[2018],{"type":37,"value":2019},"'data_type'",{"type":32,"tag":95,"props":2021,"children":2022},{"style":108},[2023],{"type":37,"value":111},{"type":32,"tag":95,"props":2025,"children":2026},{"style":152},[2027],{"type":37,"value":2028},"'date'",{"type":32,"tag":95,"props":2030,"children":2031},{"style":108},[2032],{"type":37,"value":2033},"},\n",{"type":32,"tag":95,"props":2035,"children":2036},{"class":97,"line":176},[2037,2042,2046],{"type":32,"tag":95,"props":2038,"children":2039},{"style":108},[2040],{"type":37,"value":2041},"    cluster_by",{"type":32,"tag":95,"props":2043,"children":2044},{"style":433},[2045],{"type":37,"value":840},{"type":32,"tag":95,"props":2047,"children":2048},{"style":108},[2049],{"type":37,"value":2050},"['customer_id', 'channel']\n",{"type":32,"tag":95,"props":2052,"children":2053},{"class":97,"line":189},[2054],{"type":32,"tag":95,"props":2055,"children":2056},{"style":108},[2057],{"type":37,"value":633},{"type":32,"tag":95,"props":2059,"children":2060},{"class":97,"line":211},[2061],{"type":32,"tag":95,"props":2062,"children":2063},{"emptyLinePlaceholder":1363},[2064],{"type":37,"value":1366},{"type":32,"tag":95,"props":2066,"children":2067},{"class":97,"line":26},[2068],{"type":32,"tag":95,"props":2069,"children":2070},{"style":433},[2071],{"type":37,"value":436},{"type":32,"tag":95,"props":2073,"children":2074},{"class":97,"line":246},[2075],{"type":32,"tag":95,"props":2076,"children":2077},{"style":108},[2078],{"type":37,"value":2079},"  order_id,\n",{"type":32,"tag":95,"props":2081,"children":2082},{"class":97,"line":267},[2083],{"type":32,"tag":95,"props":2084,"children":2085},{"style":108},[2086],{"type":37,"value":2087},"  customer_id,\n",{"type":32,"tag":95,"props":2089,"children":2090},{"class":97,"line":284},[2091],{"type":32,"tag":95,"props":2092,"children":2093},{"style":108},[2094],{"type":37,"value":2095},"  order_date,\n",{"type":32,"tag":95,"props":2097,"children":2098},{"class":97,"line":302},[2099],{"type":32,"tag":95,"props":2100,"children":2101},{"style":108},[2102],{"type":37,"value":2103},"  order_amount,\n",{"type":32,"tag":95,"props":2105,"children":2106},{"class":97,"line":314},[2107],{"type":32,"tag":95,"props":2108,"children":2109},{"style":108},[2110],{"type":37,"value":2111},"  channel\n",{"type":32,"tag":95,"props":2113,"children":2114},{"class":97,"line":335},[2115,2119,2123,2128],{"type":32,"tag":95,"props":2116,"children":2117},{"style":433},[2118],{"type":37,"value":608},{"type":32,"tag":95,"props":2120,"children":2121},{"style":108},[2122],{"type":37,"value":956},{"type":32,"tag":95,"props":2124,"children":2125},{"style":152},[2126],{"type":37,"value":2127},"'stg_shopify_orders'",{"type":32,"tag":95,"props":2129,"children":2130},{"style":108},[2131],{"type":37,"value":633},{"type":32,"tag":95,"props":2133,"children":2134},{"class":97,"line":1369},[2135],{"type":32,"tag":95,"props":2136,"children":2137},{"emptyLinePlaceholder":1363},[2138],{"type":37,"value":1366},{"type":32,"tag":95,"props":2140,"children":2141},{"class":97,"line":1390},[2142,2147,2152],{"type":32,"tag":95,"props":2143,"children":2144},{"style":108},[2145],{"type":37,"value":2146},"{% ",{"type":32,"tag":95,"props":2148,"children":2149},{"style":433},[2150],{"type":37,"value":2151},"if",{"type":32,"tag":95,"props":2153,"children":2154},{"style":108},[2155],{"type":37,"value":2156}," is_incremental() %}\n",{"type":32,"tag":95,"props":2158,"children":2159},{"class":97,"line":1407},[2160,2164,2169,2174,2179,2184,2188],{"type":32,"tag":95,"props":2161,"children":2162},{"style":433},[2163],{"type":37,"value":522},{"type":32,"tag":95,"props":2165,"children":2166},{"style":108},[2167],{"type":37,"value":2168}," order_date ",{"type":32,"tag":95,"props":2170,"children":2171},{"style":433},[2172],{"type":37,"value":2173},">=",{"type":32,"tag":95,"props":2175,"children":2176},{"style":108},[2177],{"type":37,"value":2178}," DATE_SUB(CURRENT_DATE(), INTERVAL ",{"type":32,"tag":95,"props":2180,"children":2181},{"style":114},[2182],{"type":37,"value":2183},"3",{"type":32,"tag":95,"props":2185,"children":2186},{"style":433},[2187],{"type":37,"value":675},{"type":32,"tag":95,"props":2189,"children":2190},{"style":108},[2191],{"type":37,"value":986},{"type":32,"tag":95,"props":2193,"children":2194},{"class":97,"line":1424},[2195],{"type":32,"tag":95,"props":2196,"children":2197},{"style":108},[2198],{"type":37,"value":2199},"{% endif %}\n",{"type":32,"tag":33,"props":2201,"children":2202},{},[2203,2205,2211],{"type":37,"value":2204},"El build incremental reduce el costo de BigQuery 90% — en lugar de escanear 2TB, escanea 50GB. Partition + cluster mejoran performance: una query ",{"type":32,"tag":52,"props":2206,"children":2208},{"className":2207},[],[2209],{"type":37,"value":2210},"WHERE customer_id = 'X'",{"type":37,"value":2212}," va solo al cluster relevante, sin full scan.",{"type":32,"tag":33,"props":2214,"children":2215},{},[2216,2218,2224],{"type":37,"value":2217},"La cobertura de pruebas es crítica. En ",{"type":32,"tag":52,"props":2219,"children":2221},{"className":2220},[],[2222],{"type":37,"value":2223},"schema.yml",{"type":37,"value":2225}," defines pruebas para cada modelo:",{"type":32,"tag":85,"props":2227,"children":2229},{"className":87,"code":2228,"language":89,"meta":16,"style":16},"models:\n  - name: fct_orders\n    columns:\n      - name: order_id\n        tests:\n          - unique\n          - not_null\n      - name: order_amount\n        tests:\n          - not_null\n          - dbt_utils.expression_is_true:\n              expression: \">= 0\"\n      - name: order_date\n        tests:\n          - dbt_utils.recency:\n              datepart: day\n              interval: 7\n",[2230],{"type":32,"tag":52,"props":2231,"children":2232},{"__ignoreMap":16},[2233,2245,2265,2277,2297,2309,2322,2334,2353,2364,2375,2391,2408,2427,2438,2454,2471],{"type":32,"tag":95,"props":2234,"children":2235},{"class":97,"line":98},[2236,2241],{"type":32,"tag":95,"props":2237,"children":2238},{"style":102},[2239],{"type":37,"value":2240},"models",{"type":32,"tag":95,"props":2242,"children":2243},{"style":108},[2244],{"type":37,"value":131},{"type":32,"tag":95,"props":2246,"children":2247},{"class":97,"line":120},[2248,2252,2256,2260],{"type":32,"tag":95,"props":2249,"children":2250},{"style":108},[2251],{"type":37,"value":140},{"type":32,"tag":95,"props":2253,"children":2254},{"style":102},[2255],{"type":37,"value":145},{"type":32,"tag":95,"props":2257,"children":2258},{"style":108},[2259],{"type":37,"value":111},{"type":32,"tag":95,"props":2261,"children":2262},{"style":152},[2263],{"type":37,"value":2264},"fct_orders\n",{"type":32,"tag":95,"props":2266,"children":2267},{"class":97,"line":134},[2268,2273],{"type":32,"tag":95,"props":2269,"children":2270},{"style":102},[2271],{"type":37,"value":2272},"    columns",{"type":32,"tag":95,"props":2274,"children":2275},{"style":108},[2276],{"type":37,"value":131},{"type":32,"tag":95,"props":2278,"children":2279},{"class":97,"line":158},[2280,2284,2288,2292],{"type":32,"tag":95,"props":2281,"children":2282},{"style":108},[2283],{"type":37,"value":195},{"type":32,"tag":95,"props":2285,"children":2286},{"style":102},[2287],{"type":37,"value":145},{"type":32,"tag":95,"props":2289,"children":2290},{"style":108},[2291],{"type":37,"value":111},{"type":32,"tag":95,"props":2293,"children":2294},{"style":152},[2295],{"type":37,"value":2296},"order_id\n",{"type":32,"tag":95,"props":2298,"children":2299},{"class":97,"line":176},[2300,2305],{"type":32,"tag":95,"props":2301,"children":2302},{"style":102},[2303],{"type":37,"value":2304},"        tests",{"type":32,"tag":95,"props":2306,"children":2307},{"style":108},[2308],{"type":37,"value":131},{"type":32,"tag":95,"props":2310,"children":2311},{"class":97,"line":189},[2312,2317],{"type":32,"tag":95,"props":2313,"children":2314},{"style":108},[2315],{"type":37,"value":2316},"          - ",{"type":32,"tag":95,"props":2318,"children":2319},{"style":152},[2320],{"type":37,"value":2321},"unique\n",{"type":32,"tag":95,"props":2323,"children":2324},{"class":97,"line":211},[2325,2329],{"type":32,"tag":95,"props":2326,"children":2327},{"style":108},[2328],{"type":37,"value":2316},{"type":32,"tag":95,"props":2330,"children":2331},{"style":152},[2332],{"type":37,"value":2333},"not_null\n",{"type":32,"tag":95,"props":2335,"children":2336},{"class":97,"line":26},[2337,2341,2345,2349],{"type":32,"tag":95,"props":2338,"children":2339},{"style":108},[2340],{"type":37,"value":195},{"type":32,"tag":95,"props":2342,"children":2343},{"style":102},[2344],{"type":37,"value":145},{"type":32,"tag":95,"props":2346,"children":2347},{"style":108},[2348],{"type":37,"value":111},{"type":32,"tag":95,"props":2350,"children":2351},{"style":152},[2352],{"type":37,"value":1242},{"type":32,"tag":95,"props":2354,"children":2355},{"class":97,"line":246},[2356,2360],{"type":32,"tag":95,"props":2357,"children":2358},{"style":102},[2359],{"type":37,"value":2304},{"type":32,"tag":95,"props":2361,"children":2362},{"style":108},[2363],{"type":37,"value":131},{"type":32,"tag":95,"props":2365,"children":2366},{"class":97,"line":267},[2367,2371],{"type":32,"tag":95,"props":2368,"children":2369},{"style":108},[2370],{"type":37,"value":2316},{"type":32,"tag":95,"props":2372,"children":2373},{"style":152},[2374],{"type":37,"value":2333},{"type":32,"tag":95,"props":2376,"children":2377},{"class":97,"line":284},[2378,2382,2387],{"type":32,"tag":95,"props":2379,"children":2380},{"style":108},[2381],{"type":37,"value":2316},{"type":32,"tag":95,"props":2383,"children":2384},{"style":102},[2385],{"type":37,"value":2386},"dbt_utils.expression_is_true",{"type":32,"tag":95,"props":2388,"children":2389},{"style":108},[2390],{"type":37,"value":131},{"type":32,"tag":95,"props":2392,"children":2393},{"class":97,"line":302},[2394,2399,2403],{"type":32,"tag":95,"props":2395,"children":2396},{"style":102},[2397],{"type":37,"value":2398},"              expression",{"type":32,"tag":95,"props":2400,"children":2401},{"style":108},[2402],{"type":37,"value":111},{"type":32,"tag":95,"props":2404,"children":2405},{"style":152},[2406],{"type":37,"value":2407},"\">= 0\"\n",{"type":32,"tag":95,"props":2409,"children":2410},{"class":97,"line":314},[2411,2415,2419,2423],{"type":32,"tag":95,"props":2412,"children":2413},{"style":108},[2414],{"type":37,"value":195},{"type":32,"tag":95,"props":2416,"children":2417},{"style":102},[2418],{"type":37,"value":145},{"type":32,"tag":95,"props":2420,"children":2421},{"style":108},[2422],{"type":37,"value":111},{"type":32,"tag":95,"props":2424,"children":2425},{"style":152},[2426],{"type":37,"value":1259},{"type":32,"tag":95,"props":2428,"children":2429},{"class":97,"line":335},[2430,2434],{"type":32,"tag":95,"props":2431,"children":2432},{"style":102},[2433],{"type":37,"value":2304},{"type":32,"tag":95,"props":2435,"children":2436},{"style":108},[2437],{"type":37,"value":131},{"type":32,"tag":95,"props":2439,"children":2440},{"class":97,"line":1369},[2441,2445,2450],{"type":32,"tag":95,"props":2442,"children":2443},{"style":108},[2444],{"type":37,"value":2316},{"type":32,"tag":95,"props":2446,"children":2447},{"style":102},[2448],{"type":37,"value":2449},"dbt_utils.recency",{"type":32,"tag":95,"props":2451,"children":2452},{"style":108},[2453],{"type":37,"value":131},{"type":32,"tag":95,"props":2455,"children":2456},{"class":97,"line":1390},[2457,2462,2466],{"type":32,"tag":95,"props":2458,"children":2459},{"style":102},[2460],{"type":37,"value":2461},"              datepart",{"type":32,"tag":95,"props":2463,"children":2464},{"style":108},[2465],{"type":37,"value":111},{"type":32,"tag":95,"props":2467,"children":2468},{"style":152},[2469],{"type":37,"value":2470},"day\n",{"type":32,"tag":95,"props":2472,"children":2473},{"class":97,"line":1407},[2474,2479,2483],{"type":32,"tag":95,"props":2475,"children":2476},{"style":102},[2477],{"type":37,"value":2478},"              interval",{"type":32,"tag":95,"props":2480,"children":2481},{"style":108},[2482],{"type":37,"value":111},{"type":32,"tag":95,"props":2484,"children":2485},{"style":114},[2486],{"type":37,"value":2487},"7\n",{"type":32,"tag":33,"props":2489,"children":2490},{},[2491,2493,2499,2501,2507],{"type":37,"value":2492},"El comando ",{"type":32,"tag":52,"props":2494,"children":2496},{"className":2495},[],[2497],{"type":37,"value":2498},"dbt test",{"type":37,"value":2500}," ejecuta estas condiciones en BigQuery como assertions — si order_amount es negativo, el build falla. En producción, cada commit corre en CI\u002FCD: ",{"type":32,"tag":52,"props":2502,"children":2504},{"className":2503},[],[2505],{"type":37,"value":2506},"dbt run --select state:modified+ → dbt test --select state:modified+",{"type":37,"value":2508},". Ejecuta el modelo modificado + dependencias downstream, prueba todo, solo permite merge si no hay problemas.",{"type":32,"tag":40,"props":2510,"children":2512},{"id":2511},"orchestración-airflow-prefect-dbt-cloud",[2513],{"type":37,"value":2514},"Orchestración: Airflow, Prefect, dbt Cloud",{"type":32,"tag":33,"props":2516,"children":2517},{},[2518],{"type":37,"value":2519},"dbt no es orquestador por sí mismo — se programa con Airflow o Prefect. Un DAG de Airflow ejemplo:",{"type":32,"tag":85,"props":2521,"children":2525},{"className":2522,"code":2523,"language":2524,"meta":16,"style":16},"language-python shiki shiki-themes github-dark","from airflow.providers.google.cloud.operators.bigquery import BigQueryInsertJobOperator\nfrom airflow.operators.bash import BashOperator\n\ndbt_run = BashOperator(\n    task_id='dbt_run',\n    bash_command='cd \u002Fopt\u002Fdbt && dbt run --profiles-dir .',\n    dag=dag\n)\n\ndbt_test = BashOperator(\n    task_id='dbt_test',\n    bash_command='cd \u002Fopt\u002Fdbt && dbt test',\n    dag=dag\n)\n\ndbt_run >> dbt_test\n","python",[2526],{"type":32,"tag":52,"props":2527,"children":2528},{"__ignoreMap":16},[2529,2552,2573,2580,2597,2619,2640,2657,2664,2671,2687,2707,2727,2742,2749,2756],{"type":32,"tag":95,"props":2530,"children":2531},{"class":97,"line":98},[2532,2537,2542,2547],{"type":32,"tag":95,"props":2533,"children":2534},{"style":433},[2535],{"type":37,"value":2536},"from",{"type":32,"tag":95,"props":2538,"children":2539},{"style":108},[2540],{"type":37,"value":2541}," airflow.providers.google.cloud.operators.bigquery ",{"type":32,"tag":95,"props":2543,"children":2544},{"style":433},[2545],{"type":37,"value":2546},"import",{"type":32,"tag":95,"props":2548,"children":2549},{"style":108},[2550],{"type":37,"value":2551}," BigQueryInsertJobOperator\n",{"type":32,"tag":95,"props":2553,"children":2554},{"class":97,"line":120},[2555,2559,2564,2568],{"type":32,"tag":95,"props":2556,"children":2557},{"style":433},[2558],{"type":37,"value":2536},{"type":32,"tag":95,"props":2560,"children":2561},{"style":108},[2562],{"type":37,"value":2563}," airflow.operators.bash ",{"type":32,"tag":95,"props":2565,"children":2566},{"style":433},[2567],{"type":37,"value":2546},{"type":32,"tag":95,"props":2569,"children":2570},{"style":108},[2571],{"type":37,"value":2572}," BashOperator\n",{"type":32,"tag":95,"props":2574,"children":2575},{"class":97,"line":134},[2576],{"type":32,"tag":95,"props":2577,"children":2578},{"emptyLinePlaceholder":1363},[2579],{"type":37,"value":1366},{"type":32,"tag":95,"props":2581,"children":2582},{"class":97,"line":158},[2583,2588,2592],{"type":32,"tag":95,"props":2584,"children":2585},{"style":108},[2586],{"type":37,"value":2587},"dbt_run ",{"type":32,"tag":95,"props":2589,"children":2590},{"style":433},[2591],{"type":37,"value":840},{"type":32,"tag":95,"props":2593,"children":2594},{"style":108},[2595],{"type":37,"value":2596}," BashOperator(\n",{"type":32,"tag":95,"props":2598,"children":2599},{"class":97,"line":176},[2600,2606,2610,2615],{"type":32,"tag":95,"props":2601,"children":2603},{"style":2602},"--shiki-default:#FFAB70",[2604],{"type":37,"value":2605},"    task_id",{"type":32,"tag":95,"props":2607,"children":2608},{"style":433},[2609],{"type":37,"value":840},{"type":32,"tag":95,"props":2611,"children":2612},{"style":152},[2613],{"type":37,"value":2614},"'dbt_run'",{"type":32,"tag":95,"props":2616,"children":2617},{"style":108},[2618],{"type":37,"value":573},{"type":32,"tag":95,"props":2620,"children":2621},{"class":97,"line":189},[2622,2627,2631,2636],{"type":32,"tag":95,"props":2623,"children":2624},{"style":2602},[2625],{"type":37,"value":2626},"    bash_command",{"type":32,"tag":95,"props":2628,"children":2629},{"style":433},[2630],{"type":37,"value":840},{"type":32,"tag":95,"props":2632,"children":2633},{"style":152},[2634],{"type":37,"value":2635},"'cd \u002Fopt\u002Fdbt && dbt run --profiles-dir .'",{"type":32,"tag":95,"props":2637,"children":2638},{"style":108},[2639],{"type":37,"value":573},{"type":32,"tag":95,"props":2641,"children":2642},{"class":97,"line":211},[2643,2648,2652],{"type":32,"tag":95,"props":2644,"children":2645},{"style":2602},[2646],{"type":37,"value":2647},"    dag",{"type":32,"tag":95,"props":2649,"children":2650},{"style":433},[2651],{"type":37,"value":840},{"type":32,"tag":95,"props":2653,"children":2654},{"style":108},[2655],{"type":37,"value":2656},"dag\n",{"type":32,"tag":95,"props":2658,"children":2659},{"class":97,"line":26},[2660],{"type":32,"tag":95,"props":2661,"children":2662},{"style":108},[2663],{"type":37,"value":986},{"type":32,"tag":95,"props":2665,"children":2666},{"class":97,"line":246},[2667],{"type":32,"tag":95,"props":2668,"children":2669},{"emptyLinePlaceholder":1363},[2670],{"type":37,"value":1366},{"type":32,"tag":95,"props":2672,"children":2673},{"class":97,"line":267},[2674,2679,2683],{"type":32,"tag":95,"props":2675,"children":2676},{"style":108},[2677],{"type":37,"value":2678},"dbt_test ",{"type":32,"tag":95,"props":2680,"children":2681},{"style":433},[2682],{"type":37,"value":840},{"type":32,"tag":95,"props":2684,"children":2685},{"style":108},[2686],{"type":37,"value":2596},{"type":32,"tag":95,"props":2688,"children":2689},{"class":97,"line":284},[2690,2694,2698,2703],{"type":32,"tag":95,"props":2691,"children":2692},{"style":2602},[2693],{"type":37,"value":2605},{"type":32,"tag":95,"props":2695,"children":2696},{"style":433},[2697],{"type":37,"value":840},{"type":32,"tag":95,"props":2699,"children":2700},{"style":152},[2701],{"type":37,"value":2702},"'dbt_test'",{"type":32,"tag":95,"props":2704,"children":2705},{"style":108},[2706],{"type":37,"value":573},{"type":32,"tag":95,"props":2708,"children":2709},{"class":97,"line":302},[2710,2714,2718,2723],{"type":32,"tag":95,"props":2711,"children":2712},{"style":2602},[2713],{"type":37,"value":2626},{"type":32,"tag":95,"props":2715,"children":2716},{"style":433},[2717],{"type":37,"value":840},{"type":32,"tag":95,"props":2719,"children":2720},{"style":152},[2721],{"type":37,"value":2722},"'cd \u002Fopt\u002Fdbt && dbt test'",{"type":32,"tag":95,"props":2724,"children":2725},{"style":108},[2726],{"type":37,"value":573},{"type":32,"tag":95,"props":2728,"children":2729},{"class":97,"line":314},[2730,2734,2738],{"type":32,"tag":95,"props":2731,"children":2732},{"style":2602},[2733],{"type":37,"value":2647},{"type":32,"tag":95,"props":2735,"children":2736},{"style":433},[2737],{"type":37,"value":840},{"type":32,"tag":95,"props":2739,"children":2740},{"style":108},[2741],{"type":37,"value":2656},{"type":32,"tag":95,"props":2743,"children":2744},{"class":97,"line":335},[2745],{"type":32,"tag":95,"props":2746,"children":2747},{"style":108},[2748],{"type":37,"value":986},{"type":32,"tag":95,"props":2750,"children":2751},{"class":97,"line":1369},[2752],{"type":32,"tag":95,"props":2753,"children":2754},{"emptyLinePlaceholder":1363},[2755],{"type":37,"value":1366},{"type":32,"tag":95,"props":2757,"children":2758},{"class":97,"line":1390},[2759,2763,2768],{"type":32,"tag":95,"props":2760,"children":2761},{"style":108},[2762],{"type":37,"value":2587},{"type":32,"tag":95,"props":2764,"children":2765},{"style":433},[2766],{"type":37,"value":2767},">>",{"type":32,"tag":95,"props":2769,"children":2770},{"style":108},[2771],{"type":37,"value":2772}," dbt_test\n",{"type":32,"tag":33,"props":2774,"children":2775},{},[2776],{"type":37,"value":2777},"dbt Cloud es la alternativa — orquestación manejada, Web IDE, alertas Slack. Pero la mayoría de empresas elige Airflow porque hay más tareas además de dbt: pull de API upstream, reverse ETL downstream, tablas snapshot.",{"type":32,"tag":33,"props":2779,"children":2780},{},[2781,2783,2789],{"type":37,"value":2782},"La estrategia de horario está vinculada a la frescura de datos. Los eventos de GA4 tienen retraso de 24 horas (processing_date ≠ event_date), la API Insights de Meta no es real-time. Los modelos de staging se gatillan según la frescura de la fuente — cuando GA4 entrega una nueva partición, ",{"type":32,"tag":52,"props":2784,"children":2786},{"className":2785},[],[2787],{"type":37,"value":2788},"stg_ga4_events",{"type":37,"value":2790}," se actualiza, la cadena intermediate → mart se propaga. Un operador sensor de Airflow verifica que BigQuery tenga la partición:",{"type":32,"tag":85,"props":2792,"children":2794},{"className":2522,"code":2793,"language":2524,"meta":16,"style":16},"wait_for_ga4 = BigQueryTableExistenceSensor(\n    task_id='wait_for_ga4_partition',\n    project_id='analytics_123456',\n    dataset_id='events_',\n    table_id=f\"events_{yesterday.strftime('%Y%m%d')}\",\n    poke_interval=300\n)\n",[2795],{"type":32,"tag":52,"props":2796,"children":2797},{"__ignoreMap":16},[2798,2815,2835,2856,2876,2941,2958],{"type":32,"tag":95,"props":2799,"children":2800},{"class":97,"line":98},[2801,2806,2810],{"type":32,"tag":95,"props":2802,"children":2803},{"style":108},[2804],{"type":37,"value":2805},"wait_for_ga4 ",{"type":32,"tag":95,"props":2807,"children":2808},{"style":433},[2809],{"type":37,"value":840},{"type":32,"tag":95,"props":2811,"children":2812},{"style":108},[2813],{"type":37,"value":2814}," BigQueryTableExistenceSensor(\n",{"type":32,"tag":95,"props":2816,"children":2817},{"class":97,"line":120},[2818,2822,2826,2831],{"type":32,"tag":95,"props":2819,"children":2820},{"style":2602},[2821],{"type":37,"value":2605},{"type":32,"tag":95,"props":2823,"children":2824},{"style":433},[2825],{"type":37,"value":840},{"type":32,"tag":95,"props":2827,"children":2828},{"style":152},[2829],{"type":37,"value":2830},"'wait_for_ga4_partition'",{"type":32,"tag":95,"props":2832,"children":2833},{"style":108},[2834],{"type":37,"value":573},{"type":32,"tag":95,"props":2836,"children":2837},{"class":97,"line":134},[2838,2843,2847,2852],{"type":32,"tag":95,"props":2839,"children":2840},{"style":2602},[2841],{"type":37,"value":2842},"    project_id",{"type":32,"tag":95,"props":2844,"children":2845},{"style":433},[2846],{"type":37,"value":840},{"type":32,"tag":95,"props":2848,"children":2849},{"style":152},[2850],{"type":37,"value":2851},"'analytics_123456'",{"type":32,"tag":95,"props":2853,"children":2854},{"style":108},[2855],{"type":37,"value":573},{"type":32,"tag":95,"props":2857,"children":2858},{"class":97,"line":158},[2859,2864,2868,2872],{"type":32,"tag":95,"props":2860,"children":2861},{"style":2602},[2862],{"type":37,"value":2863},"    dataset_id",{"type":32,"tag":95,"props":2865,"children":2866},{"style":433},[2867],{"type":37,"value":840},{"type":32,"tag":95,"props":2869,"children":2870},{"style":152},[2871],{"type":37,"value":628},{"type":32,"tag":95,"props":2873,"children":2874},{"style":108},[2875],{"type":37,"value":573},{"type":32,"tag":95,"props":2877,"children":2878},{"class":97,"line":176},[2879,2884,2888,2893,2898,2902,2907,2912,2917,2922,2927,2932,2937],{"type":32,"tag":95,"props":2880,"children":2881},{"style":2602},[2882],{"type":37,"value":2883},"    table_id",{"type":32,"tag":95,"props":2885,"children":2886},{"style":433},[2887],{"type":37,"value":840},{"type":32,"tag":95,"props":2889,"children":2890},{"style":433},[2891],{"type":37,"value":2892},"f",{"type":32,"tag":95,"props":2894,"children":2895},{"style":152},[2896],{"type":37,"value":2897},"\"events_",{"type":32,"tag":95,"props":2899,"children":2900},{"style":114},[2901],{"type":37,"value":1996},{"type":32,"tag":95,"props":2903,"children":2904},{"style":108},[2905],{"type":37,"value":2906},"yesterday.strftime(",{"type":32,"tag":95,"props":2908,"children":2909},{"style":152},[2910],{"type":37,"value":2911},"'%Y%m",{"type":32,"tag":95,"props":2913,"children":2914},{"style":114},[2915],{"type":37,"value":2916},"%d",{"type":32,"tag":95,"props":2918,"children":2919},{"style":152},[2920],{"type":37,"value":2921},"'",{"type":32,"tag":95,"props":2923,"children":2924},{"style":108},[2925],{"type":37,"value":2926},")",{"type":32,"tag":95,"props":2928,"children":2929},{"style":114},[2930],{"type":37,"value":2931},"}",{"type":32,"tag":95,"props":2933,"children":2934},{"style":152},[2935],{"type":37,"value":2936},"\"",{"type":32,"tag":95,"props":2938,"children":2939},{"style":108},[2940],{"type":37,"value":573},{"type":32,"tag":95,"props":2942,"children":2943},{"class":97,"line":189},[2944,2949,2953],{"type":32,"tag":95,"props":2945,"children":2946},{"style":2602},[2947],{"type":37,"value":2948},"    poke_interval",{"type":32,"tag":95,"props":2950,"children":2951},{"style":433},[2952],{"type":37,"value":840},{"type":32,"tag":95,"props":2954,"children":2955},{"style":114},[2956],{"type":37,"value":2957},"300\n",{"type":32,"tag":95,"props":2959,"children":2960},{"class":97,"line":211},[2961],{"type":32,"tag":95,"props":2962,"children":2963},{"style":108},[2964],{"type":37,"value":986},{"type":32,"tag":33,"props":2966,"children":2967},{},[2968],{"type":37,"value":2969},"Cuando la partición está lista, la cadena dbt comienza. Este patrón resuelve el problema de datos con retraso — en lugar de detener el pipeline por demora de API, espera.",{"type":32,"tag":40,"props":2971,"children":2973},{"id":2972},"trade-offs-qué-dbt-no-resuelve",[2974],{"type":37,"value":2975},"Trade-offs: Qué dbt no resuelve",{"type":32,"tag":33,"props":2977,"children":2978},{},[2979,2981,2986],{"type":37,"value":2980},"dbt es motor de transformación, no data loader. ¿Quién extrae datos a BigQuery? Fivetran, Airbyte, script Python personalizado. dbt asume en ",{"type":32,"tag":52,"props":2982,"children":2984},{"className":2983},[],[2985],{"type":37,"value":81},{"type":37,"value":2987}," que los datos crudos ya están ahí. Patrón ELT: Extract-Load-Transform. La diferencia con ETL es que Transform ocurre dentro del warehouse. dbt es esa capa T, EL es otra cadena de herramientas.",{"type":32,"tag":33,"props":2989,"children":2990},{},[2991],{"type":37,"value":2992},"dbt no soporta streaming en tiempo real. Kafka → inserción streaming de BigQuery → cadena de modelo incremental de dbt agrega latencia de minutos. Si necesitas latencia sub-segundo (detección de fraude, pricing dinámico), dbt no es suficiente — necesitas procesador de streams: Flink, Spark Structured Streaming, Materialize.",{"type":32,"tag":33,"props":2994,"children":2995},{},[2996],{"type":37,"value":2997},"El soporte de modelo Python en dbt (v1.3+) es limitado. Puedes hacer manipulación de dataframe Pandas pero no entrenas modelos ML pesados en dbt. El patrón común es: feature engineering en dbt, entrenamiento de modelo en Vertex AI, inferencia en BigQuery ML. Un modelo Python de dbt es así:",{"type":32,"tag":85,"props":2999,"children":3001},{"className":2522,"code":3000,"language":2524,"meta":16,"style":16},"def model(dbt, session):\n    df = dbt.ref('stg_orders').to_pandas()\n    df['log_amount'] = np.log1p(df['order_amount'])\n    return df\n",[3002],{"type":32,"tag":52,"props":3003,"children":3004},{"__ignoreMap":16},[3005,3024,3051,3088],{"type":32,"tag":95,"props":3006,"children":3007},{"class":97,"line":98},[3008,3013,3019],{"type":32,"tag":95,"props":3009,"children":3010},{"style":433},[3011],{"type":37,"value":3012},"def",{"type":32,"tag":95,"props":3014,"children":3016},{"style":3015},"--shiki-default:#B392F0",[3017],{"type":37,"value":3018}," model",{"type":32,"tag":95,"props":3020,"children":3021},{"style":108},[3022],{"type":37,"value":3023},"(dbt, session):\n",{"type":32,"tag":95,"props":3025,"children":3026},{"class":97,"line":120},[3027,3032,3036,3041,3046],{"type":32,"tag":95,"props":3028,"children":3029},{"style":108},[3030],{"type":37,"value":3031},"    df ",{"type":32,"tag":95,"props":3033,"children":3034},{"style":433},[3035],{"type":37,"value":840},{"type":32,"tag":95,"props":3037,"children":3038},{"style":108},[3039],{"type":37,"value":3040}," dbt.ref(",{"type":32,"tag":95,"props":3042,"children":3043},{"style":152},[3044],{"type":37,"value":3045},"'stg_orders'",{"type":32,"tag":95,"props":3047,"children":3048},{"style":108},[3049],{"type":37,"value":3050},").to_pandas()\n",{"type":32,"tag":95,"props":3052,"children":3053},{"class":97,"line":134},[3054,3059,3064,3069,3073,3078,3083],{"type":32,"tag":95,"props":3055,"children":3056},{"style":108},[3057],{"type":37,"value":3058},"    df[",{"type":32,"tag":95,"props":3060,"children":3061},{"style":152},[3062],{"type":37,"value":3063},"'log_amount'",{"type":32,"tag":95,"props":3065,"children":3066},{"style":108},[3067],{"type":37,"value":3068},"] ",{"type":32,"tag":95,"props":3070,"children":3071},{"style":433},[3072],{"type":37,"value":840},{"type":32,"tag":95,"props":3074,"children":3075},{"style":108},[3076],{"type":37,"value":3077}," np.log1p(df[",{"type":32,"tag":95,"props":3079,"children":3080},{"style":152},[3081],{"type":37,"value":3082},"'order_amount'",{"type":32,"tag":95,"props":3084,"children":3085},{"style":108},[3086],{"type":37,"value":3087},"])\n",{"type":32,"tag":95,"props":3089,"children":3090},{"class":97,"line":158},[3091,3096],{"type":32,"tag":95,"props":3092,"children":3093},{"style":433},[3094],{"type":37,"value":3095},"    return",{"type":32,"tag":95,"props":3097,"children":3098},{"style":108},[3099],{"type":37,"value":3100}," df\n",{"type":32,"tag":33,"props":3102,"children":3103},{},[3104],{"type":37,"value":3105},"Solo genera features — no ajustas scikit-learn. BigQuery compute es caro, el overhead de runtime Python es alto. Transformaciones complejas son más rápidas en SQL.",{"type":32,"tag":40,"props":3107,"children":3109},{"id":3108},"ahora-qué-hacer",[3110],{"type":37,"value":3111},"Ahora qué hacer",{"type":32,"tag":33,"props":3113,"children":3114},{},[3115,3117,3122,3124,3129],{"type":37,"value":3116},"Si tus datos de marketing aún están en spreadsheets con fusión manual, el primer paso es establecer flujo de datos crudos a BigQuery. Exporta GA4, conecta APIs de Meta\u002FGoogle Ads (Fivetran\u002FSupermetrics), webhook de CRM → inserción streaming BigQuery. Cuando los datos crudos están listos, abres repositorio dbt: modelos de staging hacen mapeo de fuentes, intermediate hace sesionización\u002Fatribución, mart genera KPI final. Las primeras 2 semanas necesitas solo tabla ",{"type":32,"tag":52,"props":3118,"children":3120},{"className":3119},[],[3121],{"type":37,"value":1076},{"type":37,"value":3123}," y ",{"type":32,"tag":52,"props":3125,"children":3127},{"className":3126},[],[3128],{"type":37,"value":1069},{"type":37,"value":3130}," — los dashboards apuntan aquí, las métricas se estabilizan. Semantic layer llega en semana 3, mapping de exposures en semana 4. En 6 semanas, el pipeline en producción corre git-controlled, test-covered, optimizado",{"type":32,"tag":3132,"props":3133,"children":3134},"style",{},[3135],{"type":37,"value":3136},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":134,"depth":134,"links":3138},[3139,3140,3141,3142,3143,3144,3145,3146],{"id":42,"depth":120,"text":45},{"id":402,"depth":120,"text":405},{"id":1105,"depth":120,"text":1108},{"id":1523,"depth":120,"text":1526},{"id":1906,"depth":120,"text":1909},{"id":2511,"depth":120,"text":2514},{"id":2972,"depth":120,"text":2975},{"id":3108,"depth":120,"text":3111},"markdown","content:es:data:dbt-bigquery-modern-marketing-data-stack.md","content","es\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack.md","es\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","md",1782050753423]