Use dbt at the warehouse boundary
LeapView integrates with dbt by consuming the physical data product that dbt publishes. dbt remains the transformation runtime; LeapView remains the BI serving runtime.
raw inputs -> dbt staging -> dbt marts -> warehouse relation or Parquet
|
LeapView Connection -> Source -> thin Model -> SemanticModel -> Dashboard
The boundary is the physical relation, including its locator, schema, grain,
freshness, and publication state. manifest.json and run_results.json are not
serving inputs and are not accepted as evidence that physical publication
completed.
Evidence status
The integration has three deliberately separate evidence classes:
- Proven local —
task dbt:warehousebuilds the pinned dbt project, verifies the exact two physical Parquet marts, and runs them through the ordinary local LeapView candidate lifecycle. - Structurally validated, not live Azure — the CI contract and the manual Azure reference are YAML-validated for ordering, trusted-ref gating, immutable publication, credential scope, and CI-gate wiring. Repository CI does not exercise live Azure OIDC, storage retention, or Azure RBAC.
- Project-free source root — the profile is discovered from conventional
resource directories. The target-bound Project identity remains supplied by
LEAPVIEW_WORKLOAD_PROJECT; it is not authored in the source tree.
Run the local showcase
From the repository root, run:
task dbt:warehouse
The task prepares the versions pinned in
examples/dbt-warehouse-boundary/dbt/requirements.txt, runs dbt build, and
verifies that the exact two expected non-empty Parquet files exist. It then
delegates to the repository's managed LeapView development flow, synchronizes
those files through the ordinary managed Connection, builds and qualifies a
candidate, publishes it, and starts the dashboard server. No paths need manual
editing.
The non-interactive CI equivalent is:
task dbt:warehouse:qualify
dbt staging and mart SQL owns normalization, joins, and aggregation. The
LeapView Models only select fields, assign the stable snake_case BI field
IDs, perform safe casts, and enforce the consumer-side contract. The
SemanticModel adds labels such as “Customer region” and formats revenue and
average order value as currency without another cosmetic physical
transformation.
The Source schema is strict about physical field names and types. Its fields remain nullable because portable Parquet discovery does not carry dbt's row-level non-null proof; error-severity Model checks re-establish that proof against the candidate's actual rows before activation.
Removing dbt's target/, manifest, or run-results files after publication does
not affect LeapView. Serving also requires no Python installation, dbt binary,
dbt profile, package credentials, or transformation credentials.
Use the production Azure reference
.github/workflows/dbt-warehouse-boundary-reference.yml is a deliberately
manual, copyable reference. Its production job runs only when manually
dispatched from the repository's protected default branch, using GitHub's
github.ref, github.event.repository.default_branch, and
github.ref_protected context. Configure its
dbt-warehouse-boundary-production GitHub environment with:
DBT_PRODUCER_CLIENT_ID,AZURE_TENANT_ID, andAZURE_SUBSCRIPTION_IDvariables for the producer's Azure OIDC login;DBT_PRODUCER_STORAGE_ACCOUNT,DBT_PRODUCER_SOURCE_CONTAINER, andDBT_PRODUCER_PUBLICATION_CONTAINERvariables;- the LeapView target URL and workload Project ID variables; and
LEAPVIEW_WORKLOAD_CLIENT_IDandLEAPVIEW_WORKLOAD_CLIENT_SECRETsecrets.
The following IAM scopes are operator requirements, not live authorization
evidence supplied by this repository: the producer identity must read only the
two bounded reference inputs and create objects only in the publication
container; the LeapView azure_blob Source binding must read only that
publication container (and, where supported, its selected prefix); and the
DuckLake/serving binding must write only LeapView-owned physical storage. The
reference workflow does not claim live Azure RBAC or checksum evidence.
The workflow runs dbt and its tests, verifies the local physical files, creates
a globally namespaced prefix from the repository, workflow run, attempt, and
Git revision, uploads exactly the selected marts without overwrite, and lists
the prefix to prove that the complete expected set exists. The producer job
then ends its Azure session and exposes only the non-secret prefix to a separate
activation job. That job has no Azure OIDC permission; it renders an ordinary
Azure-backed Connection/Source source root and invokes leapview dev --once --no-browser followed by leapview publish. The target binds the durable
Project identity from LEAPVIEW_WORKLOAD_PROJECT.
The LeapView target owns two credentials that are not present in the producer workflow:
- the
azure_blobSource binding has read-only access to the publication container (and should be scoped to its prefix where the target supports it); - the DuckLake/serving binding has write access only to LeapView-owned physical storage.
These are three distinct authorities: producer write, Source read, and DuckLake write. Never copy the producer's Azure profile or dbt credentials into LeapView. GitHub masks configured secrets, and the reference commands suppress Azure response bodies and dbt row output. Do not add raw-data previews or credential-bearing artifacts to the workflow.
Choose the consistency contract
An ordinary mutable relation or several independently observed Sources provide the consistency promised by their connector and producer. LeapView does not claim that independent upstream reads occurred at one point in time. Candidate activation is atomic only after the selected inputs have been read and the LeapView Models have been materialized and qualified.
For coordinated marts, publish the complete set under one new immutable versioned prefix (or use a warehouse transaction/snapshot with equivalent semantics). Start LeapView only after exact file-set verification succeeds. The reference workflow never selects a partially uploaded prefix and never rewrites an admitted prefix. No publication marker, dbt-specific release type, or custom release envelope is involved. If an upload fails, an orphan partial prefix remains unselected; storage lifecycle retention is the cleanup and retention mechanism. Recovery must not mutate or reinterpret that prefix.
Verify failure and recovery behavior
| Failure | Result |
|---|---|
| dbt compilation or test failure | Publication and LeapView steps do not run. |
| upload failure or partial file set | Verification fails and LeapView does not run. |
| stale Source observation | ADR-0010 freshness qualification blocks activation. |
| malformed Parquet or incompatible schema | Source discovery/materialization blocks the candidate. |
| invalid grain or failed Model check | ADR-0010 qualification blocks activation. |
| LeapView activation failure | Existing activation/reconciliation leaves the prior generation selected. |
Producer objects are not deleted or mutated to recover LeapView. Existing Project/environment-scoped candidate cleanup, retained generations, rollback, leases, and recovery remain authoritative. Orphan partial publication prefixes remain unselected and require storage lifecycle retention, not recovery mutation.
Ingestion minimization and semantic policy solve different problems. The producer should omit unnecessary columns and rows before publication. LeapView masking, row-level access, and semantic permissions govern downstream serving; they do not retroactively minimize what LeapView ingested.
Deferred features
The v1 integration intentionally does not include dbt artifact import, MetricFlow, dbt Semantic Layer import, immutable data promotion across environments, or cross-Project imports. A future metadata importer may assist authoring, but it must remain optional and reconcile against physical data rather than becoming runtime authority.