open-brainy/src/migration/types.ts
David Snelling 39b099cafc feat: add migration system with error handling, validation, and enterprise hardening
- MigrationRunner: per-entity error tracking (non-fatal), maxErrors bail-out,
  static validateMigrations() called in constructor, branch error propagation
- RefManager: updateRefMetadata() method for clean metadata updates
- brainy.ts: eliminate as-any casts in migration methods, use updateRefMetadata,
  forward maxErrors through full chain including branch migrations
- Types: MigrationError interface, errors field on MigrationResult, maxErrors on MigrateOptions
- Package exports: MigrationError type, migrate() on BrainyInterface, autoMigrate config
- 31 integration tests covering error handling, validation, branch error propagation
- Documentation: docs/guides/schema-migrations.md
2026-02-09 16:13:14 -08:00

83 lines
2.5 KiB
TypeScript

/**
* Migration system types for Brainy
*
* Defines the interfaces for schema migrations that transform
* entity/verb metadata across storage versions.
*/
export interface Migration {
/** Unique migration identifier, e.g., "7.17.0-rename-field" */
id: string
/** Version that introduced this migration */
version: string
/** Human-readable description of what this migration does */
description: string
/** Which entity types this migration applies to */
applies: 'nouns' | 'verbs' | 'both'
/** Return transformed metadata, or null if no change needed */
transform: (metadata: Record<string, unknown>) => Record<string, unknown> | null
}
export interface MigrationState {
/** Last completed migration version */
completedVersion: string
/** Timestamp of last completed migration */
completedAt: number
/** List of completed migration IDs */
completedMigrations: string[]
/** Resume state for crash recovery */
resumeState?: {
migrationId: string
lastProcessedOffset: number
branch: string
}
}
export interface MigrationPreview {
/** Migrations that will be applied */
pendingMigrations: { id: string; description: string }[]
/** Number of entities that would be modified */
affectedEntities: number
/** Total number of entities scanned */
totalEntities: number
/** Sample before/after transformations (up to 5) */
sampleChanges: { id: string; before: Record<string, unknown>; after: Record<string, unknown> }[]
/** Rough time estimate */
estimatedTime: string
}
export interface MigrationError {
/** ID of the entity that failed */
entityId: string
/** ID of the migration that caused the failure */
migrationId: string
/** Error message */
error: string
}
export interface MigrationResult {
/** Backup branch name, or null if no changes were needed */
backupBranch: string | null
/** IDs of migrations that were applied */
migrationsApplied: string[]
/** Total entities processed (scanned) */
entitiesProcessed: number
/** Entities actually modified */
entitiesModified: number
/** Errors encountered during migration (entity-level, non-fatal) */
errors: MigrationError[]
}
export interface MigrateOptions {
/** Preview what would change without writing */
dryRun?: boolean
/** Progress callback for long-running migrations */
onProgress?: (progress: {
migrationId: string
processed: number
modified: number
hasMore: boolean
}) => void
/** Maximum entity-level errors before bailing out (default: 100) */
maxErrors?: number
}