Thema: Teil 16. Datamart Customer 360
Schwierigkeitsgrad: Mittelstufe
Geschätzte Lernzeit: 4-6 Stunden
Voraussetzungen: Grundlegendes Verständnis von SQL und Datenmodellen
Vertrautheit mit dbt (data build tool) und dem Konzept ref()
Verständnis der Prinzipien zum Aufbau von Datamarts (data marts)
Kenntnis des Konzepts SDD (Specification-Driven Development)
Grundlegendes Verständnis von PII (Personally Identifiable Information) und Prinzipien im Umgang mit personenbezogenen Daten
Erfahrung im Umgang mit YAML-Dateien und Markdown-Dokumentation
Lernziele: Zweck und Architektur des Datamarts mart_customer_360 als ersten finalen Mart im Projekt erklären
SQL-Implementierung, Schema, Spezifikation und Abnahmefakten abgleichen, um Deckungslücken zu identifizieren
Die Abnahmematrix anwenden, um die Erfüllung jedes Abnahmefaktums mit einem konkreten Nachweistyp zu verifizieren
Das Durchsickern von PII-Feldern aus Staging-/Raw-Schichten in den finalen Mart identifizieren und verhindern
dbt-Tests (unique, not_null, singular) zum Nachweis von Abnahmefakten konstruieren
Überblick: Teil 16 des Kurses widmet sich dem Datamart mart_customer_360 — dem ersten finalen Datamart im Projekt, der Kundenattribute, Kontosalden und Kartenaktivität zusammenführt. Dieser Abschnitt ist ein zentrales Lehrbeispiel, das zeigt, wie Produktspezifikation, ODCS (Open Data Contract Standard), Modellspezifikation, dbt-Tests und Validierungsfakten zusammenwirken müssen. Besonderes Augenmerk liegt auf der Produktdisziplin: Der Datamart ist absichtlich eingeschränkt — eine Zeile pro Kunde, ohne direkte PII, der Saldo wird aus Konten berechnet, und Risikoereignisse stammen aus einem synthetischen Aktivitätsfenster. Diese Einschränkung macht das Beispiel „ehrlich“: Jedes Feld lässt sich auf eine Spezifikation und eine Validierung zurückführen. Der Lernende versteht, warum der Feldname (z. B. risk_event_count_7d) Teil des Vertrags wird und warum die PII-Richtlinie keine allgemeine Floskel sein darf. Der Datamart Customer 360 ist der Ausgangspunkt zum Verständnis der Prinzipien von SDD (Specification-Driven Development), bei dem der Nachweis der Einsatzbereitschaft auf einer Abnahmematrix beruht, nicht auf einer visuellen SQL-Review.
Schlüsselkonzepte: Datamart customer 360: Der erste finale Datamart (mart) im Projekt, der Kundenattribute, Kontosalden und Kartenaktivität zusammenführt. Ist das zentrale Lehrbeispiel für die Integration von Spezifikation, Implementierung und Tests. Auf eine Zeile pro customer_id beschränkt.
Abnahmefakten: Konkrete prüfbare Aussagen über den Datamart, die durch Nachweise abgedeckt sein müssen. Umfassen: eine Zeile pro customer_id, customer_id not null und unique, keine direkten PII, total_balance_rub not null, risk_event_count_7d not null, obligatorische Vertragsfelder vorhanden, Lineage über ref() lesbar.
Abnahmematrix: Eine Tabelle, die jeden Abnahmefaktum einem konkreten Nachweis (dbt-Test unique, not_null, Singular-Test für das Schema, Singular-Test für Vertragsspalten) zuordnet. Wenn eine Nachweiszeile leer ist, ist das keine Einsatzbereitschaft, sondern eine Lücke.
ODCS (Open Data Contract Standard): Datenvertragsstandard, der zur formalen Beschreibung der Produktspezifikation verwendet wird. Im Kontext des Datamarts — die Datei specs/customer_360_contract.odcs.yaml, die Verpflichtungen zu Struktur und Datenqualität beschreibt.
SDD (Specification-Driven Development): Ein Entwicklungsansatz, bei dem die Spezifikation vor dem SQL-Code geschrieben wird. SDD zwingt dazu, eine Version des Produktversprechens auszuwählen und sie vorab zu dokumentieren, was das Risiko eines Vertragsdrifts verringert.
dbt-Tests: Automatisierte Prüfungen in dbt (data build tool), die als Nachweise für Abnahmefakten dienen. Umfassen Generic-Tests (unique, not_null) und Singular-Tests (freies SQL zur Prüfung von Schema, Vertragsspalten, Abwesenheit von PII).
Lineage über ref(): Die Fähigkeit, die Datenherkunft (data lineage) über ref()-Funktionen in dbt zu lesen. Einer der Abnahmefakten: Lineage muss transparent und rekonstruierbar sein.
PII (Personally Identifiable Information): Personenbezogene Daten, die eine Identifikation des Betroffenen ermöglichen. Die PII-Richtlinie darf in SDD keine allgemeine Floskel sein: In Raw und Staging ist pii_email zu Lehrzwecken zulässig, im Mart darf es jedoch nicht vorkommen. Dies ist eine Produktgrenze, keine Frage der Schema-Ästhetik.
Risk event count 7d: Ein Feld für den Zähler von Risikoereignissen über ein 7-Tage-Fenster. Der Name selbst verspricht ein 7-Tage-Fenster; zählt das SQL einfach alle Risikoereignisse, wirkt das Feld zwar plausibel, täuscht aber den Verbraucher. Das Fenster muss beschrieben und durch einen separaten Test geprüft werden. Der Feldname ist Teil des Vertrags.
Vertragsdrift: Eine Abweichung zwischen der deklarierten Spezifikation und der tatsächlichen Implementierung. Muss durch eigene Prüfungen abgedeckt werden und darf nicht nur durch visuelle SQL-Reviews erkennbar sein.
Abnahmenachweis: Ein konkretes Artefakt (dbt-Test, Schema-Review, expliziter Validierungsfakt, Reviewer-Bericht), das die Erfüllung eines Abnahmefaktums belegt. Ohne Nachweis wird die Einsatzbereitschaft nicht anerkannt.
Reviewer-Notiz: Minimale Ausgabe eines Review-Artefakts, das Folgendes enthält: Granularität, PII-Status, Vertragsfelder, Liste der Prüfungen und offene Fragen. Beispiel: „Granularität: eine Zeile pro customer_id. PII: keine direkten PII. Vertragsfelder: customer_id, total_balance_rub, risk_event_count_7d. Prüfungen: dbt build, Mart-Tests, Liste verbotener PII, Vertragsspalten. Offene Fragen: Die Definition von risk_event_count_7d hängt vom Eingangs-Risiko-Flag ab“.
Qwen-Review-Prompt: Typische Aufforderung an einen LLM-Assistenten (Qwen), um SQL, Schema, ODCS und Validierungsdateien zu vergleichen und so abgedeckte, manuelle und fehlende Abnahmefakten zu identifizieren. Die Dateien werden dabei nicht verändert.
Übungsaufgaben: Name: Audit der Abnahmematrix
Problem: Sie haben den Datamart mart_customer_360 erhalten. Ein Praktikant behauptet, alles sei fertig, weil dbt build erfolgreich war. Führen Sie ein Audit durch: Gehen Sie jeden Abnahmefaktum durch und ordnen Sie ihm einen Nachweis aus der Abnahmematrix zu. Bestimmen Sie, welche Fakten automatisch abgedeckt sind, welche ein manuelles Review erfordern und welche überhaupt keinen Nachweis haben. Dateien: models/marts/mart_customer_360.sql, models/schema.yml, specs/customer_360_contract.odcs.yaml, specs/validation/customer_360.md.
Lösung: Schritt 1. Notieren Sie alle Abnahmefakten aus der Spezifikation: (1) eine Zeile pro customer_id, (2) customer_id not null, (3) customer_id unique, (4) keine direkten PII, (5) total_balance_rub not null, (6) risk_event_count_7d not null, (7) obligatorische Vertragsfelder vorhanden, (8) Lineage über ref() lesbar. Schritt 2. Öffnen Sie models/schema.yml. Suchen Sie die Tests unique und not_null für customer_id, total_balance_rub, risk_event_count_7d. Halten Sie fest: Die Fakten (2), (3), (5), (6) sind durch Generic-Tests abgedeckt. Schritt 3. Prüfen Sie, ob ein Singular-Test vorhanden ist, der verbotene PII-Felder (pii_email, pii_phone usw.) auflistet und mit der Spaltenliste des Marts vergleicht. Ist der Test vorhanden — Fakt (4) ist automatisch abgedeckt; ist er nicht vorhanden — als manuelles Review markieren. Schritt 4. Suchen Sie den Singular-Test für Vertragsspalten (Prüfung, dass im Mart genau customer_id, total_balance_rub, risk_event_count_7d und weitere obligatorische Felder aus ODCS vorhanden sind). Schritt 5. Prüfen Sie, dass im SQL nur ref() für Upstream-Modelle verwendet werden — andernfalls ist Fakt (8) nicht abgedeckt. Schritt 6. Erstellen Sie eine Deckungstabelle. Wenn auch nur eine Zeile leer ist, ist das eine Lücke der Einsatzbereitschaft, nicht Einsatzbereitschaft.
Schwierigkeit: Mittelstufe
Name: Singular-Test auf Abwesenheit von PII schreiben
Problem: In der Staging-Schicht existiert das Feld pii_email (zu Lehrzwecken und zur Demonstration des Risikos). Schreiben Sie einen Singular-Test für dbt, der prüft, dass dieses Feld im finalen Datamart mart_customer_360 fehlt und dass auch alle anderen Spalten mit den Teilzeichenfolgen 'email', 'phone', 'passport', 'inn' fehlen.
Lösung: Erstellen Sie die Datei tests/mart_customer_360_no_pii.sql mit folgendem Inhalt:
{{ config(severity='error') }}
with mart_columns as (
select column_name
from information_schema.columns
where table_schema = 'marts'
and table_name = 'mart_customer_360'
),
forbidden_substrings as (
select unnest(array['email', 'phone', 'passport', 'inn', 'snils']) as forbidden
)
select m.column_name, f.forbidden
from mart_columns m
cross join forbidden_substrings f
where lower(m.column_name) like '%' || f.forbidden || '%'
Legen Sie die Datei im Ordner tests/ ab (oder in models/marts/ mit der Konfiguration {{ config(materialized='test') }}). Der Test muss Zeilen zurückgeben — ist das Ergebnis leer, gibt es keine PII-Felder. Fügen Sie dem Schema eine Testbeschreibung in schema.yml hinzu: description: "Prüft die Abwesenheit direkter PII-Felder in mart_customer_360". Dies ist ein Singular-Test für das Schema, der als Nachweis für das Abnahmefaktum „keine direkten PII“ dient.
Schwierigkeit: Mittelstufe
Name: Schutz des Fensters risk_event_count_7d
Problem: Das Feld risk_event_count_7d verspricht ein 7-Tage-Fenster für Risikoereignisse. Die aktuelle Implementierung in mart_customer_360.sql zählt alle Ereignisse aus stg_risk_events ohne Filterung nach Datum. Schreiben Sie einen Validierungstest, der (a) das Fenster im SQL fixiert, (b) einen dbt-Test hinzufügt, der belegt, dass der Zähler tatsächlich auf die letzten 7 Tage relativ zum Ladezeitpunkt beschränkt ist.
Lösung: Schritt 1. Korrigieren Sie das SQL-Modell mart_customer_360.sql so, dass die Zählung nur über das Fenster erfolgt: Fügen Sie die Bedingung event_date >= current_date - interval '7 days' hinzu oder verwenden Sie das Makro dbt_date. Beispiel-Fragment: count(case when r.event_date >= current_date - interval '7 days' then 1 end) as risk_event_count_7d. Schritt 2. Erstellen Sie den Singular-Test tests/mart_customer_360_risk_window.sql, der die Zählung im Mart mit der Referenzzählung über das Fenster aus stg_risk_events vergleicht:
{{ config(severity='warn') }}
with mart as (
select customer_id, risk_event_count_7d
from {{ ref('mart_customer_360') }}
),
stg_window as (
select customer_id,
count(*) as expected_7d
from {{ ref('stg_risk_events') }}
where event_date >= current_date - interval '7 days'
group by 1
)
select m.customer_id
from mart m
join stg_window s on m.customer_id = s.customer_id
where m.risk_event_count_7d <> s.expected_7d
Schritt 3. Halten Sie in der Spezifikation specs/validation/customer_360.md die Fenstertdefinition fest: „risk_event_count_7d — Anzahl der Risikoereignisse eines Kunden in den letzten 7 Kalendertagen relativ zum Berechnungsdatum des Datamarts“. Schritt 4. Fügen Sie in schema.yml beim Feld risk_event_count_7d eine Beschreibung mit Angabe des Fensters hinzu. Jetzt sind Feldname, SQL, Test und Spezifikation konsistent.
Schwierigkeit: Mittelstufe
Name: Überprüfung der Lineage über ref()
Problem: Ein Prüfer vermutet, dass in mart_customer_360.sql eine der Upstream-Modelle nicht über ref(), sondern über eine direkte Quelle (source()) referenziert wird. Finden Sie diese Verletzung, erläutern Sie das Risiko und schlagen Sie eine Korrektur vor.
Lösung: Schritt 1. Öffnen Sie models/marts/mart_customer_360.sql. Überprüfen Sie alle Aufrufe in with-Blöcken und from-Sektionen: Es dürfen nur {{ ref('stg_customers') }}, {{ ref('stg_accounts') }}, {{ ref('stg_cards') }}, {{ ref('stg_risk_events') }} vorkommen. Schritt 2. Suchen Sie Aufrufe von {{ source('...', '...') }} — dies bedeutet einen direkten Zugriff auf Raw, unter Umgehung von Staging. Schritt 3. Erläutern Sie das Risiko: source() umgeht die Transformationsschicht, verletzt die Datenlineage, macht eine Qualitätsprüfung vor dem Mart unmöglich und erzeugt einen Vertragsdrift. Schritt 4. Ersetzen Sie source() durch ref() zum entsprechenden Staging-Modell. Schritt 5. Führen Sie dbt compile aus und stellen Sie sicher, dass die Lineage korrekt aufgebaut wird (dbt docs generate → Visualisierung öffnen). Schritt 6. Fügen Sie einen Singular-Test hinzu, der SQL nach Vorkommen von source() scannt (optional, fortgeschritten).
Schwierigkeit: Mittelstufe
Name: Erstellung einer Reviewer-Notiz
Problem: Erstellen Sie eine minimale Reviewer-Ausgabe für den Datamart mart_customer_360 nach der Vorlage aus den Kursmaterialien. Verwenden Sie folgende Eingaben: Der Datamart hat dbt build bestanden, in schema.yml gibt es Tests unique und not_null für customer_id, total_balance_rub, risk_event_count_7d. Ein Singular-Test auf PII existiert nicht, aber im Code wird pii_email visuell nicht ausgewählt. Ein Singular-Test auf Vertragsspalten ist vorhanden, prüft jedoch nur 3 von 5 obligatorischen ODCS-Feldern. SQL verwendet ref() korrekt. Die Definition von risk_event_count_7d in specs/validation/customer_360.md erwähnt ein 7-Tage-Fenster, gibt jedoch kein Ankerdatum an.
Lösung: Fertige Reviewer-Notiz:
Granularität: eine Zeile pro customer_id (durch dbt-Test unique abgedeckt).
PII: visuell nicht vorhanden, aber kein automatischer Nachweis — Status „manuelles Review, Singular-Test für das Schema erforderlich“.
Vertragsfelder: customer_id, total_balance_rub, risk_event_count_7d (teilweise abgedeckt — 3 von 5 Feldern gemäß ODCS, Lücke bei 2 Feldern).
Prüfungen: dbt build — ok, Mart-Tests unique/not_null — ok, Singular-Test für Vertragsspalten — unvollständig, Liste verbotener PII — fehlt.
Offene Fragen:
1. Die Definition von risk_event_count_7d fixiert kein Ankerdatum (current_date vs. event_date vs. Berechnungsdatum des Datamarts) — Risiko eines Drifts.
2. Welche weiteren 2 Felder aus ODCS müssen im Mart vorhanden sein? Abgleich mit customer_360_contract.odcs.yaml erforderlich.
3. Die PII-Prüfung existiert nur als visuelles Review — Singular-Test muss hinzugefügt werden.
Fazit: Der Datamart ist nicht produktionsreif. Drei offene Fragen müssen vor dem Merge geschlossen werden.
Schwierigkeit: Mittelstufe
Fallstudien: Name: Durchsickern von pii_email in den Marketing-Datamart einer Bank
Szenario: Eine große Retailbank baut einen Datamart Customer 360 für die CRM-Abteilung. Das Marketingteam fordert „alles, was es über den Kunden gibt“, um Segmentierung und Personalisierung vorzunehmen. Der dbt-Entwickler in der Mart-Schicht stellt eine Tabelle mit 47 Spalten zusammen, einschließlich pii_email und pii_phone, mit der Begründung, diese Felder seien „bereits in stg_customers vorhanden und für Mailings erforderlich“. Der Datamart durchläuft ein Code-only-Review: Der Reviewer sieht das SQL mit sauberem Join, gleicht aber die Spaltenliste nicht mit der PII-Richtlinie und dem ODCS-Vertrag ab.
Aufgabe: Nach 4 Monaten führt die Sicherheitsabteilung ein Audit durch und stellt fest, dass der Marketing-Datamart direkte PII enthält, die laut interner Richtlinie auf Mart-Ebene maskiert oder gehasht werden müssen. Der Datamart wurde bereits in 12 Dashboards und 3 ML-Modelle zur Churn-Prognose verwendet. Ein Datenleck fand nicht statt (der Zugriff war eingeschränkt), aber das regulatorische Risiko materialisierte sich: Es wurde ein Verstoß gegen die Richtlinie zur Verarbeitung personenbezogener Daten festgestellt, die Bank sieht einer Verfügung der Zentralbank entgegen.
Lösung: Das Team führt SDD ein: (1) schreibt den ODCS-Vertrag customer_360_contract.odcs.yaml neu und listet explizit erlaubte und verbotene Felder auf; (2) entfernt pii_email und pii_phone aus dem Mart und ersetzt sie durch hash_email für sichere Segmentierung; (3) fügt den Singular-Test mart_customer_360_no_pii.sql hinzu, der information_schema scannt und fehlschlägt, sobald verbotene Teilzeichenfolgen in Spaltennamen auftauchen; (4) führt einen obligatorischen Schritt zur Abnahmematrix in der PR-Vorlage ein — der Reviewer muss die Deckungstabelle ausfüllen; (5) bindet den Qwen-Assistenten ein, der in jedem PR SQL, schema.yml und ODCS vergleicht und Abweichungen hervorhebt.
Ergebnis: In den 6 Monaten nach Einführung von SDD sank die Anzahl der PII-Vorfälle in der Mart-Schicht auf null. Die durchschnittliche Review-Zeit für Datamarts stieg um 15 Minuten, aber die Anzahl der Rollbacks und Nacharbeiten sank. Das regulatorische Risiko ist geschlossen: Die Bank bestand das erneute Audit ohne Beanstandungen. Das Team skalierte die Praxis auf 14 weitere Datamarts.
Gelernte Lektionen: Ein Code-only-Review reicht nicht aus — automatische Singular-Tests sind nötig, die die Einhaltung der PII-Richtlinie belegen.
Der ODCS-Vertrag muss die einzige Wahrheitsquelle über die Feldzusammensetzung des Marts sein, nicht der visuelle Eindruck des Reviewers.
Namen wie „Customer 360“ sind trügerisch vertraut — verschiedene Stakeholder haben unterschiedliche Erwartungen; SDD fixiert eine Version des Versprechens.
Die Abnahmematrix verwandelt abstraktes „fertig“ in eine diskrete Liste von Fakten mit Nachweisen.
Verwandte Konzepte: mart_customer_360
PII (Personally Identifiable Information)
ODCS (Open Data Contract Standard)
Abnahmematrix
Singular-Test für das Schema
SDD (Specification-Driven Development)
Name: Vertragsdrift von risk_event_count_30d bei einer Versicherungsgesellschaft
Szenario: Eine Versicherungsgesellschaft verwendet den Datamart Customer 360 für das Betrugsscoring. Das Feld risk_event_count_30d verspricht ein 30-Tage-Fenster. Ein Datenanalyst ändert stg_risk_events: Er fügt den Filter where event_status = 'confirmed' hinzu, um „rohe“ Alarme zu entfernen. Technisch bleibt das Feld „Risikoereignisse in 30 Tagen“, aber die Bedeutung verschiebt sich von „alle Alarme“ zu „bestätigte Alarme“. Im SQL von mart_customer_360 ändert sich nichts, dbt build läuft durch, niemand bemerkt die Änderung.
Aufgabe: Nach 2 Monaten gibt das Scoring-Modell falsch positive Sperrungen für Policen aus: Kunden, die nur unbestätigte Alarme hatten, werden nun nicht gesperrt, obwohl sie es sollten. Die Betrugsverluste steigen im Quartal um 8 %. Die Untersuchung zeigt, dass das Feld im Mart weiterhin risk_event_count_30d heißt, aber seine Semantik sich geändert hat. Vertrag und Implementierung sind unbemerkt auseinandergefallen.
Lösung: Das Team führt eine mehrstufige Absicherung ein: (1) In specs/validation/customer_360.md wird eine formale Definition hinzugefügt: „risk_event_count_30d — Anzahl der Datensätze in stg_risk_events mit dem Status event_status in ('confirmed', 'investigating') in den letzten 30 Tagen relativ zum Berechnungsdatum des Datamarts“; (2) in mart_customer_360.sql wird der Filter event_status in ('confirmed', 'investigating') mit Kommentar hart fixiert; (3) ein Singular-Test wird erstellt, der den Wert des Felds im Mart mit der Referenzzählung gemäß fixierter Formel vergleicht — jede Abweichung bricht den Build; (4) in schema.yml erhält das Feld eine Beschreibung mit Verweis auf den Spezifikationsabschnitt.
Ergebnis: Das Scoring-Modell kehrt zur erwarteten Semantik zurück, die Betrugsverluste normalisieren sich. Die Einführung eines formalen Vertragstests reduziert solche Vorfälle von 2-3 pro Jahr auf null. Das Team formalisiert die Regel: „Wenn der Feldname ein Fenster, einen Status, eine Währung oder eine Aggregationsebene enthält, ist dies Teil des Vertrags und erfordert einen eigenen Test“.
Gelernte Lektionen: Der Feldname ist Teil des Vertrags. Inoffizielle Änderungen in der Upstream-Schicht lassen die Semantik der Downstream-Datamarts unbemerkt driften.
Bestehen von dbt build ≠ Einsatzbereitschaft. Es sind Tests nötig, die die Bedeutung prüfen, nicht nur die Struktur.
Ein Filter in der Staging-Schicht ändert die Semantik des Mart-Felds, selbst wenn sich das SQL im Mart nicht ändert. Es ist ein End-to-End-Test nötig.
Die Fenstertdefinition muss ein Ankerdatum sowie Ein- und Ausschlussbedingungen für Ereignisse enthalten.
Verwandte Konzepte: risk_event_count_7d
Vertragsdrift
Validierungsspezifikation
Singular-Test
Feldname als Teil des Vertrags
Name: Migration von 14 Datamarts auf SDD in einem Quartal
Szenario: Ein Fintech-Startup betreibt 14 Datamarts in der Mart-Schicht, die über 2 Jahre von verschiedenen Entwicklern geschrieben wurden. Der Umgang mit Verträgen ist uneinheitlich: Manche Datamarts haben einen ODCS, andere nur eine Wiki-Seite, wieder andere keine Dokumentation. Das Review der Datamarts ist vollständig manuell und dauert 2-3 Tage pro Datamart. Die Datenqualität ist unvorhersehbar: Konsumenten beschweren sich über „driftende“ Metriken, der Datamart Customer 360 wird in verschiedenen Branches mit unterschiedlichen Ergebnissen neu gebaut.
Aufgabe: Der Produktdirektor verlangt, innerhalb eines Quartals die Qualität zu stabilisieren und die Time-to-Market für neue Datamarts zu senken. Ein Team aus 5 dbt-Entwicklern muss gleichzeitig die bestehenden Datamarts auf SDD migrieren, ohne die Datenbereitstellung zu unterbrechen. Hohes Risiko: Bei der Migration kann man kaputt machen, was jahrelang funktioniert hat.
Lösung: Das Team geht inkrementell vor: (1) wählt mart_customer_360 als Pilot — den „ersten finalen Datamart“ mit verständlicher Geschäftslogik und begrenzter Anzahl von Feldern; (2) schreibt für den Piloten den ODCS-Vertrag, die Modellspezifikation, die Validierungsspezifikation und die Abnahmematrix, wie in Teil 16 beschrieben; (3) führt 3 Typen von dbt-Tests ein: unique/not_null für obligatorische Felder, Singular-Test auf Abwesenheit von PII, Singular-Test auf Übereinstimmung mit Vertragsspalten; (4) automatisiert die Prüfung über den Qwen-Assistenten: PR löst ein Review aus, das SQL, schema.yml und ODCS vergleicht und eine Deckungstabelle der Fakten erzeugt; (5) nach erfolgreichem Piloten werden die Artefakte templatisiert und auf die übrigen 13 Datamarts skaliert, 2 Datamarts pro Woche.
Ergebnis: In 12 Wochen wurden alle 14 Datamarts auf SDD migriert. Die Code-Review-Zeit sank von 2-3 Tagen auf 4-6 Stunden dank automatischer Deckungsprüfung. Die Anzahl der Vorfälle mit Datendrift sank von 8-10 pro Quartal auf 1 pro Halbjahr. Konsumenten berichten, dass die Datamarts „vorhersehbar“ geworden sind — Dokumentation und Implementierung fallen nicht mehr auseinander. Bonus: Neue Entwickler werden in 1 Woche statt 1 Monat onboardet dank standardisierter Vorlagen.
Gelernte Lektionen: Customer 360 ist der ideale Pilot für SDD: Der Name ist vertraut, deshalb glaubt jeder, ihn zu verstehen, aber verschiedene Leute haben unterschiedliche Erwartungen. Eine schriftliche Spezifikation räumt Unklarheiten aus.
Die Abnahmematrix verwandelt abstraktes „fertig“ in eine konkrete Checkliste mit Nachweisen. Eine leere Nachweiszeile = Einsatzbereitschaftslücke.
Ein LLM-Assistent (Qwen) beschleunigt die Routineprüfung der Faktenabdeckung, ersetzt jedoch nicht die menschliche Entscheidung bei offenen Fragen.
Die Templatisierung von Artefakten (ODCS, Spezifikation, Validierung) beschleunigt die Skalierung und verringert die Variabilität zwischen Datamarts.
Verwandte Konzepte: SDD (Specification-Driven Development)
ODCS (Open Data Contract Standard)
Abnahmematrix
Qwen-Review-Prompt
Reviewer-Notiz
Vertragsdrift
Lerntipps: Beginnen Sie mit der Abnahmematrix, nicht mit SQL. Gehen Sie jeden Faktum durch und finden Sie den Nachweis, bevor Sie den Code lesen — das dreht die Wahrnehmung von „was das Modell tut“ zu „was das Modell verspricht“.
Erstellen Sie für jeden Datamart eine Tabelle „Faktum → Nachweis → Testtyp“. Eine leere Zelle = Einsatzbereitschaftslücke. Das ist Ihr wichtigstes Arbeitsartefakt.
Fragen Sie für jedes Feld mit einem „Versprechen“ im Namen (7d, 30d, confirmed, rub, count): „Wo im Code ist dieses Versprechen fixiert?“ Wenn nur im Namen — das ist eine technische Schuld.
Verwenden Sie den Qwen-Prompt aus dem Kurs als Vorlage für Ihre eigenen PRs: Vergleichen Sie SQL, schema.yml, ODCS und die Validierungsdatei, geben Sie die Deckungstabelle aus. Ändern Sie die Dateien nicht — analysieren Sie sie nur.
Beschränken Sie sich nicht auf das Lesen von SQL. Öffnen Sie information_schema und prüfen Sie, dass im Mart physisch keine PII-Spalten vorhanden sind, auch wenn sie in SELECT nicht sichtbar sind.
Schreiben Sie Singular-Tests sofort und nicht „irgendwann später“. Ein Test auf PII-Abwesenheit sind 10 Zeilen, die Wochen an Untersuchungen sparen.
Füllen Sie für jedes PR die Reviewer-Notiz nach der Vorlage aus dem Kurs aus. Das diszipliniert: Fakten, keine Eindrücke.
Führen Sie dbt build --select mart_customer_360 aus und analysieren Sie die Ausgabe zeilenweise — welche Zeile entspricht welchem Faktum der Matrix.
Verwechseln Sie „visuell keine PII“ nicht mit „Abwesenheit von PII nachgewiesen“. Ersteres ist ein Review, Letzteres ist ein Test. SDD verlangt Nachweise.
Verwenden Sie Datumsankerung in Fensterfeldern: Fixieren Sie immer, relativ zu welchem Datum das Fenster gezählt wird (current_date, Ladezeitpunkt, event_date).
Zusätzliche Ressourcen: dbt-Dokumentation zu Tests: https://docs.getdbt.com/docs/build/data-tests — offizieller Leitfaden zu Generic-Tests (unique, not_null, accepted_values, relationships) und Singular-Tests.
dbt-Dokumentation zu ref(): https://docs.getdbt.com/reference/dbt-jinja-functions/ref — Beschreibung der Funktion ref() und Aufbau der Datenlineage.
ODCS (Open Data Contract Standard): https://bitol-io.github.io/open-data-contract-standard/ — Spezifikation des im SDD verwendeten Datenvertragsstandards.
dbt-utils-Paket: https://github.com/dbt-labs/dbt-utils — Sammlung von Makros, einschließlich Tests für PII und Vertragsspalten (expression_is_true, relationships usw.).
sqlfluff-Linter für dbt: https://sqlfluff.com/ — statische Analyse von dbt-SQL-Modellen, hilft Stil und grundlegende Fehler zu wahren.
dbt-expectations-Paket: https://github.com/calogica/dbt-expectations — erweiterte Tests im Stil von Great Expectations für dbt.
Buch „Data Contracts“ (Andrew Jones): Konzeptuelle Einführung in Datenverträge als Produktartefakt. Hilfreich, um zu verstehen, warum SDD funktioniert.
Great Expectations: https://greatexpectations.io/ — Datenvalidierungsframework, dessen Konzepte sich mit dbt-Singular-Tests überschneiden.
Zusammenfassung: Teil 16 „Datamart Customer 360“ ist das zentrale Lehrbeispiel für die Anwendung von SDD (Specification-Driven Development) auf die finale Datenschicht. Der Datamart mart_customer_360 ist absichtlich eingeschränkt: eine Zeile pro customer_id, ohne direkte PII, Saldo aus Konten, Risikoereignisse aus einem synthetischen Fenster. Jedes Feld lässt sich auf eine Spezifikation und eine Validierung zurückführen. Die Schlüsselidee: Die Abnahmematrix verwandelt abstraktes „fertig“ in eine diskrete Liste von Fakten mit konkreten Nachweisen (dbt-Tests unique/not_null, Singular-Tests für Schema und Vertragsspalten, Prüfung der Lineage über ref()). Ist eine Nachweiszeile leer, ist das eine Einsatzbereitschaftslücke, nicht Einsatzbereitschaft. Feldnamen sind Teil des Vertrags: Enthält der Name ein Fenster (7d), einen Status oder eine Aggregationsebene, muss dieses Versprechen im Code fixiert und durch einen Test bestätigt werden. Die PII-Richtlinie darf keine allgemeine Floskel sein — sie wird durch einen automatischen Singular-Test geprüft, der die Mart-Spalten scannt. Die minimale Ausgabe eines Artefakts ist eine Reviewer-Notiz mit Granularität, PII-Status, Liste der Vertragsfelder, Liste der Prüfungen und offenen Fragen. Der Qwen-Assistent kann die Routineprüfung der Faktenabdeckung beschleunigen, ersetzt jedoch nicht die menschliche Entscheidung. Die wichtigste Erkenntnis: In SDD reicht es nicht, das richtige SQL zu schreiben — man muss jede Zusage durch einen Test oder einen expliziten Faktum belegen.