forked from jsnbuchanan/crowd-funder-for-time-pwa
Merge branch 'active_did_redux' of ssh://173.199.124.46:222/trent_larson/crowd-funder-for-time-pwa into active_did_redux
This commit is contained in:
@@ -65,6 +65,14 @@ Follow this implementation checklist step-by-step to complete the migration.
|
|||||||
|
|
||||||
-- Insert default record (will be updated during migration)
|
-- Insert default record (will be updated during migration)
|
||||||
INSERT OR IGNORE INTO active_identity (id, activeDid, lastUpdated) VALUES (1, '', datetime('now'));
|
INSERT OR IGNORE INTO active_identity (id, activeDid, lastUpdated) VALUES (1, '', datetime('now'));
|
||||||
|
|
||||||
|
-- MIGRATE EXISTING DATA: Copy activeDid from settings to active_identity
|
||||||
|
-- This prevents data loss when migration runs on existing databases
|
||||||
|
UPDATE active_identity
|
||||||
|
SET activeDid = (SELECT activeDid FROM settings WHERE id = 1),
|
||||||
|
lastUpdated = datetime('now')
|
||||||
|
WHERE id = 1
|
||||||
|
AND EXISTS (SELECT 1 FROM settings WHERE id = 1 AND activeDid IS NOT NULL AND activeDid != '');
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
@@ -282,11 +290,9 @@ async function migrateActiveDidToSeparateTable(): Promise<MigrationResult> {
|
|||||||
result.warnings.push(`Successfully migrated activeDid: ${activeDid}`);
|
result.warnings.push(`Successfully migrated activeDid: ${activeDid}`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
result.errors.push(`Migration failed: ${error}`);
|
logger.error("[PlatformServiceMixin] Error getting active identity:", error);
|
||||||
logger.error("[ActiveDid Migration] Critical error during migration:", error);
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,33 @@ const MIGRATIONS = [
|
|||||||
ALTER TABLE contacts ADD COLUMN iViewContent BOOLEAN DEFAULT TRUE;
|
ALTER TABLE contacts ADD COLUMN iViewContent BOOLEAN DEFAULT TRUE;
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "003_active_did_separate_table",
|
||||||
|
sql: `
|
||||||
|
-- Create new active_identity table with proper constraints
|
||||||
|
CREATE TABLE IF NOT EXISTS active_identity (
|
||||||
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||||
|
activeDid TEXT NOT NULL,
|
||||||
|
lastUpdated TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
FOREIGN KEY (activeDid) REFERENCES accounts(did) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Add performance indexes
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_active_identity_activeDid ON active_identity(activeDid);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_identity_single_record ON active_identity(id);
|
||||||
|
|
||||||
|
-- Insert default record (will be updated during migration)
|
||||||
|
INSERT OR IGNORE INTO active_identity (id, activeDid, lastUpdated) VALUES (1, '', datetime('now'));
|
||||||
|
|
||||||
|
-- MIGRATE EXISTING DATA: Copy activeDid from settings to active_identity
|
||||||
|
-- This prevents data loss when migration runs on existing databases
|
||||||
|
UPDATE active_identity
|
||||||
|
SET activeDid = (SELECT activeDid FROM settings WHERE id = 1),
|
||||||
|
lastUpdated = datetime('now')
|
||||||
|
WHERE id = 1
|
||||||
|
AND EXISTS (SELECT 1 FROM settings WHERE id = 1 AND activeDid IS NOT NULL AND activeDid != '');
|
||||||
|
`,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
14
src/db/tables/activeIdentity.ts
Normal file
14
src/db/tables/activeIdentity.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* ActiveIdentity type describes the active identity selection.
|
||||||
|
* This replaces the activeDid field in the settings table for better
|
||||||
|
* database architecture and data integrity.
|
||||||
|
*
|
||||||
|
* @author Matthew Raymer
|
||||||
|
* @since 2025-08-29
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ActiveIdentity {
|
||||||
|
id: number;
|
||||||
|
activeDid: string;
|
||||||
|
lastUpdated: string;
|
||||||
|
}
|
||||||
@@ -58,6 +58,7 @@ import {
|
|||||||
generateInsertStatement,
|
generateInsertStatement,
|
||||||
generateUpdateStatement,
|
generateUpdateStatement,
|
||||||
} from "@/utils/sqlHelpers";
|
} from "@/utils/sqlHelpers";
|
||||||
|
import { ActiveIdentity } from "@/db/tables/activeIdentity";
|
||||||
|
|
||||||
// =================================================
|
// =================================================
|
||||||
// TYPESCRIPT INTERFACES
|
// TYPESCRIPT INTERFACES
|
||||||
@@ -548,6 +549,40 @@ export const PlatformServiceMixin = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get active identity from the new active_identity table
|
||||||
|
* This replaces the activeDid field in settings for better architecture
|
||||||
|
*/
|
||||||
|
async $getActiveIdentity(): Promise<ActiveIdentity> {
|
||||||
|
try {
|
||||||
|
const result = await this.$dbQuery(
|
||||||
|
"SELECT id, activeDid, lastUpdated FROM active_identity WHERE id = 1",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result?.values?.length) {
|
||||||
|
const [id, activeDid, lastUpdated] = result.values[0];
|
||||||
|
return {
|
||||||
|
id: id as number,
|
||||||
|
activeDid: activeDid as string,
|
||||||
|
lastUpdated: lastUpdated as string,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return default if no record exists
|
||||||
|
return {
|
||||||
|
id: 1,
|
||||||
|
activeDid: "",
|
||||||
|
lastUpdated: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
"[PlatformServiceMixin] Error getting active identity:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction wrapper with automatic rollback on error
|
* Transaction wrapper with automatic rollback on error
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user