@ -280,7 +280,7 @@ async function validateMigrationApplication<T>(
error ,
error ,
) ;
) ;
}
}
} else if ( migration . name === "003_active_did_separation " ) {
} else if ( migration . name === "003_active_identity_and_seed_backup " ) {
// Validate active_identity table exists and has correct structure
// Validate active_identity table exists and has correct structure
try {
try {
// Check that active_identity table exists
// Check that active_identity table exists
@ -322,6 +322,22 @@ async function validateMigrationApplication<T>(
error ,
error ,
) ;
) ;
}
}
} else if ( migration . name === "003b_add_hasBackedUpSeed_to_settings" ) {
// Validate hasBackedUpSeed column exists in settings table
try {
await sqlQuery ( ` SELECT hasBackedUpSeed FROM settings LIMIT 1 ` ) ;
validation . isValid = true ;
validation . hasExpectedColumns = true ;
} catch ( error ) {
validation . isValid = false ;
validation . errors . push (
` Column hasBackedUpSeed missing from settings table ` ,
) ;
logger . error (
` ❌ [Migration-Validation] Column hasBackedUpSeed missing: ` ,
error ,
) ;
}
}
}
// Add validation for future migrations here
// Add validation for future migrations here
@ -385,7 +401,7 @@ async function isSchemaAlreadyPresent<T>(
// Reduced logging - only log on error
// Reduced logging - only log on error
return false ;
return false ;
}
}
} else if ( migration . name === "003_active_did_separation " ) {
} else if ( migration . name === "003_active_identity_and_seed_backup " ) {
// Check if active_identity table exists and has correct structure
// Check if active_identity table exists and has correct structure
try {
try {
// Check that active_identity table exists
// Check that active_identity table exists
@ -496,14 +512,32 @@ export async function runMigrations<T>(
) ;
) ;
` );
` );
// Step 2: Get list of already applied migrations
// Step 2: Handle migration name changes (master branch compatibility)
// Map old migration names to new ones
const migrationNameMap = new Map ( [
// No longer needed - migrations consolidated into single 003
] ) ;
// Update any old migration names to new ones
for ( const [ oldName , newName ] of migrationNameMap ) {
try {
await sqlExec ( "UPDATE migrations SET name = ? WHERE name = ?" , [ newName , oldName ] ) ;
if ( await sqlQuery ( "SELECT 1 FROM migrations WHERE name = ? LIMIT 1" , [ newName ] ) ) {
migrationLog ( ` 🔄 [Migration] Renamed migration: ${ oldName } → ${ newName } ` ) ;
}
} catch ( error ) {
// Ignore errors - migration might not exist
}
}
// Step 3: Get list of already applied migrations
const appliedMigrationsResult = await sqlQuery (
const appliedMigrationsResult = await sqlQuery (
"SELECT name FROM migrations" ,
"SELECT name FROM migrations" ,
) ;
) ;
const appliedMigrations = extractMigrationNames ( appliedMigrationsResult ) ;
const appliedMigrations = extractMigrationNames ( appliedMigrationsResult ) ;
// Step 3: Get all registered migrations
// Step 4 : Get all registered migrations
const migrations = migrationRegistry . getMigrations ( ) ;
const migrations = migrationRegistry . getMigrations ( ) ;
if ( migrations . length === 0 ) {
if ( migrations . length === 0 ) {
@ -518,7 +552,7 @@ export async function runMigrations<T>(
let appliedCount = 0 ;
let appliedCount = 0 ;
let skippedCount = 0 ;
let skippedCount = 0 ;
// Step 4 : Process each migration
// Step 5 : Process each migration
for ( const migration of migrations ) {
for ( const migration of migrations ) {
// Check 1: Is it recorded as applied in migrations table?
// Check 1: Is it recorded as applied in migrations table?
const isRecordedAsApplied = appliedMigrations . has ( migration . name ) ;
const isRecordedAsApplied = appliedMigrations . has ( migration . name ) ;
@ -557,7 +591,26 @@ export async function runMigrations<T>(
try {
try {
// Execute the migration SQL
// Execute the migration SQL
await sqlExec ( migration . sql ) ;
migrationLog ( ` 🔧 [Migration] Executing SQL for: ${ migration . name } ` ) ;
migrationLog ( ` 🔧 [Migration] SQL content: ${ migration . sql } ` ) ;
const execResult = await sqlExec ( migration . sql ) ;
migrationLog ( ` 🔧 [Migration] SQL execution result: ${ JSON . stringify ( execResult ) } ` ) ;
// Debug: Check if active_identity table exists and has data
if ( migration . name === "003_active_identity_and_seed_backup" ) {
try {
const tableCheck = await sqlQuery ( "SELECT name FROM sqlite_master WHERE type='table' AND name='active_identity'" ) ;
migrationLog ( ` 🔍 [Migration] Table check result: ${ JSON . stringify ( tableCheck ) } ` ) ;
const rowCount = await sqlQuery ( "SELECT COUNT(*) as count FROM active_identity" ) ;
migrationLog ( ` 🔍 [Migration] Row count in active_identity: ${ JSON . stringify ( rowCount ) } ` ) ;
const allRows = await sqlQuery ( "SELECT * FROM active_identity" ) ;
migrationLog ( ` 🔍 [Migration] All rows in active_identity: ${ JSON . stringify ( allRows ) } ` ) ;
} catch ( error ) {
migrationLog ( ` ❌ [Migration] Debug query failed: ${ JSON . stringify ( error ) } ` ) ;
}
}
// Validate the migration was applied correctly
// Validate the migration was applied correctly
const validation = await validateMigrationApplication (
const validation = await validateMigrationApplication (
@ -606,6 +659,8 @@ export async function runMigrations<T>(
` ⚠️ [Migration] Schema validation failed for ${ migration . name } : ` ,
` ⚠️ [Migration] Schema validation failed for ${ migration . name } : ` ,
validation . errors ,
validation . errors ,
) ;
) ;
// Don't mark as applied if validation fails
continue ;
}
}
// Mark the migration as applied since the schema change already exists
// Mark the migration as applied since the schema change already exists