Files
ThothII/frontend/src/viewers/artifactV2.ts
T

136 lines
3.1 KiB
TypeScript

// TypeScript mirrors of the persisted v2 artifact payload contracts. Detection everywhere is
// `data.schema_version === 2` + a shape-guard; anything else falls back to the
// legacy renderers in ArtifactView.
// --- A. cte_plan v2 ---------------------------------------------------------
export interface CtePlanTable {
name: string;
description?: string;
}
export interface CtePlanFilter {
column: string;
op: string;
value: string;
description?: string;
rationale?: string;
}
export interface CtePlanCte {
name: string;
index: number;
purpose?: string;
rationale?: string;
depends_on?: string[];
tables?: CtePlanTable[];
keys?: string[];
filters?: CtePlanFilter[];
output_columns?: string[];
}
export interface CtePlanV2 {
schema_version: 2;
question?: string;
strategy?: string;
ctes: CtePlanCte[];
}
// --- B. cte_result v2 --------------------------------------------------------
export interface CteResultColumn {
name: string;
description?: string;
}
export interface CteResultPreview {
columns: string[];
rows: unknown[][];
}
export interface CteResultV2 {
schema_version: 2;
name: string;
index: number;
total: number;
purpose?: string;
rationale?: string;
depends_on?: string[];
sql: string;
status: "ok" | "error" | string;
execution_ms?: number;
row_sample?: number;
warnings?: string[];
sql_hash?: string;
columns?: CteResultColumn[];
preview?: CteResultPreview;
note?: string;
}
// --- C. phase summary v2 -----------------------------------------------------
export interface PhaseMeta {
id: string;
num: number;
name: string;
}
export interface PhaseCheck {
label: string;
status: "ok" | "warn" | "fail" | string;
detail?: string;
}
export interface PhaseSectionItem {
label: string;
table?: string;
column?: string;
value?: string;
kind?: "table" | "column" | "filter" | "join" | "metric" | "note" | string;
description?: string;
rationale?: string;
}
export interface PhaseSection {
title: string;
items?: PhaseSectionItem[];
}
export interface PhaseTableColumn {
name: string;
description?: string;
value_filter?: string;
}
export interface PhaseTable {
name: string;
role: "promoted" | "excluded" | string;
description?: string;
columns?: PhaseTableColumn[];
}
export interface PhaseSummaryV2 {
schema_version: 2;
phase: PhaseMeta;
summary?: string;
checks?: PhaseCheck[];
sections?: PhaseSection[];
tables?: PhaseTable[];
open_questions?: string[];
}
/** Defensive compatibility for malformed v2 artifacts persisted before the gate
* enforced `open_questions: string[]`. New payloads stay strictly typed as strings. */
export function phaseOpenQuestionText(value: unknown): string | null {
if (typeof value === "string") return value.trim() || null;
if (typeof value === "number" || typeof value === "boolean") return String(value);
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
const record = value as Record<string, unknown>;
for (const field of ["question", "label"]) {
const text = record[field];
if (typeof text === "string" && text.trim()) return text.trim();
}
return null;
}