@ -1,87 +1,192 @@
# Active Identity Migration & Upgrade (Merged)
# Active Identity Upgrade Plan
## Part 1: Database Migration Impact Analysis
**Author**: Matthew Raymer
**Date**: 2025-09-11
**Status**: 🎯 **PLANNING** - Database migration and active identity system upgrade
# Database Migration Impact Analysis
## Overview
Comprehensive upgrade to the active identity system, addressing architectural issues and implementing enhanced database constraints. Includes database migration enhancements and settings table cleanup based on team feedback.
## Implementation Status
**✅ COMPLETED**: Migration structure updated according to team member feedback
### Implemented Changes
1. ** ✅ Migration 003**: `003_add_hasBackedUpSeed_to_settings` - Adds `hasBackedUpSeed` column to settings (assumes master deployment)
2. ** ✅ Migration 004**: `004_active_identity_and_seed_backup` - Creates `active_identity` table with data migration
3. ** ✅ Migration Service**: Updated validation and schema detection logic for new migration structure
4. ** ✅ TypeScript**: Fixed type compatibility issues
### Migration Structure Now Follows Team Guidance
- **Migration 003** : `003_add_hasBackedUpSeed_to_settings` (assumes master code deployed)
- **Migration 004** : `004_active_identity_and_seed_backup` (creates active_identity table)
- **All migrations are additional** - no editing of previous migrations
- **Data migration logic** preserves existing `activeDid` from settings
- **iOS/Android compatibility** confirmed with SQLCipher 4.9.0 (SQLite 3.44.2)
## Educational Context
### Why This Upgrade Matters
The active identity system is **critical infrastructure** affecting every user interaction:
1. **Data Integrity** : Current `ON DELETE SET NULL` allows accidental deletion of active accounts
2. **Manual Maintenance** : Timestamps require manual updates, creating inconsistency opportunities
3. **Architectural Clarity** : Separating active identity from user settings improves maintainability
### What This Upgrade Achieves
- **Prevents Data Loss** : `ON DELETE RESTRICT` prevents accidental account deletion
- **Automatic Consistency** : Database triggers ensure timestamps are always current
- **Cleaner Architecture** : Complete separation of identity management from user preferences
- **Better Performance** : Optimized indexes for faster account selection
## Current State Analysis
## Current State Analysis
### Existing Migration Structure
### Existing Migration Structure
The current migration system has:
- **Migration 003** : `003_active_identity_and_seed_backup` - Creates `active_identity` table with basic structure
- **Migration 003** : `003_add_hasBackedUpSeed_to_settings` - Adds `hasBackedUpSeed` column to settings (already deployed in master)
- **Migration 004** : `004_active_identity_and_seed_backup` - Creates `active_identity` table with data migration
- **Foreign Key** : `ON DELETE SET NULL` constraint
- **Foreign Key** : `ON DELETE SET NULL` constraint
- **Basic Indexing** : Single unique index on `id`
- **Data Migration** : Copies existing `activeDid` from settings to `active_identity` table
- **Bootstrapping** : Auto-selects first account if `activeDid` is null/empty
- **Bootstrapping** : Auto-selects first account if `activeDid` is null/empty
### Current Schema (Migration 003)
**Important**: All migrations are **additional** - no editing of previous migrations since master code has been deployed.
### Current Schema (Migration 004) - IMPLEMENTED
```sql
```sql
-- Migration 004: active_identity_and_seed_backup
-- Assumes master code deployed with migration 003
PRAGMA foreign_keys = ON;
CREATE UNIQUE INDEX IF NOT EXISTS idx_accounts_did_unique ON accounts(did);
CREATE TABLE IF NOT EXISTS active_identity (
CREATE TABLE IF NOT EXISTS active_identity (
id INTEGER PRIMARY KEY CHECK (id = 1),
id INTEGER PRIMARY KEY CHECK (id = 1),
activeDid TEXT DEFAULT NULL,
activeDid TEXT DEFAULT NULL,
lastUpdated TEXT NOT NULL DEFAULT (datetime('now')),
lastUpdated TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (activeDid) REFERENCES accounts(did) ON DELETE SET NULL
FOREIGN KEY (activeDid) REFERENCES accounts(did) ON DELETE SET NULL
);
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_identity_single_record ON active_identity(id);
-- Seed singleton row
INSERT INTO active_identity (id, activeDid, lastUpdated)
SELECT 1, NULL, datetime('now')
WHERE NOT EXISTS (SELECT 1 FROM active_identity WHERE id = 1);
-- MIGRATE EXISTING DATA: Copy activeDid from settings
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 != '');
```
## Current Implementation Details
### PlatformServiceMixin.ts Implementation
The current `$getActiveIdentity()` method in `src/utils/PlatformServiceMixin.ts` :
```typescript
async $getActiveIdentity(): Promise< { activeDid: string }> {
try {
const result = await this.$dbQuery("SELECT activeDid FROM active_identity WHERE id = 1");
if (!result?.values?.length) {
logger.warn("[PlatformServiceMixin] Active identity table is empty - migration issue");
return { activeDid: "" };
}
const activeDid = result.values[0][0] as string | null;
// Handle null activeDid - auto-select first account
if (activeDid === null) {
const firstAccount = await this.$dbQuery("SELECT did FROM accounts ORDER BY dateCreated, did LIMIT 1");
if (firstAccount?.values?.length) {
const firstAccountDid = firstAccount.values[0][0] as string;
await this.$dbExec("UPDATE active_identity SET activeDid = ?, lastUpdated = datetime('now') WHERE id = 1", [firstAccountDid]);
return { activeDid: firstAccountDid };
}
logger.warn("[PlatformServiceMixin] No accounts available for auto-selection");
return { activeDid: "" };
}
// Validate activeDid exists in accounts
const accountExists = await this.$dbQuery("SELECT did FROM accounts WHERE did = ?", [activeDid]);
if (accountExists?.values?.length) {
return { activeDid };
}
// Clear corrupted activeDid and return empty
logger.warn("[PlatformServiceMixin] Active identity not found in accounts, clearing");
await this.$dbExec("UPDATE active_identity SET activeDid = NULL, lastUpdated = datetime('now') WHERE id = 1");
return { activeDid: "" };
} catch (error) {
logger.error("[PlatformServiceMixin] Error getting active identity:", error);
return { activeDid: "" };
}
}
```
```
### Key Implementation Notes
1. **Null Handling** : Auto-selects first account when `activeDid` is null
2. **Corruption Detection** : Clears invalid `activeDid` values
3. **Manual Timestamps** : Updates `lastUpdated` manually in code
4. **Error Handling** : Returns empty string on any error with appropriate logging
## Proposed Changes Impact
## Proposed Changes Impact
### 1. Foreign Key Constraint Change
### 1. Foreign Key Constraint Change
**Current**: `ON DELETE SET NULL`
**Current**: `ON DELETE SET NULL` → **Proposed** : `ON DELETE RESTRICT`
**Proposed**: `ON DELETE RESTRICT`
**Impact**:
- **Data Safety** : Prevents accidental deletion of active account
- **Data Safety** : Prevents accidental deletion of active account
- **Migration Rewrite** : Update existing migration 003
- **New Migration** : Add migration 005 to update constraint
### 2. Automatic Timestamp Updates
### 2. Automatic Timestamp Updates
**Current**: Manual `lastUpdated` updates in code
**Current**: Manual `lastUpdated` updates → **Proposed** : Database trigger
**Proposed**: Database trigger for automatic updates
**Impact**:
- **Code Simplification** : Remove manual timestamp updates from `PlatformServiceMixin`
- **Code Simplification** : Remove manual timestamp updates from `PlatformServiceMixin`
- **Consistency** : Ensures `lastUpdated` is always current
- **Consistency** : Ensures `lastUpdated` is always current
### 3. Enhanced Indexing
### 3. Enhanced Indexing
**Current**: Single unique index on `id`
**Current**: Single unique index on `id` → **Proposed** : Additional index on `accounts(dateCreated, did)`
**Proposed**: Additional index on `accounts(dateCreated, did)`
**Impact**:
- **Performance Improvement** : Faster account selection queries
- **Performance Improvement** : Faster account selection queries
- **Minimal Risk** : Additive change only
- **Minimal Risk** : Additive change only
## Implementation Strategy
## Implementation Strategy
### Rewrite Migration 003
### Add Migration 005
Since the `active_identity` table is new and we're in active development, we can simply rewrite the existing migration:
Since the `active_identity` table already exists and is working, we can add a new migration to enhance it:
```sql
```sql
{
{
name: "003_active_identity_and_seed_backup",
name: "005_active_identity_enhancements ",
sql: `
sql: `
-- Enable foreign key constraints for data integrity
PRAGMA foreign_keys = ON;
PRAGMA foreign_keys = ON;
-- Add UNIQUE constraint to accounts.did for foreign key support
-- Recreate table with ON DELETE RESTRICT constraint
CREATE UNIQUE INDEX IF NOT EXISTS idx_accounts_did_unique ON accounts(did);
CREATE TABLE active_identity_new (
-- Create active_identity table with enhanced constraints
CREATE TABLE IF NOT EXISTS active_identity (
id INTEGER PRIMARY KEY CHECK (id = 1),
id INTEGER PRIMARY KEY CHECK (id = 1),
activeDid TEXT REFERENCES accounts(did) ON DELETE RESTRICT,
activeDid TEXT REFERENCES accounts(did) ON DELETE RESTRICT,
lastUpdated TEXT NOT NULL DEFAULT (datetime('now'))
lastUpdated TEXT NOT NULL DEFAULT (datetime('now'))
);
);
-- Copy existing data
INSERT INTO active_identity_new (id, activeDid, lastUpdated)
SELECT id, activeDid, lastUpdated FROM active_identity;
-- Replace old table
DROP TABLE active_identity;
ALTER TABLE active_identity_new RENAME TO active_identity;
-- Add performance indexes
-- Add performance indexes
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_identity_single_record ON active_identity(id);
CREATE INDEX IF NOT EXISTS idx_accounts_pick ON accounts(dateCreated, did);
CREATE INDEX IF NOT EXISTS idx_accounts_pick ON accounts(dateCreated, did);
-- Seed singleton row (only if not already exists)
INSERT INTO active_identity (id, activeDid, lastUpdated)
SELECT 1, NULL, datetime('now')
WHERE NOT EXISTS (SELECT 1 FROM active_identity WHERE id = 1);
-- Add hasBackedUpSeed field to settings
ALTER TABLE settings ADD COLUMN hasBackedUpSeed BOOLEAN DEFAULT FALSE;
-- Create automatic timestamp trigger
-- Create automatic timestamp trigger
CREATE TRIGGER IF NOT EXISTS trg_active_identity_touch
CREATE TRIGGER IF NOT EXISTS trg_active_identity_touch
@ -96,46 +201,59 @@ Since the `active_identity` table is new and we're in active development, we can
}
}
```
```
## Migration Service Updates Required
## Migration Service Updates Required
### Enhanced Validation Logic
### Enhanced Validation Logic
**File**: `src/services/migrationService.ts`
**File**: `src/services/migrationService.ts`
The existing validation for migration 003 needs to be enhanced to check for:
**Migration 004 validation**:
- **Table existence** : `SELECT name FROM sqlite_master WHERE type='table' AND name='active_identity'`
- **Column structure** : `SELECT id, activeDid, lastUpdated FROM active_identity LIMIT 1`
- **Schema detection** : Uses `isSchemaAlreadyPresent()` to check if migration was already applied
**Migration 005 validation**:
- **Trigger existence** : `trg_active_identity_touch`
- **Trigger existence** : `trg_active_identity_touch`
- **Performance index** : `idx_accounts_pick`
- **Performance index** : `idx_accounts_pick`
- **Foreign key constraint** : `ON DELETE RESTRICT`
- **Foreign key constraint** : `ON DELETE RESTRICT`
- **Table recreation** : Verify table was successfully recreated
### Enhanced Schema Detection
### Enhanced Schema Detection
**File**: `src/services/migrationService.ts`
The existing schema detection for migration 003 needs to be enhanced to verify:
**Migration 004 verification**:
- **Table structure** : Enhanced constraints
- **Table structure** : Checks `active_identity` table exists and has correct columns
- **Data integrity** : Validates that the table can be queried successfully
- **Migration tracking** : Uses `isSchemaAlreadyPresent()` to avoid re-applying migrations
**Migration 005 verification**:
- **Table structure** : Enhanced constraints with `ON DELETE RESTRICT`
- **Trigger presence** : Automatic timestamp updates
- **Trigger presence** : Automatic timestamp updates
- **Index presence** : Performance optimization
- **Index presence** : Performance optimization
- **Data integrity** : Existing data was preserved during table recreation
## Risk Assessment
## Risk Assessment
### Low Risk Changes
### Low Risk Changes
- **Performance Index** : Additive only, no data changes
- **Performance Index** : Additive only, no data changes
- **Trigger Creation** : Additive only, improves consistency
- **Trigger Creation** : Additive only, improves consistency
- **Migration Rewrite** : Clean implementation, no additional migrations
- **New Migration** : Clean implementation, no modification of existing migrations
### Medium Risk Changes
### Medium Risk Changes
- **Foreign Key Change** : `ON DELETE RESTRICT` is more restrictive
- **Foreign Key Change** : `ON DELETE RESTRICT` is more restrictive
- **Table Recreation** : Requires careful data preservation
- **Validation Updates** : Need to test enhanced validation logic
- **Validation Updates** : Need to test enhanced validation logic
### Mitigation Strategies
### Mitigation Strategies
1. **Comprehensive Testing** : Test migration on various database states
1. **Comprehensive Testing** : Test migration on various database states
2. **Development Phase** : Since we're in active development, risk is minimal
2. **Data Preservation** : Verify existing data is copied correctly
3. **Clean Implementation** : Single migration with all enhancements
3. **Clean Implementation** : New migration with all enhancements
4. **Validation Coverage** : Enhanced validation ensures correctness
4. **Validation Coverage** : Enhanced validation ensures correctness
5. **Rollback Plan** : Can drop new table and restore original if needed
## Implementation Timeline
## Implementation Timeline
### Phase 1: Migration Rewrite
### Phase 1: Migration Enhancement
- [ ] Update migration 003 with enhanced constraints
- [ ] Add migration 005 with enhanced constraints
- [ ] Add enhanced validation logic
- [ ] Add enhanced validation logic
- [ ] Add enhanced schema detection logic
- [ ] Add enhanced schema detection logic
- [ ] Test migration on clean database
- [ ] Test migration on clean database
@ -145,6 +263,7 @@ The existing schema detection for migration 003 needs to be enhanced to verify:
- [ ] Validate foreign key constraints work correctly
- [ ] Validate foreign key constraints work correctly
- [ ] Test trigger functionality
- [ ] Test trigger functionality
- [ ] Test performance improvements
- [ ] Test performance improvements
- [ ] Verify data preservation during table recreation
### Phase 3: Deployment
### Phase 3: Deployment
- [ ] Deploy enhanced migration to development
- [ ] Deploy enhanced migration to development
@ -152,359 +271,120 @@ The existing schema detection for migration 003 needs to be enhanced to verify:
- [ ] Deploy to production
- [ ] Deploy to production
- [ ] Monitor for any issues
- [ ] Monitor for any issues
## Code Changes Required
### Phase 4: Settings Table Cleanup
- [ ] Create migration 006 to clean up settings table
### Files to Modify
- [ ] Remove orphaned settings records (accountDid is null)
1. ** `src/db-sql/migration.ts` ** - Update migration 003 with enhanced constraints
- [ ] Clear any remaining activeDid values in settings
2. ** `src/services/migrationService.ts` ** - Add enhanced validation and detection logic
- [ ] Consider removing activeDid column entirely (future task)
3. ** `src/utils/PlatformServiceMixin.ts` ** - Remove manual timestamp updates
### Estimated Impact
- **Migration File** : ~20 lines modified (enhanced constraints)
- **Migration Service** : ~50 lines added (enhanced validation)
- **PlatformServiceMixin** : ~20 lines removed (manual timestamps)
- **Total** : ~50 lines changed
## Conclusion
The proposed database changes are **feasible and beneficial** with a much simpler implementation:
**Benefits**:
## Settings Table Cleanup Strategy
- Improved data integrity with `ON DELETE RESTRICT`
- Automatic timestamp consistency
- Better query performance
- Cleaner code (no manual timestamp updates)
- **Simpler implementation** - just rewrite migration 003
**Risks**:
### Current State Analysis
- More restrictive foreign key constraints
The settings table currently contains:
- Enhanced validation logic needs testing
- **Legacy activeDid column** : Still present from original design
- **Orphaned records** : Settings with `accountDid = null` that may be obsolete
- **Redundant data** : Some settings may have been copied unnecessarily
**Recommendation**: Proceed with **rewriting migration 003** as it provides the cleanest path forward with minimal complexity and maximum benefit.
Based on team feedback, the cleanup should include:
1. **Remove orphaned settings records** :
```sql
DELETE FROM settings WHERE accountDid IS NULL;
```
---
2. **Clear any remaining activeDid values** :
```sql
## Part 2: Active Identity System Upgrade Plan
UPDATE settings SET activeDid = NULL;
```
# Active Identity System Upgrade Plan
## Overview
This document outlines a comprehensive upgrade to the `$getActiveIdentity` system
to address current ambiguities, race conditions, and improve overall robustness.
## Current Issues Identified
### 1. **Ambiguous Return States**
- Current: Returns `{ activeDid: string }` where empty string conflates multiple states
- Problem: Cannot distinguish between "no accounts", "migration gap", "corruption cleared"
- Impact: UI cannot provide appropriate user guidance
### 2. **Race Conditions (TOCTOU)**
- Current: Read → Write → Re-read across multiple statements
3. **Future consideration** : Remove the activeDid column entirely from settings table
- Problem: No transactional guard, potential for inconsistent state
- Impact: Rare but possible data corruption scenarios
### 3. **No Single-Row Enforcement**
### Migration 006: Settings Cleanup
- Current: App logic assumes `id=1` singleton, but DB doesn't enforce
- Problem: Multiple rows could theoretically exist
- Impact: Unpredictable behavior
### 4. **Deletion Hazards**
- Current: No protection against deleting active account
- Problem: App "discovers" corruption after the fact
- Impact: Poor user experience, potential data loss
### 5. **Inconsistent Updates**
- Current: `lastUpdated` only set on some code paths
- Problem: Audit trail incomplete
- Impact: Debugging difficulties
## Proposed Solution Architecture
### Database Schema Changes
```sql
```sql
-- Enhanced active_identity table with constraints
{
CREATE TABLE IF NOT EXISTS active_identity (
name: "006_settings_cleanup",
id INTEGER PRIMARY KEY CHECK (id = 1),
sql: `
activeDid TEXT REFERENCES accounts(did) ON DELETE RESTRICT,
-- Remove orphaned settings records (accountDid is null)
lastUpdated TEXT NOT NULL DEFAULT (datetime('now'))
DELETE FROM settings WHERE accountDid IS NULL;
);
-- Clear any remaining activeDid values in settings
-- Automatic timestamp updates
UPDATE settings SET activeDid = NULL;
CREATE TRIGGER IF NOT EXISTS trg_active_identity_touch
AFTER UPDATE ON active_identity
-- Optional: Consider removing the activeDid column entirely
FOR EACH ROW
-- ALTER TABLE settings DROP COLUMN activeDid;
BEGIN
`
UPDATE active_identity
}
SET lastUpdated = datetime('now')
WHERE id = 1;
END;
-- Deterministic account selection index
CREATE INDEX IF NOT EXISTS idx_accounts_pick
ON accounts(dateCreated, did);
-- Seed singleton row
INSERT INTO active_identity (id, activeDid)
SELECT 1, NULL
WHERE NOT EXISTS (SELECT 1 FROM active_identity WHERE id = 1);
```
### Type System Enhancement
```typescript
type ActiveIdentity =
| { state: 'ok'; activeDid: string }
| { state: 'unset'; activeDid: '' } // row exists, but no active set yet
| { state: 'auto-selected'; activeDid: string } // we selected & saved first account
| { state: 'empty-accounts'; activeDid: '' } // there are no accounts to select
| { state: 'cleared-corrupt'; activeDid: '' } // DB had a non-existent DID; cleared
| { state: 'error'; activeDid: '' };
```
```
## Migration Strategy
### Benefits of Settings Cleanup
- **Reduced confusion** : Eliminates dual-purpose columns
### Phase 1: Database Schema Migration
- **Cleaner architecture** : Settings table focuses only on user preferences
- **Reduced storage** : Removes unnecessary data
**Files to modify:**
- **Clearer separation** : Active identity vs. user settings are distinct concerns
- `src/db-sql/migration.ts` - Add new migration
- `src/services/migrationService.ts` - Update validation logic
**Migration Steps:**
1. Add foreign key constraint to `active_identity.activeDid`
2. Add `ON DELETE RESTRICT` constraint
3. Create timestamp trigger
4. Add deterministic index
5. Ensure singleton row exists
**Risk Assessment:** LOW
- Additive changes only
- Existing data preserved
- Rollback possible
### Phase 2: Core Method Refactor
**Files to modify:**
- `src/utils/PlatformServiceMixin.ts` - Replace `$getActiveIdentity`
- `src/interfaces/` - Add new type definitions
**Changes:**
1. Implement transactional `$getActiveIdentity` with explicit states
2. Add `$setActiveIdentity` method
3. Add `$deleteAccountSafely` method
4. Update return type to `ActiveIdentity`
**Risk Assessment:** MEDIUM
- Breaking change to return type
- Requires coordinated updates across codebase
- Extensive testing needed
### Phase 3: Consumer Updates
**Files to modify:**
- All Vue components using `$getActiveIdentity`
- Router guards
- Service layer components
**Changes:**
1. Update all callers to handle new return type
2. Implement state-specific UI logic
3. Add appropriate user messaging
**Risk Assessment:** HIGH
- Wide impact across codebase
- UI/UX changes required
- Extensive testing needed
## Implementation Phases
### Phase 1: Database Foundation
- [ ] Create migration for schema changes
- [ ] Test migration on development databases
- [ ] Validate foreign key constraints work correctly
- [ ] Test rollback scenarios
### Phase 2: Core Implementation
- [ ] Implement new `$getActiveIdentity` method
### Risk Assessment: LOW
- [ ] Add `$setActiveIdentity` method
- **Data safety** : Only removes orphaned/obsolete records
- [ ] Add `$deleteAccountSafely` method
- **Backward compatibility** : Maintains existing column structure
- [ ] Create comprehensive unit tests
- **Rollback** : Easy to restore if needed
- [ ] Test transactional behavior
- **Testing** : Can be validated with existing data
### Phase 3: Consumer Updates
## Code Changes Required
- [ ] Audit all current usage of `$getActiveIdentity`
- [ ] Create migration guide for components
- [ ] Update critical path components first
- [ ] Implement state-specific UI logic
### Phase 4: Testing & Rollout
- [ ] End-to-end testing
- [ ] Performance testing
- [ ] User acceptance testing
- [ ] Gradual rollout with feature flags
## Backward Compatibility Strategy
### Gradual Migration Approach
The gradual migration strategy allows us to implement the new active identity system without breaking existing functionality. This approach minimizes risk and provides a clear path for incremental updates.
#### Phase 1: Dual Method Implementation
- **Keep existing method** : Leave current `$getActiveIdentity` unchanged (no renaming)
- **Add new method** : Implement `$getActiveIdentityV2` with new return type and logic
- **Feature flag control** : Use `FEATURE_FLAG_ACTIVE_IDENTITY_V2` to control which method is used
- **Default to existing** : Start with existing method enabled to ensure no breaking changes
#### Phase 2: Component Migration
- **Audit usage** : Identify all components using `$getActiveIdentity`
- **Create migration guide** : Document the changes needed for each component type
- **Update incrementally** : Migrate components to use `$getActiveIdentityV2` one
by one, starting with non-critical paths
- **Test each migration** : Validate each component works with the new method
before proceeding
#### Phase 3: Feature Flag Rollout
- **Enable for migrated components** : Switch feature flag for components that have been updated
- **Monitor performance** : Track any performance or behavior changes
- **Gradual enablement** : Enable the new method for more components as they're migrated
- **Fallback capability** : Keep legacy method available for rollback if issues arise
#### Phase 4: Legacy Cleanup
- **Remove feature flag** : Once all components are migrated, remove the feature flag
- **Replace existing method** : Replace the implementation of `$getActiveIdentity` with the V2 logic
- **Remove V2 method** : Delete `$getActiveIdentityV2` and related code
- **Update documentation** : Remove references to the V2 method
- **Final validation** : Ensure no remaining references to V2 method
#### Benefits of This Approach
- **Zero downtime** : No breaking changes during migration
- **Incremental testing** : Each component can be tested individually
- **Easy rollback** : Can revert individual components or entire system if needed
- **Clear progress tracking** : Easy to see which components still need migration
- **Reduced risk** : Issues are isolated to individual components rather than system-wide
## Risk Mitigation
### Database Risks
- **Foreign Key Violations** : Test with existing data
- **Migration Failures** : Comprehensive rollback plan
- **Performance Impact** : Monitor query performance
### Code Risks
- **Breaking Changes** : Extensive testing, gradual rollout
- **Race Conditions** : Comprehensive unit tests
- **State Management** : Clear documentation, examples
### User Experience Risks
- **Confusing States** : Clear UI messaging
- **Data Loss** : Backup strategies, validation
- **Performance** : Monitor response times
## Success Metrics
### Technical Metrics
- Zero race condition incidents
- 100% test coverage for new methods
- < 50ms average response time
- Zero data corruption incidents
### User Experience Metrics
- Clear state-specific messaging
- Reduced user confusion
- Improved onboarding flow
- Faster account switching
## Rollback Plan
### Database Rollback
1. Remove foreign key constraints
2. Remove triggers
3. Remove indexes
4. Restore previous migration state
### Code Rollback
1. Revert to previous `$getActiveIdentity` implementation
### Files to Modify
2. Remove new type definitions
1. ** `src/db-sql/migration.ts` ** - Add migration 005 with enhanced constraints
3. Restore previous component logic
2. ** `src/db-sql/migration.ts` ** - Add migration 006 for settings cleanup
4. Remove new methods
3. ** `src/services/migrationService.ts` ** - Add enhanced validation and detection logic
4. ** `src/utils/PlatformServiceMixin.ts` ** - Remove manual timestamp updates
## Testing Strategy
### Estimated Impact
- **Migration File** : ~25 lines added (migration 005) + ~15 lines added (migration 006)
- **Migration Service** : ~50 lines added (enhanced validation)
- **PlatformServiceMixin** : ~20 lines removed (manual timestamps)
- **Total** : ~90 lines changed
### Unit Tests
## Conclusion
- Test all state transitions
**✅ IMPLEMENTATION COMPLETE**: The active identity upgrade plan has been successfully applied to the current project.
- Test transactional behavior
- Test error conditions
- Test edge cases
### Integration Tests
### Successfully Implemented
- Test with real database
**✅ Migration Structure Updated**:
- Test migration scenarios
- **Migration 003** : `003_add_hasBackedUpSeed_to_settings` (assumes master deployment)
- Test concurrent access
- **Migration 004** : `004_active_identity_and_seed_backup` (creates active_identity table)
- Test foreign key constraints
- **All migrations are additional** - follows team member feedback exactly
### End-to-End Tests
**✅ Technical Implementation**:
- **Data Migration** : Preserves existing `activeDid` from settings table
- **Foreign Key Constraints** : `ON DELETE SET NULL` for data safety
- **iOS/Android Compatibility** : Confirmed with SQLCipher 4.9.0 (SQLite 3.44.2)
- **Migration Service** : Updated validation and schema detection logic
- Test complete user flows
**✅ Code Quality**:
- Test account creation/deletion
- **TypeScript** : All type errors resolved
- Test active identity switching
- **Linting** : No linting errors
- Test error recovery
- **Team Guidance** : Follows "additional migrations only" requirement
## Documentation Requirements
### Next Steps (Future Enhancements)
### Developer Documentation
The foundation is now in place for future enhancements:
- Migration guide for components
1. **Migration 005** : `005_active_identity_enhancements` (ON DELETE RESTRICT, triggers, indexes)
- API documentation for new methods
2. **Migration 006** : `006_settings_cleanup` (remove orphaned settings, clear legacy activeDid)
- Type definitions and examples
3. **Code Simplification** : Remove manual timestamp updates from PlatformServiceMixin
- Best practices guide
### User Documentation
### Current Status
- State-specific UI messaging
**Migration 004 is ready for deployment** and will:
- Error message guidelines
- ✅ Create `active_identity` table with proper constraints
- Onboarding flow updates
- ✅ Migrate existing `activeDid` data from settings
- Troubleshooting guide
- ✅ Work identically on iOS and Android
- ✅ Follow team member feedback for additional migrations only
## Conclusion
**Key Point**: All migrations are **additional** - no editing of previous migrations since master code has been deployed. This ensures compatibility and proper testing.
This upgrade addresses critical architectural issues while providing a clear path
---
forward. The phased approach minimizes risk while ensuring thorough testing and
validation at each step.
**Recommendation:** Proceed with Phase 1 (Database Schema) immediately, as it
**Status**: Ready for team review and implementation approval
provides immediate benefits with minimal risk. The gradual migration approach allows
**Last Updated**: 2025-09-11
for incremental updates without breaking existing functionality.
**Next Review**: After team feedback and approval