/** * Migration-related type definitions * * Platform-independent migrations that work across SQL and NoSQL databases. * Migrations are translated to database-specific operations by adapters. */ import { IndexType } from './enums'; import { IConnectionConfig } from './connection.interface'; import { IIndexDefinition, IAlterTableOperation } from './schema.interface'; /** * Migration definition * Platform-independent - works across all supported databases */ export interface IMigration { /** Unique migration tag */ tag: string; /** Human-readable name */ name: string; /** Description of what this migration does */ description?: string; /** Operations to apply (up migration) */ up: IMigrationOperation[]; /** Operations to rollback (down migration) */ down: IMigrationOperation[]; /** Dependencies - migrations that must run first */ dependencies?: string[]; /** Timestamp when migration was created */ createdAt?: Date; } /** * Types of migration operations * Unified across SQL and NoSQL databases */ export type IMigrationOperation = ICreateCollectionMigration | IDropCollectionMigration | ICreateIndexMigration | IDropIndexMigration | IAddFieldMigration | IDropFieldMigration | IRenameFieldMigration | IModifyFieldMigration | IAddConstraintMigration | IDropConstraintMigration | ICreateMongoValidationMigration | IDropMongoValidationMigration | IShardCollectionMigration | ICreateDynamoTableMigration | IUpdateDynamoThroughputMigration | IAddDynamoGSIMigration | IRemoveDynamoGSIMigration | IEnableDynamoStreamMigration | IEnableDynamoTTLMigration | IAlterCassandraTableMigration | ICreateCassandraMaterializedViewMigration | IDropCassandraMaterializedViewMigration | IRawOperationMigration; /** * Create collection/table migration * Works for: SQL tables, MongoDB collections, DynamoDB tables, Cassandra tables */ export interface ICreateCollectionMigration { type: 'createCollection'; /** Collection/table name */ name: string; /** Field/column definitions */ fields: IFieldDefinition[]; /** Index definitions */ indexes?: IIndexDefinition[]; /** Only create if doesn't exist */ ifNotExists?: boolean; /** SQL-specific: table options */ sqlOptions?: { /** Primary key columns (for composite keys) */ primaryKey?: string[]; /** Constraints */ constraints?: IConstraintDefinition[]; /** Temporary table */ temporary?: boolean; /** Unlogged table (PostgreSQL) */ unlogged?: boolean; }; /** MongoDB-specific options */ mongoOptions?: { /** Capped collection */ capped?: boolean; /** Max size in bytes (for capped) */ size?: number; /** Max documents (for capped) */ max?: number; /** Validation rules */ validator?: object; /** Validation level */ validationLevel?: 'off' | 'strict' | 'moderate'; }; /** DynamoDB-specific options */ dynamoOptions?: { /** Partition key */ partitionKey: { name: string; type: 'S' | 'N' | 'B'; }; /** Sort key (optional) */ sortKey?: { name: string; type: 'S' | 'N' | 'B'; }; /** Billing mode */ billingMode?: 'PROVISIONED' | 'PAY_PER_REQUEST'; /** Read capacity units (for PROVISIONED) */ readCapacity?: number; /** Write capacity units (for PROVISIONED) */ writeCapacity?: number; /** Global secondary indexes */ globalSecondaryIndexes?: IDynamoGSI[]; /** Local secondary indexes */ localSecondaryIndexes?: IDynamoLSI[]; /** Enable streams */ streamEnabled?: boolean; /** Stream view type */ streamViewType?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'; }; /** Cassandra-specific options */ cassandraOptions?: { /** Partition key columns */ partitionKey: string[]; /** Clustering columns */ clusteringColumns?: string[]; /** Clustering order */ clusteringOrder?: { column: string; order: 'ASC' | 'DESC'; }[]; /** Compaction strategy */ compaction?: object; /** Compression options */ compression?: object; /** TTL in seconds */ defaultTTL?: number; }; } /** * Drop collection/table migration */ export interface IDropCollectionMigration { type: 'dropCollection'; /** Collection/table name */ name: string; /** Only drop if exists */ ifExists?: boolean; /** Cascade to dependent objects (SQL) */ cascade?: boolean; } /** * Platform-independent field/column definition */ export interface IFieldDefinition { /** Field name */ name: string; /** * Field type - platform independent * Use abstract types that map to each database's native types */ type: FieldType; /** Minimum length for string types (validation constraint) */ minLength?: number; /** Maximum length for string types (database column size) */ maxLength?: number; /** Precision (for decimal) */ precision?: number; /** Scale (for decimal) */ scale?: number; /** Allow null values */ nullable?: boolean; /** Primary key */ primaryKey?: boolean; /** Auto increment/generated */ autoGenerate?: boolean; /** Unique constraint */ unique?: boolean; /** Default value */ defaultValue?: any; /** Enum values (for enum type) */ enumValues?: string[]; /** Array element type */ arrayElementType?: FieldType; /** Nested object schema (for document DBs) */ nestedSchema?: IFieldDefinition[]; /** Field comment/description */ comment?: string; } /** * Platform-independent field types * These are translated to database-specific types by adapters */ export type FieldType = 'integer' | 'bigint' | 'smallint' | 'decimal' | 'float' | 'double' | 'string' | 'text' | 'uuid' | 'boolean' | 'date' | 'time' | 'datetime' | 'timestamp' | 'binary' | 'blob' | 'json' | 'object' | 'array' | 'enum' | 'any'; /** * Create index migration * Works for all databases with index support */ export interface ICreateIndexMigration { type: 'createIndex'; /** Collection/table name */ collection: string; /** Index name */ name: string; /** Fields to index */ fields: IIndexFieldDefinition[]; /** Unique index */ unique?: boolean; /** Sparse index (skip null values) */ sparse?: boolean; /** Only create if doesn't exist */ ifNotExists?: boolean; /** SQL-specific options */ sqlOptions?: { /** Index method (BTREE, HASH, GIN, GIST, etc.) */ method?: IndexType | string; /** Partial index condition */ where?: string; /** Include columns (covering index) */ include?: string[]; /** Create concurrently (no lock) */ concurrent?: boolean; }; /** MongoDB-specific options */ mongoOptions?: { /** Background build */ background?: boolean; /** TTL in seconds (for date fields) */ expireAfterSeconds?: number; /** Text index weights */ weights?: Record; /** 2dsphere index options */ '2dsphereIndexVersion'?: number; }; /** Cassandra-specific options */ cassandraOptions?: { /** SASI index options */ sasiOptions?: { mode?: 'PREFIX' | 'CONTAINS' | 'SPARSE'; analyzerClass?: string; caseSensitive?: boolean; }; }; } /** * Index field definition */ export interface IIndexFieldDefinition { /** Field name */ name: string; /** Sort order */ order?: 'asc' | 'desc'; /** Index type for this field (MongoDB: text, 2dsphere, etc.) */ type?: string; } /** * Drop index migration */ export interface IDropIndexMigration { type: 'dropIndex'; /** Collection/table name */ collection: string; /** Index name */ name: string; /** Only drop if exists */ ifExists?: boolean; /** Drop concurrently (SQL) */ concurrent?: boolean; } /** * Add field/column migration */ export interface IAddFieldMigration { type: 'addField'; /** Collection/table name */ collection: string; /** Field definition */ field: IFieldDefinition; } /** * Drop field/column migration */ export interface IDropFieldMigration { type: 'dropField'; /** Collection/table name */ collection: string; /** Field name */ fieldName: string; /** Cascade (SQL) */ cascade?: boolean; } /** * Rename field/column migration */ export interface IRenameFieldMigration { type: 'renameField'; /** Collection/table name */ collection: string; /** Current field name */ oldName: string; /** New field name */ newName: string; } /** * Modify field/column migration */ export interface IModifyFieldMigration { type: 'modifyField'; /** Collection/table name */ collection: string; /** Field name */ fieldName: string; /** New field definition (partial - only changed properties) */ changes: Partial; } /** * Constraint definition */ export interface IConstraintDefinition { /** Constraint name */ name: string; /** Constraint type */ type: 'primaryKey' | 'foreignKey' | 'unique' | 'check'; /** Columns involved */ columns: string[]; /** Foreign key reference */ references?: { table: string; columns: string[]; onDelete?: 'CASCADE' | 'SET_NULL' | 'SET_DEFAULT' | 'RESTRICT' | 'NO_ACTION'; onUpdate?: 'CASCADE' | 'SET_NULL' | 'SET_DEFAULT' | 'RESTRICT' | 'NO_ACTION'; }; /** Check expression */ expression?: string; } /** * Add constraint migration (SQL only) */ export interface IAddConstraintMigration { type: 'addConstraint'; /** Table name */ collection: string; /** Constraint definition */ constraint: IConstraintDefinition; } /** * Drop constraint migration (SQL only) */ export interface IDropConstraintMigration { type: 'dropConstraint'; /** Table name */ collection: string; /** Constraint name */ constraintName: string; /** Cascade */ cascade?: boolean; } /** * Create/update MongoDB validation schema */ export interface ICreateMongoValidationMigration { type: 'createMongoValidation'; /** Collection name */ collection: string; /** JSON Schema validator */ validator: object; /** Validation level */ validationLevel?: 'off' | 'strict' | 'moderate'; /** Validation action */ validationAction?: 'error' | 'warn'; } /** * Remove MongoDB validation schema */ export interface IDropMongoValidationMigration { type: 'dropMongoValidation'; /** Collection name */ collection: string; } /** * Shard a MongoDB collection */ export interface IShardCollectionMigration { type: 'shardCollection'; /** Collection name */ collection: string; /** Shard key */ shardKey: Record; /** Unique shard key */ unique?: boolean; } /** * DynamoDB Global Secondary Index definition */ export interface IDynamoGSI { /** Index name */ name: string; /** Partition key */ partitionKey: { name: string; type: 'S' | 'N' | 'B'; }; /** Sort key */ sortKey?: { name: string; type: 'S' | 'N' | 'B'; }; /** Projection type */ projection: 'ALL' | 'KEYS_ONLY' | { type: 'INCLUDE'; attributes: string[]; }; /** Read capacity */ readCapacity?: number; /** Write capacity */ writeCapacity?: number; } /** * DynamoDB Local Secondary Index definition */ export interface IDynamoLSI { /** Index name */ name: string; /** Sort key (partition key inherited from table) */ sortKey: { name: string; type: 'S' | 'N' | 'B'; }; /** Projection type */ projection: 'ALL' | 'KEYS_ONLY' | { type: 'INCLUDE'; attributes: string[]; }; } /** * Create DynamoDB table (alternative to createCollection for more control) */ export interface ICreateDynamoTableMigration { type: 'createDynamoTable'; /** Table name */ name: string; /** Partition key */ partitionKey: { name: string; type: 'S' | 'N' | 'B'; }; /** Sort key */ sortKey?: { name: string; type: 'S' | 'N' | 'B'; }; /** Billing mode */ billingMode?: 'PROVISIONED' | 'PAY_PER_REQUEST'; /** Read capacity units */ readCapacity?: number; /** Write capacity units */ writeCapacity?: number; /** Global secondary indexes */ globalSecondaryIndexes?: IDynamoGSI[]; /** Local secondary indexes */ localSecondaryIndexes?: IDynamoLSI[]; /** Enable streams */ streamEnabled?: boolean; /** Stream view type */ streamViewType?: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'; /** Enable point-in-time recovery */ pointInTimeRecovery?: boolean; /** Server-side encryption */ sseEnabled?: boolean; } /** * Update DynamoDB table throughput */ export interface IUpdateDynamoThroughputMigration { type: 'updateDynamoThroughput'; /** Table name */ name: string; /** New read capacity */ readCapacity?: number; /** New write capacity */ writeCapacity?: number; /** Switch to on-demand */ billingMode?: 'PROVISIONED' | 'PAY_PER_REQUEST'; } /** * Add DynamoDB Global Secondary Index */ export interface IAddDynamoGSIMigration { type: 'addDynamoGSI'; /** Table name */ tableName: string; /** GSI definition */ gsi: IDynamoGSI; } /** * Remove DynamoDB Global Secondary Index */ export interface IRemoveDynamoGSIMigration { type: 'removeDynamoGSI'; /** Table name */ tableName: string; /** GSI name */ gsiName: string; } /** * Enable DynamoDB Streams */ export interface IEnableDynamoStreamMigration { type: 'enableDynamoStream'; /** Table name */ tableName: string; /** Stream view type */ streamViewType: 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES'; } /** * Enable DynamoDB TTL */ export interface IEnableDynamoTTLMigration { type: 'enableDynamoTTL'; /** Table name */ tableName: string; /** TTL attribute name */ attributeName: string; /** Enable or disable */ enabled: boolean; } /** * Alter Cassandra table options */ export interface IAlterCassandraTableMigration { type: 'alterCassandraTable'; /** Table name */ name: string; /** New options */ options: { /** Default TTL */ defaultTTL?: number; /** Compaction options */ compaction?: object; /** Compression options */ compression?: object; /** Caching options */ caching?: object; /** GC grace seconds */ gcGraceSeconds?: number; }; } /** * Create Cassandra materialized view */ export interface ICreateCassandraMaterializedViewMigration { type: 'createCassandraMaterializedView'; /** View name */ name: string; /** Base table */ baseTable: string; /** Selected columns */ columns: string[]; /** Where clause (required for MV) */ where: string; /** Partition key */ partitionKey: string[]; /** Clustering columns */ clusteringColumns?: string[]; } /** * Drop Cassandra materialized view */ export interface IDropCassandraMaterializedViewMigration { type: 'dropCassandraMaterializedView'; /** View name */ name: string; /** Only drop if exists */ ifExists?: boolean; } /** * Raw operation for database-specific commands * Use sparingly - prefer platform-independent operations */ export interface IRawOperationMigration { type: 'raw'; /** Target database types (leave empty for all) */ databases?: ('postgresql' | 'mysql' | 'mariadb' | 'mongodb' | 'dynamodb' | 'cassandra')[]; /** Operations per database type */ operations: { /** PostgreSQL raw SQL */ postgresql?: { sql: string; params?: any[]; }; /** MySQL raw SQL */ mysql?: { sql: string; params?: any[]; }; /** MariaDB raw SQL */ mariadb?: { sql: string; params?: any[]; }; /** MongoDB command */ mongodb?: { command: object; }; /** DynamoDB operation */ dynamodb?: { operation: string; params: object; }; /** Cassandra CQL */ cassandra?: { cql: string; params?: any[]; }; }; } /** * Migration history entry */ export interface IMigrationHistory { /** Migration tag */ tag: string; /** Migration name */ name: string; /** When migration was applied */ appliedAt: Date; /** Who applied the migration */ appliedBy?: string; /** Checksum for verification */ checksum?: string; /** Execution time in milliseconds */ executionTime?: number; /** Environment where applied */ environment?: string; } /** * Options for getting migration status */ export interface IMigrationStatusOptions extends IConnectionConfig { /** All defined migrations to check against */ definedMigrations: IMigration[]; } /** * Migration status result */ export interface IMigrationStatusResult { /** Total number of defined migrations */ total: number; /** Number of applied migrations */ completed: number; /** Number of pending migrations */ pending: number; /** Last applied migration */ lastApplied?: IMigrationHistory; /** List of pending migration tags */ pendingMigrations: string[]; /** List of applied migration tags */ appliedMigrations: string[]; } /** * Result of running a migration */ export interface IMigrationResult { /** Whether migration was successful */ success: boolean; /** Operations executed */ operations: string[]; /** Error message if failed */ error?: string; /** Execution time in milliseconds */ executionTime?: number; } /** @deprecated Use ICreateCollectionMigration */ export type ICreateTableMigration = ICreateCollectionMigration; /** @deprecated Use IDropCollectionMigration */ export type IDropTableMigration = IDropCollectionMigration; /** @deprecated Use IAddFieldMigration */ export type IAddColumnMigration = IAddFieldMigration; /** @deprecated Use IDropFieldMigration */ export type IDropColumnMigration = IDropFieldMigration; /** @deprecated Use IRenameFieldMigration */ export type IRenameColumnMigration = IRenameFieldMigration; /** @deprecated Use IModifyFieldMigration with collection instead */ export interface IAlterTableMigration { type: 'alterTable'; tableName: string; operations: IAlterTableOperation[]; } /** @deprecated Use IRawOperationMigration */ export interface IRawSqlMigration { type: 'rawSql'; sql: string; params?: any[]; } /** * Helper function signatures for creating migrations */ export interface IMigrationHelpers { /** Create a collection/table migration */ createCollectionMigration(tag: string, name: string, fields: IFieldDefinition[]): IMigration; /** Create an add field migration */ addFieldMigration(tag: string, collection: string, field: IFieldDefinition): IMigration; /** Create an add index migration */ addIndexMigration(tag: string, collection: string, indexName: string, fields: string[], unique?: boolean): IMigration; /** Generate a migration tag with timestamp */ generateMigrationTag(name: string): string; }