A Visual Editor for Open Data Contracts

A full ODCS v3.1.0 contract editor with tabbed forms, live YAML preview, catalog import with AI-suggested quality checks, and dbt export.

We built a full ODCS v3.1.0 contract editor with tabbed forms, live YAML preview, catalog import with AI-suggested quality checks, and dbt export. A raw YAML textarea became a Databricks-inspired editing experience.


The problem with YAML-first contracts

The Open Data Contract Standard (ODCS) is good. It gives data teams a structured way to define what their data should look like: schema, quality rules, SLAs, ownership. The spec covers everything from column-level type constraints to cron-scheduled quality checks.

But editing ODCS contracts means writing YAML. YAML means indentation errors that silently produce wrong structures, no autocomplete for the 30+ field types, no validation until you try to save, and no way to see what a quality check will actually test.

We wanted the contract to feel like filling out a form. Not writing configuration files.

The visual editor

Seven tabs, one contract

The editor breaks the ODCS spec into focused tabs:

TabWhat you configure
GeneralName, version, status, domain, tags
Server & LocationCatalog/namespace/table picker that auto-populates server config
SchemaColumn properties with expandable rows for type constraints and per-column quality
QualityTable-level checks: library metrics, SQL assertions, custom engine rules
Team & SupportOwnership, stewardship, Slack/email channels
SLAFreshness, latency, availability with cron schedules
DescriptionUsage, purpose, limitations

A collapsible YAML preview panel on the right updates in real-time as you edit. Every keystroke produces valid ODCS YAML. No indentation errors possible.

Import from catalog

The fastest path to a contract: pick a table from the data catalog. The import:

  1. Fetches the Iceberg schema (column names, types, nullable flags)
  2. Auto-populates the server section with the platform’s external URL
  3. Runs profiling to understand the data
  4. Suggests quality checks based on column statistics:
    • Column with zero nulls gets a not_null check
    • High-cardinality column gets a unique check
    • Numeric column with known range gets a mustBeBetween check
    • Few distinct values gets an enum check

Suggestions appear with an “AI” badge. Accept, edit, or delete each one. The contract starts 80% complete from a single click.

Implicit checks from schema flags

When you check “Required” or “Primary Key” on a column, the quality runner automatically generates the corresponding checks at execution time. not_null for required, unique for primary key/unique. You don’t need to separately define quality checks for these basic constraints.

Export to dbt

Contracts export to three formats:

  • ODCS YAML as the native standard
  • dbt sources.yml with source definitions and dbt tests
  • dbt schema.yml with model-level tests (not_null, unique from contract flags)

This closes the loop: define quality expectations in a contract, export to dbt, run tests in your pipeline. The contract is the single source of truth.

Quality execution

Clicking “Run All” compiles the contract’s quality checks to SQL and executes them against the actual data via SQE/Trino:

-- From: required=true on 'id' column
SELECT SUM(CASE WHEN id IS NULL THEN 1 ELSE 0 END) FROM main_warehouse.analytics_db.user_summary
-- From: primaryKey=true on 'id' column
SELECT COUNT(*) - COUNT(DISTINCT id) FROM main_warehouse.analytics_db.user_summary

Results show per-check pass/fail with expected vs actual values. The history tab shows trends over time.

SQE compatibility

Our initial SQL used COUNT(*) FILTER (WHERE ...) which is standard SQL but not supported by our Sovereign Query Engine’s Trino-compatible endpoint. We switched to SUM(CASE WHEN ... THEN 1 ELSE 0 END) which works everywhere.

The contract list

Contracts are grouped by catalog, then namespace, in a collapsible tree. Same pattern as the Data Explorer. Status filter chips (draft/active/deprecated/retired) and search make it easy to find contracts across hundreds of tables.

Each row shows a quality badge with the latest run’s score. Green means all checks pass. Red means something needs attention.

What made this hard

ODCS customProperties format. The spec says customProperties must be a list of {property, value} objects, not a key-value dict. Our YAML builder initially generated the wrong format, causing Pydantic validation failures on save.

Schema field name mismatch. The backend stores properties as property_name and logical_type (database column names), but the frontend type has name and type. Every display component needed to handle both naming conventions.

Cascading select reset in edit mode. When editing an existing contract, loading the catalog/namespace/table values triggers the cascading useEffects that normally clear child values when a parent changes. We added an isInitialLoad ref to skip the reset during form population.


The ODCS Visual Contract Editor was built in April 2026. Design spec: docs/superpowers/specs/2026-04-10-odcs-visual-contract-editor-design.md. Implementation plan: docs/superpowers/plans/2026-04-10-odcs-visual-contract-editor.md.

All posts