Part 14 — Full End-to-End Project and Architecture Blueprint
This is the final part of the series. Parts 1 through 13 covered every layer of a modern data platform individually — dimensional modeling, architecture selection, medallion design, ingestion, transformations, warehouse and lakehouse implementation, semantic layers, orchestration, data quality, performance engineering, and governance. This part assembles all of it into a single, cohesive, end-to-end reference architecture and a capstone project that walks through the complete implementation from scratch.
By the end of this part you will have a blueprint you can use as the starting point for any enterprise analytics project, a complete tool selection matrix mapping every layer to every major platform, and three progressive workshop projects — from a basic star schema pipeline to a full enterprise-grade governed analytics platform.
How to use this part: Read Section 1 for the complete architecture overview and diagram. Use Section 2 as a reference when selecting tools for a new project. Use Sections 3 through 10 as a walkthrough of the complete implementation. The workshops at the end are the capstone projects — work through them in order to build everything from scratch in your chosen platform.
- Layer 1: Ingestion and Bronze
- Layer 2: Silver Transformation
- Layer 3: Gold Dimensional Models
- Layer 4: Warehouse or Lakehouse Physical Implementation
- Layer 5: Semantic Layer and BI
- Layer 6: Orchestration and Automation
- Layer 7: Data Quality and Observability
- Layer 8: Security, Governance, and Compliance
1 The Complete Architecture Everyone
The architecture below represents the production-grade analytical platform built across this series. Every component maps to one or more parts. The layered design is intentional — each layer has clear inputs, outputs, and responsibilities, making the system modular, testable, and replaceable one layer at a time as technology evolves.
2 Full Tool Selection Matrix Everyone
| Layer | Snowflake | Databricks | BigQuery | Fabric | AWS |
|---|---|---|---|---|---|
| Storage | Micro-partitions / Iceberg | Delta Lake on ADLS/S3 | Colossus / BigLake | Delta on OneLake | Iceberg on S3 |
| Ingestion | Snowpipe / Fivetran | Auto Loader / Fivetran | BigQuery Transfer / Fivetran | Fabric Pipelines / ADF | Glue / DMS / Fivetran |
| Transformation | dbt + Snowflake SQL | dbt + PySpark + SQL | dbt + BigQuery SQL | dbt + T-SQL + Spark | dbt + Glue PySpark |
| Orchestration | Airflow / dbt Cloud / Tasks | Databricks Workflows | Cloud Composer (Airflow) | Fabric Data Pipelines | Step Functions / MWAA |
| Semantic Layer | Dynamic Tables / Views | Databricks SQL / Views | Looker / BI Engine | Power BI Semantic Model | QuickSight / Looker |
| Data Quality | dbt + Soda + Monte Carlo | dbt + GE + Monte Carlo | dbt + GE + BigQuery DQ | dbt + Soda + Data Activator | dbt + GE + Soda |
| Governance | Snowflake tags + policies | Unity Catalog | IAM + Data Catalog | Microsoft Purview | Lake Formation + Glue Catalog |
| BI Tool | Tableau / Looker / Power BI | Power BI / Tableau / Looker | Looker / Looker Studio | Power BI (native) | QuickSight / Tableau |
3 Layer 1: Ingestion and Bronze Beginner
Bronze ingestion is the entry point for all data. The goal is simple: land raw data reliably, preserve it exactly as received, and track when it arrived. Every decision here is about reliability and completeness — not transformation.
Checklist: Bronze Layer Ready
- Ingestion tool configured and tested for each source (Fivetran, Airbyte, Auto Loader, Snowpipe, Glue, or ADF)
- Bronze folder structure follows the
/lake/bronze/{source}/{entity}/year=/month=/day=/pattern - Ingestion metadata columns added:
_ingested_at,_source_file - Schema drift handling configured: allow new columns in Bronze, block in Silver
- Freshness SLAs defined and monitored via dbt source freshness or Soda
- CDC enabled on source databases where deletion tracking is required
- Unknown key row (-1) inserted in all Gold dimension tables before fact loads begin
-- Bronze setup verification query
-- Run after ingestion to confirm data arrived and metadata columns are populated
SELECT
COUNT(*) AS total_rows,
MIN(_ingested_at) AS earliest_ingestion,
MAX(_ingested_at) AS latest_ingestion,
COUNT(DISTINCT _source_file) AS source_files,
SUM(CASE WHEN customer_id IS NULL
THEN 1 ELSE 0 END) AS null_key_count
FROM bronze.crm_customer
WHERE _ingested_at >= DATEADD('hour', -25, CURRENT_TIMESTAMP());
-- Expected: total_rows > 0, latest_ingestion within last 24 hours, null_key_count = 0
4 Layer 2: Silver Transformation Beginner
Silver cleans, conforms, and deduplicates Bronze data. The schema contract is enforced here — every downstream consumer relies on Silver having consistent column names, types, and no duplicates. Business logic stays out of Silver entirely.
Checklist: Silver Layer Ready
- One dbt staging model per Bronze source table
- All required fields have not-null tests defined
- Unique test on natural key column confirms deduplication is effective
- Accepted values tests on domain columns (loyalty_tier, status, etc.)
- Incremental model with
incremental_strategy = 'merge'for mutable sources - JSON flattening applied for any nested Bronze sources
- Natural keys pass through Silver unchanged — no surrogate key lookups
- Silver quality gate blocks Gold pipeline if any dbt test fails
# Verify Silver layer health after transformation run
# Run via dbt or directly in your warehouse
# Count comparison: Bronze vs Silver row counts
SELECT
'bronze.crm_customer' AS layer,
COUNT(*) AS row_count,
COUNT(DISTINCT customer_id) AS unique_keys
FROM bronze.crm_customer
UNION ALL
SELECT
'silver.customer',
COUNT(*),
COUNT(DISTINCT customer_id)
FROM silver.customer;
-- Expected: Silver unique_keys should equal or be slightly less than Bronze
-- (deduplication removes duplicates -- Silver should never have MORE unique keys than Bronze)
5 Layer 3: Gold Dimensional Models Intermediate
Gold implements the dimensional model from Part 1. This is the most sensitive layer to bugs — errors here produce incorrect KPIs that analysts may trust for weeks before detecting them. The two-step SCD Type 2 pattern, the unknown key row, the grain validation query, and the referential integrity test are all non-negotiable.
Checklist: Gold Layer Ready
- Unknown key row (-1) in every dimension before any fact loads
- DimDate populated for all dates from earliest historical data through 10 years future
- SCD Type 2 two-step pattern: MERGE to close, INSERT to open new version
- SCD2 verification query: each natural key has exactly one
is_current = 1row - Fact load uses LEFT JOIN with COALESCE to assign unknown key for late-arriving dimensions
- Grain validation query: zero duplicate
order_line_keyvalues in fact table - Referential integrity dbt test on all foreign key columns in fact table
- Revenue reasonableness check: no negative
extended_amountvalues - Gold quality gate blocks semantic refresh if any test fails
-- Gold health check: run after every pipeline execution
-- Returns one row per check -- all should show PASS
SELECT 'SCD2 integrity' AS check_name,
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END AS status,
COUNT(*) AS failing_rows
FROM (
SELECT customer_natural_key, COUNT(*) AS cnt
FROM gold.dim_customer WHERE is_current = 1
GROUP BY customer_natural_key HAVING cnt > 1
)
UNION ALL
SELECT 'Grain: no duplicate order line keys',
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END,
COUNT(*)
FROM (
SELECT order_line_key, COUNT(*) AS cnt
FROM gold.fct_order_line
GROUP BY order_line_key HAVING cnt > 1
)
UNION ALL
SELECT 'No negative revenue',
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END,
COUNT(*)
FROM gold.fct_order_line
WHERE extended_amount < 0
UNION ALL
SELECT 'No orphan fact rows (unknown key check)',
CASE WHEN COUNT(*) = 0 THEN 'PASS' ELSE 'FAIL' END,
COUNT(*)
FROM gold.fct_order_line
WHERE customer_key = -1;
-- Last check: customer_key = -1 means a late-arriving dimension -- investigate source
6 Layer 4: Warehouse or Lakehouse Physical Implementation Intermediate
The physical implementation of Gold tables — clustering keys, partitioning, distribution strategies, file format — determines query performance and cost. The checklist below covers the most impactful physical decisions for each platform.
Checklist: Physical Implementation Ready
- Snowflake: clustering key added on
fct_order_line(order_date_key, customer_key)for tables over 100M rows. Auto-suspend set to 60–120 seconds. Separate warehouses for ETL and BI workloads. - Fabric Warehouse: COPY INTO used for bulk loads. Direct Lake connection confirmed for Power BI. V-Order enabled for optimal Direct Lake read performance.
- BigQuery: fact table partitioned by
order_date, clustered bycustomer_key, product_key. Dry-run cost estimate verified before first production load. BI Engine reservation created for dashboard workloads. - Databricks: Liquid Clustering enabled on Gold fact and dimension tables. Auto-optimize TBLPROPERTIES set. Unity Catalog permissions applied by schema.
- Synapse: fact table HASH distributed on
customer_key. Small dimensions REPLICATED. Distribution skew check confirms even distribution. - Redshift: DISTKEY on
customer_key, COMPOUND SORTKEY on(order_date_key, customer_key). RA3 nodes configured. Spectrum external schema for Bronze S3 access.
-- Universal performance baseline query
-- Run before and after physical optimization to measure improvement
-- Replace schema/table names for your platform
SELECT
CURRENT_TIMESTAMP() AS run_time,
COUNT(DISTINCT f.customer_key) AS unique_customers,
COUNT(*) AS total_order_lines,
SUM(f.extended_amount) AS total_revenue,
AVG(f.extended_amount) AS avg_order_value,
MIN(d.full_date) AS earliest_order,
MAX(d.full_date) AS latest_order
FROM gold.fct_order_line f
JOIN gold.dim_date d ON f.order_date_key = d.date_key
JOIN gold.dim_customer c ON f.customer_key = c.customer_key
AND c.is_current = 1
WHERE d.year = 2025;
-- Record: execution time, bytes scanned, partitions read
-- Re-run after adding clustering/partitioning to measure improvement
7 Layer 5: Semantic Layer and BI Intermediate
The semantic layer is the governed surface that connects Gold tables to BI consumers. Every KPI must be defined here — not in individual dashboards. Access control (RLS) must be applied here — not in individual reports.
Checklist: Semantic Layer Ready
- All surrogate key columns hidden from analyst view
- All SCD2 metadata columns hidden (EffectiveFrom, EffectiveTo, IsCurrent)
- Revenue, Customer Count, Avg Order Value, and Gross Margin measures defined once
- Date hierarchy defined: Year → Quarter → Month → Week → Day
- Product hierarchy defined: Category → Subcategory → Product
- Geography hierarchy defined: Country → Region → State → City
- Row-level security roles defined and tested with at least two different user roles
- Aggregation table created for monthly revenue summary (most common BI query pattern)
- All metric definitions documented with owner, definition, and data source
-- DAX: core KPI measures for Power BI semantic model
-- These are the minimum viable measure set for a retail analytics model
Revenue =
SUM ( FctOrderLine[ExtendedAmount] )
Revenue YTD =
CALCULATE ( [Revenue], DATESYTD ( DimDate[FullDate] ) )
Revenue YoY % =
VAR Curr = CALCULATE ( [Revenue], YEAR(DimDate[FullDate]) = YEAR(TODAY()) )
VAR Prev = CALCULATE ( [Revenue], YEAR(DimDate[FullDate]) = YEAR(TODAY()) - 1 )
RETURN DIVIDE ( Curr - Prev, Prev, BLANK() )
Customer Count =
DISTINCTCOUNT ( FctOrderLine[CustomerKey] )
Avg Order Value =
DIVIDE ( [Revenue], DISTINCTCOUNT ( FctOrderLine[OrderLineKey] ), BLANK() )
Gross Margin % =
DIVIDE (
SUM ( FctOrderLine[ExtendedAmount] ) - SUM ( FctOrderLine[CostAmount] ),
SUM ( FctOrderLine[ExtendedAmount] ),
BLANK()
)
8 Layer 6: Orchestration and Automation Intermediate
The orchestration layer ties every previous layer together into a scheduled, monitored, automatically recovering pipeline. Nothing in this system should require manual intervention for normal operations.
Checklist: Orchestration Ready
- All Bronze ingestion tasks run in parallel (no unnecessary serialization)
- Silver waits for all Bronze tasks to complete successfully
- Silver quality gate blocks Gold on dbt test failure
- Gold dimension tables run in parallel after Silver quality gate
- Gold fact table waits for all dimension tables to complete
- Gold quality gate blocks semantic refresh on test failure
- Semantic model refresh triggered via REST API after Gold quality gate passes
- All tasks configured with 3 retries and exponential backoff
- Email or Slack alert on any pipeline failure
- SLA set: full pipeline must complete within 4 hours of scheduled start
- Data freshness monitoring table updated after each successful pipeline run
- Orchestrator scheduled at 3 AM daily (after source systems complete their nightly processing)
9 Layer 7: Data Quality and Observability Intermediate
Quality is not a final-layer concern — it runs at every layer. The quality stack defined in Part 11 is only valuable if it is actually blocking the pipeline when it fails and alerting the team before stakeholders discover problems.
Checklist: Data Quality Ready
- dbt source freshness configured for all Bronze sources with warn and error thresholds
- dbt schema tests: not_null, unique, accepted_values, relationships on all Silver and Gold models
- Custom SQL tests for SCD2 integrity, grain validation, and no negative revenue
- Great Expectations or Soda suite for Bronze file validation (row count, schema, null rates)
- Quality results written to orchestration.quality_results table after each run
- Soda
change for row_countcheck detecting volume anomalies relative to historical median - Statistical anomaly detection query for daily revenue deviation (Z-score > 3 = alert)
- Monte Carlo or equivalent observability tool connected to Gold tables for ML-based anomaly detection
- Quality dashboard published showing pass/fail rates per layer per day
10 Layer 8: Security, Governance, and Compliance Intermediate
Governance is applied from day one — not retrofitted after the platform is in use. The security model must be complete before analysts connect their first BI tool.
Checklist: Governance Ready
- SSO configured: all users authenticate via Entra ID, Okta, or GCP Identity
- RBAC applied: separate roles for data-engineers, analysts, bi-team, pipeline-service-account
- Analysts cannot query Bronze or Silver — Gold and semantic layer only
- Column masking applied to PII columns: email, customer_name, phone_number
- Row-level security applied to fact table if multi-tenant or regional access restrictions apply
- PII columns tagged in Unity Catalog, Snowflake tags, or Purview classification
- Lineage confirmed end-to-end: Bronze source → Silver → Gold → semantic model → BI report
- Audit logging verified: test query access appears in ACCOUNT_USAGE or system.access.audit
- GDPR erasure procedure documented and tested against a non-production customer ID
- Encryption at rest confirmed for all Gold tables and Bronze storage
11 Eight Principles That Never Change Everyone
Platforms change. Tools are replaced. Cloud providers release new capabilities every quarter. But these eight principles have been true for every successful analytics platform built over the past decade, and they will remain true for the next one. Build your architecture around these principles and it will survive the inevitable technology changes ahead.
- ELT beats ETL in modern architectures. Push transformation to the engine nearest the data. Raw data stays preserved in Bronze. Compute scales with the warehouse.
- Bronze → Silver → Gold is universal. This pattern works on every platform. The layer names may differ — raw, trusted, refined; landing, cleansed, curated — but the separation of concerns is always the same.
- Dimensional modeling still matters. Even in lakehouses, ML systems, and AI pipelines, a clean dimensional model makes analytics faster, more consistent, and easier to govern than a flat wide table or a document store.
- The semantic layer owns the metrics. Business logic must not live in dashboards. Define revenue, churn, MRR, and every other KPI once in the semantic layer. Enforce it everywhere.
- Data quality must be automated. Manual validation does not scale. Automated tests that block the pipeline when they fail are the only reliable protection against bad data reaching stakeholders.
- Governance is a design constraint, not an afterthought. Access control, masking, lineage, and auditing designed in from the start are an hour of work. Retrofitted after two years of unsecured operation, they are months of work and considerable organizational disruption.
- Performance engineering is deliberate. Partitioning, clustering, and file management decisions made at design time prevent expensive rewrites six months later when the platform slows down under production load.
- Orchestration is the glue. Every pipeline fails without reliable scheduling, dependency management, quality gates, and automatic recovery. An unorchestrated pipeline is a manual process with extra steps.
12 The Series Index — All 15 Articles Everyone
13 Workshops — The Capstone Projects
Novice
Build a Mini End-to-End Pipeline
- Ingest a CSV file into Bronze (OneLake Files or S3)
- Clean into a Silver Delta table using Spark or dbt
- Build DimCustomer and DimDate in Gold
- Build FctOrderLine with surrogate key lookups
- Connect Power BI or a SQL client to the Gold schema
- Run the Gold health check query — verify all checks PASS
- Create a Revenue by Month bar chart
Intermediate
Add Orchestration and Quality
- Build dbt models for all Silver and Gold layers
- Add not_null, unique, relationships tests to all Gold models
- Create an Airflow DAG or Fabric Pipeline with Bronze → Silver → Gold → Semantic order
- Add dbt quality gates between Silver and Gold, and before semantic refresh
- Configure email alert on pipeline failure
- Schedule daily at 3 AM and verify successful execution in orchestrator UI
- Intentionally break a Silver test — confirm pipeline stops at the quality gate
Advanced
Full Enterprise Architecture
- Build Bronze/Silver/Gold in Delta Lake (Fabric or Databricks) or Snowflake
- Implement SCD Type 2 with two-step MERGE and verification queries
- Add the unknown key pattern and test late-arriving dimension recovery
- Apply Unity Catalog or Snowflake RBAC: separate roles for engineers and analysts
- Apply column masking on email column — test with both roles
- Build dbt Metrics for Revenue and Customer Count — validate against DAX measures
- Add partitioning and clustering — benchmark query time before and after
- Configure Monte Carlo or Soda Cloud for observability on Gold tables
- Implement the GDPR erasure procedure for a test customer
- Deploy CI/CD: dbt tests run automatically on every pull request
References
- Microsoft Fabric — Get Started
- Databricks Documentation
- Snowflake Documentation
- Google BigQuery Documentation
- dbt — Introduction and Architecture
- Fivetran Documentation
- Airbyte Documentation
- Azure Data Factory
- AWS Glue Documentation
- Delta Lake Documentation
- Apache Iceberg Documentation
- Apache Parquet Documentation
- Kimball Group — Dimensional Modeling Techniques
- Microsoft — Power BI Semantic Models
- Looker — LookML Introduction
- Apache Airflow Documentation
- Great Expectations Documentation
- Soda Core Documentation
- Monte Carlo Data Observability
- Databricks Unity Catalog
- Microsoft Purview
Discover more from SQLYARD
Subscribe to get the latest posts sent to your email.


