TL;DR — Plataforma de dados end-to-end (open-source) que espelha, em OSS, uma arquitetura de produção:
dlt→dbt(Medallion, contracts, Semantic Layer, dbt Mesh) →Airflow+ Cosmos → Data Quality (Soda) → observabilidade/lineage (OpenLineage) → BI (Evidence.dev) → CI/CD + IaC (Terraform). Roda 100% offline em DuckDB (reprodutível) e é portável para Databricks (Unity Catalog + Delta) sem mudar o SQL.An end-to-end, open-source data platform mirroring a production lakehouse architecture — dev runs fully on DuckDB, prod on Databricks.
Monorepo de uma plataforma de dados de auditoria de vale-pedágio — da transformação à orquestração. Dados sintéticos (nenhum dado real de cliente).
toll-analytics-platform/
├── ingestion-toll-analytics/ # INGESTÃO/EL (dlt → schema landing no DuckDB)
├── streaming-toll-analytics/ # STREAMING near-real-time (Redpanda/Kafka → micro-batch)
├── dbt-toll-analytics/ # TRANSFORMAÇÃO (dbt + DuckDB dev / Databricks prod)
├── dbt-toll-exec/ # dbt MESH: downstream que consome os models public
├── quality-toll-analytics/ # DATA QUALITY independente (Soda Core)
├── bi-toll-analytics/ # BI / serving (Evidence.dev → site estático)
├── airflow-toll-analytics/ # ORQUESTRAÇÃO (Airflow + Astronomer Cosmos)
├── infra/terraform/ # IaC do warehouse de prod (Databricks/Unity Catalog)
├── .pre-commit-config.yaml # qualidade antes do commit (ruff, yaml, etc.)
└── .github/workflows/ # CI/CD dos projetos (rodam por working-directory)
📖 Novo no projeto? Comece pelo GUIA_DBT_E_AIRFLOW.md — passo a passo do que dbt e Airflow fazem, como funcionam por dentro e os comandos do dia a dia.
flowchart LR
CSV["Arquivos CSV"]
EV["Eventos (tempo real)"]
subgraph ING["Ingestao - Fases 4 e 10"]
DLT["dlt (EL)"]
KAFKA["Redpanda/Kafka<br/>produtor -> consumidor"]
end
LAND[("landing (bronze)<br/>DuckDB dev / Databricks prod")]
subgraph TRANSF["Transformacao - dbt - Fases 1-3 e 5"]
STG["staging (silver)"]
INT["intermediate<br/>tarifa point-in-time"]
MARTS["marts (gold)<br/>fct - dims - agg - auditoria"]
MESH["dbt Mesh -> dbt-toll-exec"]
end
subgraph QA["Data Quality - Fase 5"]
DTESTS["dbt tests + unit tests"]
SODA["Soda Core (gate)"]
ELEM["Elementary (anomalia)"]
end
subgraph OUT["Serving - Fase 7"]
BI["Evidence.dev (dashboard)"]
LIN["dbt docs / lineage"]
end
CSV --> DLT --> LAND
EV --> KAFKA --> LAND
LAND --> STG --> INT --> MARTS --> MESH
MARTS --> BI
MARTS --> LIN
STG --> DTESTS
MARTS --> SODA
MARTS --> ELEM
ORCH["Orquestracao - Airflow + Cosmos (Fase 6)<br/>ingest -> freshness -> transform -> DQ -> docs"]
OBS["Observabilidade - Fase 6<br/>OpenLineage/Marquez - Prometheus/Grafana"]
CICD["CI/CD e IaC - Fase 8<br/>GitHub Actions (10 workflows) - Terraform - pre-commit"]
ORCH -.->|orquestra| ING
ORCH -.->|orquestra| TRANSF
ORCH -.->|gate| QA
OBS -.->|coleta| ORCH
CICD -.->|valida e publica| TRANSF
Escala (Fase 9): gerador
faker+ benchmark — 100k transacoes em ~23s no DuckDB (PASS=192 ERROR=0).devroda 100% em DuckDB;prodem Databricks (Unity Catalog + Delta).
| Projeto | O que faz | Entrar |
|---|---|---|
| ingestion-toll-analytics | EL com dlt: lê arquivos de landing (CSV) e carrega no schema landing do DuckDB (merge/replace, metadados, ''→NULL). O "E" e o "L" antes do "T". |
README |
| streaming-toll-analytics | Streaming near-real-time: produtor → Redpanda/Kafka → consumidor micro-batch → landing → fct incremental. |
README |
| dbt-toll-analytics | Medallion (landing→silver→gold), tarifa point-in-time, contracts, unit tests, Semantic Layer, sources+freshness, observabilidade (Elementary). Dev em DuckDB, prod em Databricks. | README · PLANO |
| dbt-toll-exec | dbt Mesh: projeto downstream que consome só os models public do upstream via cross-project ref() (dbt-loom). Prova a fronteira de acesso (ADR-18). |
README |
| quality-toll-analytics | Data Quality independente (Soda Core): checks nos marts, gate no Airflow e no CI. | README |
| bi-toll-analytics | BI / serving (Evidence.dev): painel executivo lendo os marts → site estático publicado no Pages (com o lineage do dbt em /lineage/). |
README |
| airflow-toll-analytics | Orquestra ingestão → transform → DQ gate (Soda) com Cosmos: cada model/test = 1 task, schedule, retries, freshness gate, alertas, DAG de observabilidade. | README |
# 1) Ingestão (EL) — dlt carrega os arquivos de landing no schema `landing`
cd ingestion-toll-analytics
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python toll_ingestion.py
# 2) Transformação (dbt) — consome via source('toll_raw', ...)
cd ../dbt-toll-analytics
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
dbt deps --profiles-dir . && dbt build --profiles-dir . # PASS, WARN intencional
# (atalho: `make build` roda a ingestão + build + checa a doc)
# 3) Orquestração (Airflow + Cosmos) — sobe Airflow e roda ingestão→transform
cd ../airflow-toll-analytics
bash scripts/validate_local.sh # state=success, ponta-a-pontadbt_ci.yml— ingestão (dlt) +dbt build+ SQLFluff + check de drift da documentaçãopages_site.yml— site no GitHub Pages: dashboard BI (Evidence) em/+ lineage do dbt em/lineage/(habilitar 1x: Settings → Pages → Source: GitHub Actions)dbt_slim_ci.yml— Slim CI (state:modified+ --defer) em PRsgovernance_ci.yml— mesh + DQ: upstream → Soda Core → downstream (dbt-loom)observability.yml— testes de anomalia (Elementary), agendadoairflow_ci.yml— teste de integridade dos DAGs (sem erro de import)pre_commit.yml— roda os hooks de pre-commit (ruff, yaml…) no CIterraform_ci.yml— valida a IaC do Databricks (terraform validate, sem apply)cd_deploy.yml— CD manual com promoção staging→prod (GitHub Environments)streaming_ci.yml— round-trip de streaming: sobe Redpanda, produz/consome e confere
Qualidade local: pip install pre-commit && pre-commit install — roda ruff
(lint+format), yamllint e checagens básicas a cada commit.
bash scripts/benchmark.sh 100000 gera 100k transações (faker), ingere (dlt) e roda
dbt build, medindo. Medido: ~23 s total no DuckDB (fato com 100.472 linhas,
PASS=192 ERROR=0); a auditoria encontra ~6.988 suspeitas. Para volumes maiores, o
prod (Databricks) usaria incremental microbatch + clustering (ADR-24). O dataset
de escala é gerado/gitignored — o dataset curado pequeno fica para os testes determinísticos.
Stack-alvo: o
devroda offline em DuckDB (reprodutível por qualquer um); oprodé Databricks real (Unity Catalog + Delta) — os models SQL não mudam, só a conexão (profiles.yml).