forked from jsnbuchanan/crowd-funder-for-time-pwa
refactor: implement team feedback for active identity migration structure
- Update migration 003 to match master deployment (hasBackedUpSeed) - Rename migration 004 for active_identity table creation - Update migration service validation for new structure - Fix TypeScript compatibility issue in migration.ts - Streamline active identity upgrade plan documentation - Ensure all migrations are additional per team guidance Migration structure now follows "additional migrations only" principle: - 003: hasBackedUpSeed (assumes master deployment) - 004: active_identity table with data migration - iOS/Android compatibility confirmed with SQLCipher 4.9.0 Files: migration.ts, migrationService.ts, active-identity-upgrade-plan.md
This commit is contained in:
@@ -35,7 +35,7 @@ interface DatabaseResult {
|
||||
// where they couldn't take action because they couldn't unlock that identity.)
|
||||
|
||||
const randomBytes = crypto.getRandomValues(new Uint8Array(32));
|
||||
const secretBase64 = arrayBufferToBase64(randomBytes);
|
||||
const secretBase64 = arrayBufferToBase64(randomBytes.buffer);
|
||||
|
||||
// Each migration can include multiple SQL statements (with semicolons)
|
||||
const MIGRATIONS = [
|
||||
@@ -132,8 +132,20 @@ const MIGRATIONS = [
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "003_active_identity_and_seed_backup",
|
||||
name: "003_add_hasBackedUpSeed_to_settings",
|
||||
sql: `
|
||||
-- Add hasBackedUpSeed field to settings
|
||||
-- This migration assumes master code has been deployed
|
||||
-- The error handling will catch this if column already exists and mark migration as applied
|
||||
ALTER TABLE settings ADD COLUMN hasBackedUpSeed BOOLEAN DEFAULT FALSE;
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "004_active_identity_and_seed_backup",
|
||||
sql: `
|
||||
-- Migration 004: active_identity_and_seed_backup
|
||||
-- Assumes master code deployed with migration 003 (hasBackedUpSeed)
|
||||
|
||||
-- Enable foreign key constraints for data integrity
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
@@ -152,7 +164,6 @@ const MIGRATIONS = [
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_identity_single_record ON active_identity(id);
|
||||
|
||||
-- Seed singleton row (only if not already exists)
|
||||
-- Use a more explicit approach to ensure the row gets inserted
|
||||
INSERT INTO active_identity (id, activeDid, lastUpdated)
|
||||
SELECT 1, NULL, datetime('now')
|
||||
WHERE NOT EXISTS (SELECT 1 FROM active_identity WHERE id = 1);
|
||||
@@ -174,15 +185,6 @@ const MIGRATIONS = [
|
||||
SELECT 'DEBUG: Row count after insertion' as debug_message, COUNT(*) as row_count FROM active_identity;
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "003b_add_hasBackedUpSeed_to_settings",
|
||||
sql: `
|
||||
-- Add hasBackedUpSeed field to settings
|
||||
-- This may fail if column already exists from master branch migration
|
||||
-- The error handling will catch this and mark migration as applied
|
||||
ALTER TABLE settings ADD COLUMN hasBackedUpSeed BOOLEAN DEFAULT FALSE;
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -280,7 +280,23 @@ async function validateMigrationApplication<T>(
|
||||
error,
|
||||
);
|
||||
}
|
||||
} else if (migration.name === "003_active_identity_and_seed_backup") {
|
||||
} else if (migration.name === "003_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,
|
||||
);
|
||||
}
|
||||
} else if (migration.name === "004_active_identity_and_seed_backup") {
|
||||
// Validate active_identity table exists and has correct structure
|
||||
try {
|
||||
// Check that active_identity table exists
|
||||
@@ -315,29 +331,13 @@ async function validateMigrationApplication<T>(
|
||||
} catch (error) {
|
||||
validation.isValid = false;
|
||||
validation.errors.push(
|
||||
`Validation error for active_did_separation: ${error}`,
|
||||
`Validation error for active_identity_and_seed_backup: ${error}`,
|
||||
);
|
||||
logger.error(
|
||||
`❌ [Migration-Validation] Validation failed for ${migration.name}:`,
|
||||
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
|
||||
@@ -401,7 +401,15 @@ async function isSchemaAlreadyPresent<T>(
|
||||
// Reduced logging - only log on error
|
||||
return false;
|
||||
}
|
||||
} else if (migration.name === "003_active_identity_and_seed_backup") {
|
||||
} else if (migration.name === "003_add_hasBackedUpSeed_to_settings") {
|
||||
// Check if hasBackedUpSeed column exists in settings table
|
||||
try {
|
||||
await sqlQuery(`SELECT hasBackedUpSeed FROM settings LIMIT 1`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
} else if (migration.name === "004_active_identity_and_seed_backup") {
|
||||
// Check if active_identity table exists and has correct structure
|
||||
try {
|
||||
// Check that active_identity table exists
|
||||
@@ -608,7 +616,7 @@ export async function runMigrations<T>(
|
||||
);
|
||||
|
||||
// Debug: Check if active_identity table exists and has data
|
||||
if (migration.name === "003_active_identity_and_seed_backup") {
|
||||
if (migration.name === "004_active_identity_and_seed_backup") {
|
||||
try {
|
||||
const tableCheck = await sqlQuery(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='active_identity'",
|
||||
|
||||
Reference in New Issue
Block a user