Rebtel Intercom Export
Purpose
Deliver Rebtel’s Intercom marts from Majority’s BigQuery warehouse for use in Rebtel’s data warehouse.
Ownership
- Owner: Data team across both stacks
- Source stack: Majority (
BigQuery,GCS,Airflow) - Destination stack: Rebtel (
Snowflake; loading proposed)
Delivery
- The Majority-stack
intercom_rebtel_api_exportpipeline ingests the Rebtel workspace, buildsdbt_rebtel, then exports selected marts as fullParquetsnapshots. - dt-reporting owns the exporter and manifest contract; the
DAGowns the table allowlist. - Output lands in
gs://rebtel-intercom-exports-prodinreverse-etl-pipelines-prod, with equivalent-devresources forStage Airflow. - dt-gcp-infrastructure manages the buckets and workload-identity access using the shared storage module defaults; no automatic deletion rule is configured.
- The current delivery stops at
GCS; direct loading into Rebtel’sSnowflakeis proposed below and is not yet implemented.
Delivery contract and recovery
- Snapshot folders use
snapshots/<UTC-run-timestamp>/<attempt-uuid>/, with theAirflowrun start time formatted as2026-10-20T16-09-05Z; retries keep the timestamp and get a fresh attempt ID. - To find the newest run, choose the greatest timestamp with a completed
manifest.json; usecompleted_atto choose among successful attempts of that run. - Consume only attempts with a completed
manifest.json; it lists exact files, row counts and source schemas. - Treat every table as a replacement snapshot, including zero-row tables; deduplicate completed attempts by
run_id. - Keep the
DAGlimited to one active run and avoid independent source rebuilds during export; tables are captured sequentially. - A failed export leaves an incomplete attempt without a manifest. Retry only
export_parquetafter fixing the error; incomplete attempts remain inGCSuntil explicitly deleted. - A retry captures current source data under a fresh attempt ID, so clearing an old run does not reconstruct its historical contents.
- Deploy bucket/IAM changes first, the
dt-reportingimage second, and theDAGlast; validate a manual stage run before production rollout.
Proposed direct Snowflake loading
- Target flow:
BigQuery → GCS → Snowflake, using the existing snapshots without anS3copy. - In the Rebtel stack:
Snowflakestorage integration, externalParquetstage, destination tables and scheduled loader - In the Majority stack, grant the integration’s generated Google service account
storage.buckets.get,storage.objects.getandstorage.objects.liston the export bucket; see the Snowflake integration guide. - The loader discovers completed manifests and uses
COPY INTOto load only their listed files into staging tables. - Validate schemas and row counts before replacing destination contents, including clearing tables with zero-row snapshots; retain the previous published snapshot if validation fails.
- Record the published
run_idandbatch_idto make retries idempotent and prevent older runs from replacing newer snapshots. - Schedule manifest-based loading rather than loading each arriving file independently; the manifest is the batch completion signal.