@ -580,8 +580,8 @@
: key = "setting.id"
class = "text-xs text-gray-600 bg-gray-50 p-2 rounded"
>
< div class = "font-medium" > ID : { { setting . id } } ( { { setting . id === 1 ? 'master' : 'account' } } ) < / div >
< div class = "text-gray-500" > { { setting . activeDid || setting . accountD id } } < / div >
< div class = "font-medium" > { { getSettingDisplayName ( setting ) } } < / div >
< div class = "text-gray-500" > ID : { { setting . id } } < / div >
< div class = "text-gray-400" > Registered : { { setting . isRegistered ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
@ -601,8 +601,8 @@
: key = "setting.id"
class = "text-xs text-gray-600 bg-gray-50 p-2 rounded"
>
< div class = "font-medium" > ID : { { setting . id } } ( { { setting . id === 1 ? 'master' : 'account' } } ) < / div >
< div class = "text-gray-500" > { { setting . activeDid || setting . accountD id } } < / div >
< div class = "font-medium" > { { getSettingDisplayName ( setting ) } } < / div >
< div class = "text-gray-500" > ID : { { setting . id } } < / div >
< div class = "text-gray-400" > Registered : { { setting . isRegistered ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
@ -622,8 +622,8 @@
: key = "setting.id"
class = "text-xs text-gray-600 bg-gray-50 p-2 rounded"
>
< div class = "font-medium" > ID : { { setting . id } } ( { { setting . id === 1 ? 'master' : 'account' } } ) < / div >
< div class = "text-gray-500" > { { setting . activeDid || setting . accountD id } } < / div >
< div class = "font-medium" > { { getSettingDisplayName ( setting ) } } < / div >
< div class = "text-gray-500" > ID : { { setting . id } } < / div >
< div class = "text-gray-400" > Registered : { { setting . isRegistered ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
@ -706,8 +706,8 @@
< div class = "font-medium" > ID : { { account . id } } < / div >
< div class = "text-gray-500" > { { account . did } } < / div >
< div class = "text-gray-400" > Created : { { account . dateCreated } } < / div >
< div class = "text-gray-400" > Has Identity : { { account . identity ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { account . mnemonic ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Identity : { { getAccountHasIdentity ( account ) ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { getAccountHasMnemonic ( account ) ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
< / div >
@ -729,8 +729,8 @@
< div class = "font-medium" > ID : { { account . id } } < / div >
< div class = "text-gray-500" > { { account . did } } < / div >
< div class = "text-gray-400" > Created : { { account . dateCreated } } < / div >
< div class = "text-gray-400" > Has Identity : { { account . identity ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { account . mnemonic ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Identity : { { getAccountHasIdentity ( account ) ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { getAccountHasMnemonic ( account ) ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
< / div >
@ -752,8 +752,8 @@
< div class = "font-medium" > ID : { { account . id } } < / div >
< div class = "text-gray-500" > { { account . did } } < / div >
< div class = "text-gray-400" > Created : { { account . dateCreated } } < / div >
< div class = "text-gray-400" > Has Identity : { { account . identity ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { account . mnemonic ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Identity : { { getAccountHasIdentity ( account ) ? 'Yes' : 'No' } } < / div >
< div class = "text-gray-400" > Has Mnemonic : { { getAccountHasMnemonic ( account ) ? 'Yes' : 'No' } } < / div >
< / div >
< / div >
< / div >
@ -857,6 +857,76 @@ export default class DatabaseMigration extends Vue {
return USE_DEXIE_DB ;
}
/ * *
* Computed property to get the display name for a setting
* Handles both live comparison data and exported JSON format
*
* @ param { any } setting - The setting object
* @ returns { string } The display name for the setting
* /
getSettingDisplayName ( setting : any ) : string {
/ / H a n d l e e x p o r t e d J S O N f o r m a t ( h a s ' t y p e ' a n d ' d i d ' f i e l d s )
if ( setting . type && setting . did ) {
return ` ${ setting . type } ( ${ setting . did } ) ` ;
}
/ / H a n d l e l i v e c o m p a r i s o n d a t a ( h a s ' a c t i v e D i d ' o r ' a c c o u n t D i d ' f i e l d s )
const did = setting . activeDid || setting . accountDid ;
const type = setting . id === 1 ? 'master' : 'account' ;
return ` ${ type } ( ${ did || 'no DID' } ) ` ;
}
/ * *
* Computed property to get the DID for a setting
* Handles both live comparison data and exported JSON format
*
* @ param { any } setting - The setting object
* @ returns { string } The DID for the setting
* /
getSettingDid ( setting : any ) : string {
/ / H a n d l e e x p o r t e d J S O N f o r m a t ( h a s ' d i d ' f i e l d )
if ( setting . did ) {
return setting . did ;
}
/ / H a n d l e l i v e c o m p a r i s o n d a t a ( h a s ' a c t i v e D i d ' o r ' a c c o u n t D i d ' f i e l d s )
return setting . activeDid || setting . accountDid || 'no DID' ;
}
/ * *
* Computed property to check if an account has identity
* Handles both live comparison data and exported JSON format
*
* @ param { any } account - The account object
* @ returns { boolean } True if account has identity
* /
getAccountHasIdentity ( account : any ) : boolean {
/ / H a n d l e e x p o r t e d J S O N f o r m a t ( h a s ' h a s I d e n t i t y ' f i e l d )
if ( account . hasIdentity !== undefined ) {
return account . hasIdentity ;
}
/ / H a n d l e l i v e c o m p a r i s o n d a t a ( h a s ' i d e n t i t y ' f i e l d )
return ! ! account . identity ;
}
/ * *
* Computed property to check if an account has mnemonic
* Handles both live comparison data and exported JSON format
*
* @ param { any } account - The account object
* @ returns { boolean } True if account has mnemonic
* /
getAccountHasMnemonic ( account : any ) : boolean {
/ / H a n d l e e x p o r t e d J S O N f o r m a t ( h a s ' h a s M n e m o n i c ' f i e l d )
if ( account . hasMnemonic !== undefined ) {
return account . hasMnemonic ;
}
/ / H a n d l e l i v e c o m p a r i s o n d a t a ( h a s ' m n e m o n i c ' f i e l d )
return ! ! account . mnemonic ;
}
/ * *
* Migrates all data from Dexie to SQLite in the proper order
*
@ -1078,12 +1148,10 @@ export default class DatabaseMigration extends Vue {
}
/ * *
* Verifies the migration by running another comparison
* Verifies the migration by running a fresh comparison
*
* This method runs a fresh comparison between Dexie and SQLite databases
* to verify that the migration was successful . It ' s useful to run this
* after completing migrations to ensure data integrity and relationship
* preservation .
* This method runs a new comparison after migration to verify
* that the data was transferred correctly .
*
* @ async
* @ returns { Promise < void > }
@ -1095,74 +1163,23 @@ export default class DatabaseMigration extends Vue {
try {
const newComparison = await compareDatabases ( ) ;
/ / C a l c u l a t e d i f f e r e n c e s b y t y p e f o r e a c h t a b l e
const differences = {
contacts : {
added : newComparison . differences . contacts . added . length ,
modified : newComparison . differences . contacts . modified . length ,
missing : newComparison . differences . contacts . missing . length ,
} ,
settings : {
added : newComparison . differences . settings . added . length ,
modified : newComparison . differences . settings . modified . length ,
missing : newComparison . differences . settings . missing . length ,
} ,
accounts : {
added : newComparison . differences . accounts . added . length ,
modified : newComparison . differences . accounts . modified . length ,
missing : newComparison . differences . accounts . missing . length ,
} ,
} ;
const totalRemaining = Object . values ( differences ) . reduce (
( sum , table ) =>
sum + table . added + table . modified + table . missing ,
0
) ;
/ / B u i l d a d e t a i l e d m e s s a g e
const detailMessages = [ ] ;
if ( differences . contacts . added + differences . contacts . modified + differences . contacts . missing > 0 ) {
detailMessages . push (
` Contacts: ${ differences . contacts . added } to add, ${ differences . contacts . modified } modified, ${ differences . contacts . missing } missing `
) ;
}
if ( differences . settings . added + differences . settings . modified + differences . settings . missing > 0 ) {
detailMessages . push (
` Settings: ${ differences . settings . added } to add, ${ differences . settings . modified } modified, ${ differences . settings . missing } missing `
) ;
}
if ( differences . accounts . added + differences . accounts . modified + differences . accounts . missing > 0 ) {
detailMessages . push (
` Accounts: ${ differences . accounts . added } to add, ${ differences . accounts . modified } modified, ${ differences . accounts . missing } missing `
) ;
}
const totalRemaining =
newComparison . differences . contacts . added . length +
newComparison . differences . settings . added . length +
newComparison . differences . accounts . added . length ;
if ( totalRemaining === 0 ) {
this . successMessage =
"✅ Migration verification successful! All data has been migrated correctly." ;
logger . info (
"[DatabaseMigration] Migration verification successful - no differences found"
) ;
this . successMessage = "Migration verification successful! All data has been migrated." ;
this . comparison = newComparison ;
} else {
this . successMessage = ` ⚠️ Migration verification completed. Found ${ totalRemaining } remaining differences: \ n ${ detailMessages . join ( "\n" ) } ` ;
if ( differences . settings . modified > 0 || differences . settings . missing > 0 ) {
this . successMessage += "\n\nNote: Some settings differences may be expected due to default values in SQLite." ;
}
logger . warn (
"[DatabaseMigration] Migration verification found remaining differences" ,
{
remaining : totalRemaining ,
differences : differences ,
}
) ;
this . error = ` Migration verification failed. ${ totalRemaining } items still need to be migrated. ` ;
this . comparison = newComparison ;
}
/ / U p d a t e t h e c o m p a r i s o n t o s h o w t h e c u r r e n t s t a t e
this . comparison = newComparison ;
logger . info ( "[DatabaseMigration] Migration verification completed" , {
totalRemaining ,
success : totalRemaining === 0
} ) ;
} catch ( error ) {
this . error = ` Failed to verify migration: ${ error } ` ;
logger . error ( "[DatabaseMigration] Migration verification failed:" , error ) ;
@ -1172,10 +1189,10 @@ export default class DatabaseMigration extends Vue {
}
/ * *
* Exports comparison results to a file
* Exports the comparison data to a JSON file
*
* This method generates a YAML - formatted comparison and triggers
* a file download for the user .
* This method generates a JSON file containing the complete comparison
* data in a format that matches the exported JSON structure .
*
* @ async
* @ returns { Promise < void > }
@ -1191,40 +1208,22 @@ export default class DatabaseMigration extends Vue {
const blob = new Blob ( [ yamlData ] , { type : "application/json" } ) ;
const url = URL . createObjectURL ( blob ) ;
const link = document . createElement ( "a" ) ;
link . href = url ;
link . download = ` database-comparison- ${ new Date ( ) . toISOString ( ) . split ( "T" ) [ 0 ] } .json ` ;
document . body . appendChild ( link ) ;
link . click ( ) ;
document . body . removeChild ( link ) ;
const a = document . createElement ( "a" ) ;
a . href = url ;
a . download = ` database-comparison- ${ new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] } .json ` ;
document . body . appendChild ( a ) ;
a . click ( ) ;
document . body . removeChild ( a ) ;
URL . revokeObjectURL ( url ) ;
this . successMessage = "Comparison exported successfully" ;
logger . info ( "[DatabaseMigration] Comparison exported successfully" ) ;
this . successMessage = "Comparison data exported successfully" ;
logger . info ( "[DatabaseMigration] Comparison data exported successfully" ) ;
} catch ( error ) {
this . error = ` Failed to export comparison: ${ error } ` ;
this . error = ` Failed to export comparison data : ${ error } ` ;
logger . error ( "[DatabaseMigration] Export failed:" , error ) ;
}
}
/ * *
* Sets the loading state and message
*
* @ param { string } message - The loading message to display
* /
private setLoading ( message : string ) : void {
this . isLoading = message !== "" ;
this . loadingMessage = message ;
}
/ * *
* Clears all error and success messages
* /
private clearMessages ( ) : void {
this . error = "" ;
this . successMessage = "" ;
}
/ * *
* Tests the specific settings migration for the fields you mentioned
*
@ -1252,5 +1251,23 @@ export default class DatabaseMigration extends Vue {
this . setLoading ( "" ) ;
}
}
/ * *
* Sets the loading state and message
*
* @ param { string } message - The loading message to display
* /
private setLoading ( message : string ) : void {
this . isLoading = message !== "" ;
this . loadingMessage = message ;
}
/ * *
* Clears all error and success messages
* /
private clearMessages ( ) : void {
this . error = "" ;
this . successMessage = "" ;
}
}
< / script >