54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import type { CatalogMetrics } from "./types.js";
|
|
|
|
export interface CatalogMetricCounts {
|
|
tables: number;
|
|
columns: number;
|
|
sensitiveColumns: number;
|
|
relationships: number;
|
|
describedTables: number;
|
|
describedColumns: number;
|
|
}
|
|
|
|
export function hasCatalogDescription(target: {
|
|
description: string | null;
|
|
generatedDescription: string | null;
|
|
}): boolean {
|
|
return Boolean(target.description?.trim() || target.generatedDescription?.trim());
|
|
}
|
|
|
|
export function latestCatalogTimestamp(
|
|
values: readonly (string | null | undefined)[],
|
|
): string | null {
|
|
let latest: number | undefined;
|
|
for (const value of values) {
|
|
if (!value) continue;
|
|
const timestamp = Date.parse(value);
|
|
if (!Number.isFinite(timestamp)) continue;
|
|
latest = latest === undefined ? timestamp : Math.max(latest, timestamp);
|
|
}
|
|
return latest === undefined ? null : new Date(latest).toISOString();
|
|
}
|
|
|
|
export function createCatalogMetrics(
|
|
databaseId: string | undefined,
|
|
counts: CatalogMetricCounts,
|
|
updatedAt: string | null,
|
|
): CatalogMetrics {
|
|
const descriptionTargets = counts.tables + counts.columns;
|
|
const describedTargets = counts.describedTables + counts.describedColumns;
|
|
return {
|
|
scope: databaseId === undefined ? "global" : "database",
|
|
databaseId: databaseId ?? null,
|
|
tables: counts.tables,
|
|
columns: counts.columns,
|
|
sensitiveColumns: counts.sensitiveColumns,
|
|
relationships: counts.relationships,
|
|
descriptionTargets,
|
|
describedTargets,
|
|
descriptionCoverage: descriptionTargets === 0
|
|
? 0
|
|
: Math.round((describedTargets / descriptionTargets) * 100),
|
|
updatedAt,
|
|
};
|
|
}
|