Files
0pt/src/quality/quality-types.ts
T
Simon AxelssonandClaude Fable 5 b46807da75 feat(data-os): P0 capability layer — source registry, search, quality, dataset versions, metadata, analytics, features, ER
- Source Registry (§10): rights/license/purpose metadata, provenance,
  freshness SLA, health checks, describe/query; purpose gate FAILS CLOSED
  (no rights record => deny); cross-tenant probes => NOT_FOUND.
- Search (§10/§42): OpenSearch REST adapter (no SDK) + SearchService with
  MANDATORY tenant + purpose/rights filtering, versioned index definitions,
  bulk, generation-per-rebuild (opt-{name}--g{n}) with atomic alias cutover,
  rollback, failed-rebuild generation discard. OpenSearch never canonical.
- Quality (§10): versioned rule registry (GE-JSON interchange), local
  engine for the GE core subset (never silently passes unsupported types),
  runs/results/issues/score/trend, whole-run delegation to the GE backend
  via N0D (0pt.quality.ge_run) - never fabricated results.
- Dataset (§10/§5/§53): immutable numbered versions holding canonical
  st0re:artifact refs only, idempotent createVersion, export registers the
  ST0RE artifact + AUD0 evidence + OpenLineage.
- Metadata (§10): OpenMetadata PUT /api/v1/tables projection adapter +
  projectAll rebuild path; projection never canonical.
- Analytics (§10): ClickHouse HTTP adapter, closed metric-query DSL with
  FORCED tenant predicate + readonly/max_execution_time/max_result_rows,
  TTL retention. Zero connection to b0ts/quarantined pipelines.
- Features (§10): versioned feature-view registry, real Feast
  get-online-features adapter, materialize/get-historical as N0D delegation.
- ER (§10): generic candidate API with deterministic blocking + transparent
  scoring + per-field explanations, product hard-rule hook (force both
  directions), review-band handoff, Splink batch via N0D contract.

93 new unit/contract tests; suite 248 passed / 1 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 16:49:32 +02:00

115 lines
3.7 KiB
TypeScript

/**
* src/quality/quality-types.ts
* =============================
* Types for 0pt's Data Quality capability (Master-DoD §10 Data quality:
* rule registry, runs, results, issues, scores, trend, rule versioning,
* product-supplied rules).
*
* IMPORTANT HISTORY: this repo once carried FABRICATED claims that a
* quality-check service existed (see CLAUDE.md + docs/P0_DATASET_QUALITY_FLOW.md,
* which is the explicit target spec). THIS module is the first real
* implementation — anything it cannot do is stated, not implied.
*
* Expectations are serialized in Great Expectations' canonical JSON shape
* (`expectation_type` + `kwargs`) so a rule authored here can be executed
* verbatim by a GE backend (0pt-motor's Python engine, Master-DoD §11 DQ)
* AND by the local TypeScript engine for the supported core subset. The GE
* suite is the interchange format; the local engine is honest about which
* expectation types it supports (unsupported ⇒ must delegate, never fake).
*/
/** GE-compatible expectation (interchange shape). */
export interface QualityExpectation {
/** Great Expectations expectation type, e.g. "expect_column_values_to_not_be_null". */
expectation_type: string;
kwargs: Record<string, unknown>;
}
export type QualitySeverity = "info" | "warning" | "error" | "critical";
export interface DataQualityRule {
rule_id: string;
tenant_id: string;
project_id: string;
/** Dataset the rule targets; product-supplied rules set their own dataset ids. */
dataset_id: string;
name: string;
expectation: QualityExpectation;
severity: QualitySeverity;
/** Monotonic rule version — bumped on every mutation (§10 rule versioning). */
version: number;
status: "active" | "disabled" | "superseded";
/** Which product supplied the rule ("0pt" | "vehiq" | ...). */
supplied_by: string;
created_at: string;
updated_at?: string;
}
export interface CreateQualityRuleInput {
rule_id: string;
tenant_id: string;
project_id: string;
dataset_id: string;
name: string;
expectation: QualityExpectation;
severity?: QualitySeverity;
supplied_by?: string;
}
/** One executed expectation within a run. */
export interface DataQualityResult {
rule_id: string;
rule_version: number;
success: boolean;
/** Fraction of evaluated rows/elements that passed (1 for table-level checks that pass). */
pass_ratio: number;
evaluated_count: number;
unexpected_count: number;
/** Up to 20 sample unexpected values (never full rows — PII minimization). */
unexpected_samples: unknown[];
/** Engine that executed the expectation. */
executed_by: "0pt-local" | "great_expectations";
}
/** An issue opened for a failed rule (human-review handoff). */
export interface DataQualityIssue {
issue_id: string;
run_id: string;
rule_id: string;
rule_version: number;
tenant_id: string;
dataset_id: string;
severity: QualitySeverity;
status: "open" | "acknowledged" | "resolved" | "wont_fix";
summary: string;
created_at: string;
}
export type QualityRunStatus = "running" | "succeeded" | "failed" | "delegated";
export interface DataQualityRun {
run_id: string;
tenant_id: string;
project_id: string;
dataset_id: string;
/** Dataset version under test, when versioned. */
dataset_version?: number;
status: QualityRunStatus;
results: DataQualityResult[];
/** Overall score 0..100 (severity-weighted pass ratio). */
score?: number;
started_at: string;
finished_at?: string;
correlation_id?: string;
/** N0D job id when execution was delegated to the GE backend. */
delegated_job_id?: string;
}
/** One point of the §10 trend series. */
export interface QualityTrendPoint {
run_id: string;
dataset_id: string;
score: number;
finished_at: string;
}