Comprehensive change management system for tracking draft and applied changes to tables, dimensions, and metrics within projects. Changesets enable controlled schema evolution with support for create, update, and delete operations, with integration into AI Agent workflows for automated schema modifications.
import { FieldType, type MetricType } from '@lightdash/common';A changeset represents a collection of related schema changes that can be in draft or applied status.
interface Changeset {
changesetUuid: string;
createdAt: Date;
updatedAt: Date;
createdByUserUuid: string;
updatedByUserUuid: string;
projectUuid: string;
status: 'draft' | 'applied';
name: string;
}
interface ChangesetWithChanges extends Changeset {
changes: Change[];
}
type ApiChangesetsResponse = {
status: 'ok';
results: ChangesetWithChanges;
};Individual changes within a changeset target specific entities (tables, dimensions, or metrics) and define the operation to perform.
interface Change extends ChangeBase {
changeUuid: string;
changesetUuid: string;
createdAt: Date;
createdByUserUuid: string;
sourcePromptUuid: string | null; // Links to AI Agent prompt when applicable
}
interface ChangeBase {
entityType: 'table' | 'dimension' | 'metric';
entityTableName: string;
entityName: string;
type: 'create' | 'update' | 'delete';
payload: CreatePayload | UpdatePayload | DeletePayload;
}
type ApiGetChangeResponse = {
status: 'ok';
results: Change;
};Create new metrics with full metadata and SQL definitions.
interface CreatePayload {
type: 'metric';
value: {
fieldType: FieldType.METRIC;
type: MetricType; // sum, count, avg, etc.
name: string;
label: string;
table: string;
tableLabel: string;
sql: string; // Templated SQL expression
description?: string;
hidden: boolean;
compiledSql: string; // Compiled SQL after template resolution
tablesReferences?: string[];
tablesRequiredAttributes?: Record<string, Record<string, string | string[]>>;
};
}Update existing entities using JSON Patch format for precise field modifications.
interface UpdatePayload {
patches: Array<{
op: 'replace' | 'add';
path: string; // JSON Pointer path (e.g., "/label", "/hidden")
value: unknown;
}>;
}Remove entities from the schema.
interface DeletePayload {} // Empty payload for delete operationsParameters for creating new changes within a changeset.
type CreateChangeParams = Pick<
Change,
| 'createdByUserUuid'
| 'sourcePromptUuid'
| 'type'
| 'entityName'
| 'entityType'
| 'entityTableName'
| 'payload'
>;import type { Changeset, ChangesetWithChanges, Change, CreateChangeParams } from '@lightdash/common';
// Create a new metric via changeset
const createMetricChange: CreateChangeParams = {
createdByUserUuid: 'user-123',
sourcePromptUuid: 'prompt-456', // Optional: links to AI Agent prompt
type: 'create',
entityType: 'metric',
entityTableName: 'customers',
entityName: 'total_revenue',
payload: {
type: 'metric',
value: {
fieldType: FieldType.METRIC,
type: MetricType.SUM,
name: 'total_revenue',
label: 'Total Revenue',
table: 'customers',
tableLabel: 'Customers',
sql: '${customers.order_value}',
description: 'Sum of all order values',
hidden: false,
compiledSql: 'SUM(customers.order_value)',
}
}
};
// Update an existing metric's label
const updateChange: CreateChangeParams = {
createdByUserUuid: 'user-123',
sourcePromptUuid: null,
type: 'update',
entityType: 'metric',
entityTableName: 'customers',
entityName: 'total_revenue',
payload: {
patches: [
{
op: 'replace',
path: '/label',
value: 'Total Customer Revenue'
},
{
op: 'replace',
path: '/description',
value: 'Sum of all customer order values'
}
]
}
};
// Delete a metric
const deleteChange: CreateChangeParams = {
createdByUserUuid: 'user-123',
sourcePromptUuid: null,
type: 'delete',
entityType: 'metric',
entityTableName: 'customers',
entityName: 'deprecated_metric',
payload: {}
};sourcePromptUuid for tracking automated schema modifications