Skip to content
Menu

Score a table with a data contract

View .md
You end up withA contract on one table with a handful of rules, evaluated on a cron schedule. Each evaluation stores a weighted score, the table shows a trend, and a drop below your threshold alerts a channel.
Timeabout 20 minutes
You needA PostgreSQL, SQL Server or MySQL data source whose metadata is loaded, and the right to run saved SQL on it through a project. For alerts, a recipient. A Custom SQL rule needs an Admin.
Applies toBeacon 5.0 · Full Beacon
DecisionOptionsDefault
TableOne table per contract: a schema and a table of the data sourceRequired
RulesFreshness, Volume, Null rate, Uniqueness, Referential, Range, Pattern, Custom SQLStart with two or three
ScheduleA 5-field cron expression0 */6 * * * (every 6 hours)
AlertAlert on failure and a Failure threshold (%)On, 80

Data contracts evaluate on PostgreSQL, SQL Server and MySQL only. On another engine the rules fail. The table and each rule’s columns must exist in the data source’s stored metadata: refresh the metadata first when the table is new.

Open Data Quality and click New contract.

FieldWhat to enter
Contract nameFor example Orders freshness and volume
Data sourceYour database data source
Schema name / Table nameFor example public / orders
Cron expression0 */6 * * *, or 0 3 * * * for nightly
Failure threshold (%)80 is the default; alerts fire when the score is below it
EnabledOn, so the schedule is active
Alert on failureOn, then pick Notification recipients

Click Add rule for each. Each has a Name, Type, optional Column, Severity, Weight and a Configuration (JSON). You do not write the schema or table: Beacon takes them from the contract.

TypeChecksConfiguration
FreshnessNewest timestamp is not older than a limit{"column": "updated_at", "maxAgeMinutes": 60}
VolumeRow count in range{"minRows": 100}
Null rateNULL percentage at most a limit{"column": "email", "maxNullPercent": 5}
UniquenessNo duplicate values{"column": "id"}
ReferentialEvery value exists in a reference table{"column": "user_id", "referenceTable": "users", "referenceColumn": "id"}
RangeNumbers between min and max{"column": "age", "min": "0", "max": "150"}
PatternEvery value matches a pattern{"column": "email", "pattern": "^[^@]+@[^@]+$"}
Custom SQLAny check you can write as SQLSee Custom SQL rules

Pattern behaves differently by engine: a regular expression on PostgreSQL and MySQL, LIKE wildcards on SQL Server.

Severity multiplies a rule’s influence (Low ×1, Medium ×2, High ×3, Critical ×4) and Weight (0.1 to 10, default 1) tunes it within a severity. Make the rules whose failure you cannot tolerate Critical.

A passing Critical freshness rule and a failing Low volume rule, both weight 1, score (100×4 + 0×1) / (4+1) = 80%. Most rules score 100 or 0; Null rate and Range lose points in proportion to the overrun. See Scoring.

Click Create. An enabled contract is scheduled at once.

On the contract’s page, click Evaluate now. It runs every enabled rule once as you, stores the evaluation and updates the table’s score. It sends no alert: only scheduled runs alert.

The page’s tabs show the result:

  • Rules: the rule set.
  • Evaluations: the history, newest first, with the overall score and pass and fail counts.
  • Latest results: per rule, pass or fail, score, expected and actual value and message.

A rule that cannot run (a bad configuration, a missing column, a timeout of 60 seconds) is recorded as failed with score 0, and the other rules still run.

With Alert on failure on and a recipient attached, a scheduled evaluation scoring below the threshold sends a notification titled [Data Quality] {contract name} to each recipient. It carries the overall score, the threshold, the table, pass and fail counts and every failed rule with its expected and actual value.

To check it end to end, set Failure threshold (%) to 100 with a rule that currently fails, wait for the next scheduled run (or set a near cron time), and watch the channel. Then put the threshold back.

The table’s trend is Improving, Stable or Degrading by more than 1 point against the previous score. See Table scores and trends.

Use one when no built-in type fits. Only an Admin can create, change or delete a contract that contains one.

  1. Add a rule of type Custom SQL.
  2. Put a single read-only SELECT in the configuration:
{"sql": "SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE 0 END AS passed, COUNT(*) AS actual_value, 'orders without a customer' AS message FROM orders WHERE customer_id IS NULL"}
  • It must return passed (1 or 0). score (0 to 100), actual_value and message are optional.
  • Do not set your own LIMIT, TOP or FETCH: Beacon reads one row.
  • Name only the data source’s own database. Other qualifiers are refused.
  • PII in actual_value and message is masked before it is stored or alerted.

The same contract can be managed under /beacon/api/data-quality: POST /contracts to create, POST /contracts/{id}/evaluate to run now, GET /contracts/{id}/evaluations for the history and GET /overview for scores per data source. A scoped API key needs the Execute scope for writes. See Data Quality → REST API.

  • The contract page shows Latest score after Evaluate now, and Evaluations lists the run.
  • Latest results shows each enabled rule as pass or fail with an actual value.
  • The Data Quality overview shows the table with its score.
  • After a scheduled run below the threshold, the recipient’s channel gets [Data Quality] {contract name}.
SymptomCause and fix
Saving says “Table … is not in the data source’s metadata”The table or a column is not in the stored metadata. Refresh the data source’s metadata, or fix the spelling.
”Data contract’s data source must be a database type”The data source is not a database (for example an API). Pick a database data source.
A rule fails with “Rule type … is not supported on …”The engine is not PostgreSQL, SQL Server or MySQL.
”Invalid rule configuration”The JSON is incomplete for the type. Compare it with the table above.
”Custom SQL must not set its own LIMIT, TOP or FETCH”Remove the outer row limit.
”Rule timed out.”The check ran over 60 seconds. Narrow it or index the column.
No alert despite a low scoreAlerts need Alert on failure, a recipient, a score strictly below the threshold and a scheduled run. A recipient waiting for approval receives nothing.
Owner not authorized on the contractThe owner may no longer run saved SQL on the data source, so evaluations are skipped. An Admin or UserAdmin uses Change owner.
”Every enabled rule … is a Custom SQL rule waiting for approval”Approve it on Approvals, or enable a rule that does not wait.