{
  "schemaVersion": 1,
  "project": {
    "name": "dbt — Inkrementell-, Lösch- und Historien-Pilot (BIS-Vorlage v1)",
    "goal": "dbt Core v1, dbt OSS v2 und dbt v2 mit Plattform am selben synthetischen Fall prüfen. Alle Bewertungen sind ungeprüft und keine Produktnoten.",
    "sources": "Synthetischer ETL-Hauptfall: initial ID 1=1000 EUR, ID 2=2000 EUR, ID 3=500 EUR, Summe 3500 EUR. Danach ID 1 auf 1200 EUR korrigiert, ID 2 Hard Delete, ID 4 neu mit 800 EUR, ID 3 verspätet auf 700 EUR korrigiert (älteres updated_at, höhere event_seq). Soll: IDs 1,3,4 und 2700 EUR. Replay, nicht numerischer Betrag wie malformed.csv, neue currency-Spalte und zwei Änderungen von ID 3 zwischen Snapshots prüfen. Gesonderte Gleichsummenfalle: a=1000, b=200, c=1500 EUR, danach a=1200, b gelöscht, d=0; beide Summen 2700 EUR.",
    "owners": "Datenquelle, Transformation, Plattformbetrieb, Freigabe und Vertretung ergänzen."
  },
  "candidates": [
    {
      "id": "candidate-1",
      "name": "dbt Core",
      "provider": "dbt Labs",
      "edition": "v1.x — genaue Version, Adapter und Betriebsweg ergänzen"
    },
    {
      "id": "candidate-2",
      "name": "dbt OSS",
      "provider": "dbt Labs",
      "edition": "v2 — genaue Version, Adapter und Betriebsweg ergänzen"
    },
    {
      "id": "candidate-3",
      "name": "dbt + dbt platform",
      "provider": "dbt Labs",
      "edition": "dbt v2 mit Plattformtarif — Version, Adapter und Tarif ergänzen"
    }
  ],
  "criteria": [
    {
      "id": "criterion-1",
      "group": "Daten und Kennzahlen",
      "title": "Datenquelle und v1-/v2-Adapter nachweisen",
      "target": "Konkrete Quelle, Zielplattform, Adapterversion, Reifegrad und benötigte Funktionen dokumentieren; v1-Unterstützung nicht auf v2 übertragen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-2",
      "group": "Daten und Kennzahlen",
      "title": "Ingestion vor dbt zuordnen",
      "target": "Verantwortliche Ladequelle, Frequenz, Rohdatenvollständigkeit und Fehlerweg benennen; dbt-Modelllauf ersetzt den Import nicht.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-3",
      "group": "Betrieb",
      "title": "Lizenz und Hostingweg festhalten",
      "target": "Distribution, Lizenztext, eigener oder gehosteter Betrieb und gegebenenfalls gebuchter Plattformtarif mit Beleg festhalten.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-4",
      "group": "Rollen und Rechte",
      "title": "EU-Datenweg und Rechte prüfen",
      "target": "Konto-Region, Warehouse-Region, Zusatzdienste einschließlich dbt State, Zugriffe auf Abfrageergebnisse und Aufbewahrung dokumentieren.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-5",
      "group": "Daten und Kennzahlen",
      "title": "Sollstand nach Hard Delete erreichen",
      "target": "Synthetisch: ID 2 (2000 EUR) aus Quelle löschen; nach allen Änderungen müssen IDs 1, 3, 4 im Ziel stehen. Löschsignal und konkrete Delete-Logik zeigen; unique_key allein genügt nicht.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-6",
      "group": "Daten und Kennzahlen",
      "title": "Verspätete Korrektur übernehmen",
      "target": "ID 1 von 1000 auf 1200 EUR korrigieren. Zusätzlich ID 3 verspätet von 500 auf 700 EUR korrigieren: älteres updated_at, höhere event_seq. Replay oder Sequenzlogik belegen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-7",
      "group": "Daten und Kennzahlen",
      "title": "Replay idempotent halten",
      "target": "Identische Eingabe und Joblauf wiederholen; kein Duplikat, kein Rückfall auf alte Version. Schlüssel und Summe vergleichen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-8",
      "group": "Daten und Kennzahlen",
      "title": "View, Table und Full Refresh abgrenzen",
      "target": "Frische, Laufzeit und Warehousekosten der gewählten Materialisierung nachweisen; Full Refresh nur mit geplantem Zeit- und Kostenrahmen.",
      "requirement": "could",
      "weight": 2,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-9",
      "group": "Daten und Kennzahlen",
      "title": "Fehlerhaften Betrag sichtbar abweisen",
      "target": "Wie in malformed.csv einen nicht numerischen Betrag einspeisen; Fehlermeldung und Quarantäne/Reparaturweg belegen. Negative Beträge nur bei vorab definierter fachlicher Verbotsregel getrennt testen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-10",
      "group": "Daten und Kennzahlen",
      "title": "Schlüssel und Summen kontrollieren",
      "target": "ETL-Hauptfall: anfänglich IDs 1,2,3 mit 3500 EUR; nach allen Änderungen IDs 1,3,4 mit 2700 EUR. Schlüssel und Zeilenwerte kontrollieren. Gesonderte Gleichsummenfalle mit IDs a,b,c,d prüfen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-11",
      "group": "Daten und Kennzahlen",
      "title": "Freshness-Alarm und Jobfolge belegen",
      "target": "Schwellenwert, Ausführung von dbt freshness bzw. Quellprüfung, Warnung/Fehler und Wirkung auf nachfolgende Jobs dokumentieren; kein automatisches Upstream-Repair annehmen.",
      "requirement": "could",
      "weight": 2,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-12",
      "group": "Daten und Kennzahlen",
      "title": "Snapshotverlust bewusst entscheiden",
      "target": "ID 3 zweimal zwischen Snapshot-Läufen ändern; nicht beobachtete Zwischenversion darf nicht als wiederherstellbar bewertet werden. CDC oder Takt als Alternative festhalten.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-13",
      "group": "Daten und Kennzahlen",
      "title": "Neue currency-Spalte mit Backfill prüfen",
      "target": "currency nur für neue Zeilen setzen; alte NULL-Werte nach Schemaänderung erkennen und separaten Backfill oder Full Refresh planen.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    },
    {
      "id": "criterion-14",
      "group": "Kosten und Exit",
      "title": "Gesamtkosten und Reversibilität nachweisen",
      "target": "Sitze, erfolgreiche Modell-Builds, State-DATT, Warehouse, Ingestion und Betrieb separat rechnen; SQL/YAML, Daten und Dokumentation beim Wechsel sichern.",
      "requirement": "must",
      "weight": 3,
      "assessments": {
        "candidate-1": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-2": {
          "status": "unchecked",
          "evidence": ""
        },
        "candidate-3": {
          "status": "unchecked",
          "evidence": ""
        }
      }
    }
  ]
}
