dimensionlab-website/src/lib/server/db/model-migrations.ts
2026-06-18 18:16:21 +02:00

62 lines
1.7 KiB
TypeScript

import {
DASHBOARD_SCHEMA_VERSION,
validateDashboardDocument,
type DashboardDocument,
type DashboardValidationFailure,
} from "$lib/model";
export interface DashboardModelMigrationSuccess {
valid: true;
document: DashboardDocument;
fromVersion: string;
toVersion: typeof DASHBOARD_SCHEMA_VERSION;
migrated: boolean;
}
export interface DashboardModelMigrationFailure {
valid: false;
failure: DashboardValidationFailure;
}
export type DashboardModelMigrationResult =
| DashboardModelMigrationFailure
| DashboardModelMigrationSuccess;
export class UnsupportedDashboardModelVersionError extends Error {
constructor(
readonly fromVersion: string,
readonly toVersion: string,
) {
super(`No dashboard model migration from ${fromVersion} to ${toVersion}`);
this.name = "UnsupportedDashboardModelVersionError";
}
}
export function migrateDashboardDocumentForPersistence(
value: unknown,
): DashboardModelMigrationResult {
const version = readSchemaVersion(value);
if (version && version !== DASHBOARD_SCHEMA_VERSION) {
throw new UnsupportedDashboardModelVersionError(version, DASHBOARD_SCHEMA_VERSION);
}
const validation = validateDashboardDocument(value);
if (!validation.valid) {
return { valid: false, failure: validation };
}
return {
valid: true,
document: validation.data,
fromVersion: DASHBOARD_SCHEMA_VERSION,
toVersion: DASHBOARD_SCHEMA_VERSION,
migrated: false,
};
}
function readSchemaVersion(value: unknown): string | null {
if (!value || typeof value !== "object") return null;
const schemaVersion = (value as { schemaVersion?: unknown }).schemaVersion;
return typeof schemaVersion === "string" ? schemaVersion : null;
}