feat: add AI catalog description generation

This commit is contained in:
Codex
2026-08-29 16:42:56 +02:00
parent b0afba81ca
commit 376dd5a09d
76 changed files with 14860 additions and 102 deletions
+121
View File
@@ -132,6 +132,13 @@ export interface CatalogMetadataDeleteCounts {
relationships: number;
}
export type CatalogDescriptionTarget = "tables" | "columns";
export interface CatalogDescriptionConsolidationCounts {
copied: number;
skipped: number;
}
export type CatalogSyncScope = "tables" | "columns" | "relationships" | "all";
export type CatalogSyncState = "queued" | "running" | "awaiting_confirmation" | "applying"
| "succeeded" | "failed" | "cancelled" | "interrupted";
@@ -176,8 +183,113 @@ export interface CatalogSyncEvent {
createdAt: string;
}
export interface MetadataGenerationModel {
id: string;
label: string;
}
export interface MetadataGenerationModels {
models: MetadataGenerationModel[];
default: string | null;
}
export type DescriptionGenerationScope = "selected_columns" | "selected_tables" | "all" | "missing";
export type DescriptionGenerationStatus = "queued" | "running" | "completed"
| "completed_with_errors" | "cancelled" | "failed" | "interrupted";
export interface DescriptionGenerationRun {
id: string;
databaseId: string;
scope: DescriptionGenerationScope;
modelId: string;
language: "en" | "it";
status: DescriptionGenerationStatus;
total: number;
processed: number;
generated: number;
nonGeneratable: number;
failed: number;
createdAt: string;
startedAt: string | null;
updatedAt: string;
finishedAt: string | null;
errorSummary: string | null;
}
export interface DescriptionGenerationEvent {
sequence: number;
level: "info" | "warning" | "error";
message: string;
createdAt: string;
}
export const listCatalogDatabases = () => apiFetch<CatalogDatabase[]>("/catalog/databases");
export const listMetadataGenerationModels = () =>
apiFetch<MetadataGenerationModels>("/catalog/metadata-generation/models");
export function startDescriptionGenerationRun(
databaseId: string,
modelId: string,
scope: Extract<DescriptionGenerationScope, "selected_columns" | "selected_tables">,
targetIds: string[],
): Promise<DescriptionGenerationRun>;
export function startDescriptionGenerationRun(
databaseId: string,
modelId: string,
scope: Extract<DescriptionGenerationScope, "all" | "missing">,
): Promise<DescriptionGenerationRun>;
export function startDescriptionGenerationRun(
databaseId: string,
modelId: string,
scope: DescriptionGenerationScope,
targetIds?: string[],
): Promise<DescriptionGenerationRun> {
const body = scope === "all" || scope === "missing"
? { modelId, scope }
: { modelId, scope, targetIds: targetIds ?? [] };
return apiFetch<DescriptionGenerationRun>(
`/catalog/databases/${encodeURIComponent(databaseId)}/description-generation-runs`,
{ method: "POST", body: JSON.stringify(body) },
);
}
export const getDescriptionGenerationRun = (runId: string) =>
apiFetch<DescriptionGenerationRun>(
`/catalog/description-generation-runs/${encodeURIComponent(runId)}`,
);
export const listDescriptionGenerationRuns = (limit = 50) =>
apiFetch<DescriptionGenerationRun[]>(
`/catalog/description-generation-runs?limit=${encodeURIComponent(String(limit))}`,
);
export const listDescriptionGenerationEvents = (runId: string, after = 0) =>
apiFetch<DescriptionGenerationEvent[]>(
`/catalog/description-generation-runs/${encodeURIComponent(runId)}/events-list?after=${after}`,
);
export const cancelDescriptionGenerationRun = (runId: string) =>
apiFetch<DescriptionGenerationRun>(
`/catalog/description-generation-runs/${encodeURIComponent(runId)}/cancel`,
{ method: "POST" },
);
export const unlockDescriptionGenerationRun = () =>
apiFetch<DescriptionGenerationRun>(
"/catalog/description-generation-runs/unlock",
{ method: "POST" },
);
export function descriptionGenerationEventsUrl(runId: string, after = 0): string {
const url = joinBackendPath(
BASE,
`/catalog/description-generation-runs/${encodeURIComponent(runId)}/events?after=${after}`,
);
assertSameOriginRequestUrl(url);
return url;
}
export const createCatalogDatabase = (input: DatabaseConfiguration) =>
apiFetch<CatalogDatabase>("/catalog/databases", { method: "POST", body: JSON.stringify(input) });
@@ -254,6 +366,15 @@ export const deleteCatalogTableMetadata = (
{ method: "POST", body: JSON.stringify({ tableIds, target }) },
);
export const consolidateCatalogDescriptions = (
databaseId: string,
target: CatalogDescriptionTarget,
targetIds: string[],
) => apiFetch<CatalogDescriptionConsolidationCounts>(
`/catalog/databases/${encodeURIComponent(databaseId)}/descriptions/consolidate`,
{ method: "POST", body: JSON.stringify({ target, targetIds }) },
);
export const startCatalogSync = (
databaseId: string,
version: number,