Reboot of the ActiveDID migration #188

Open
anomalist wants to merge 0 commits from active_did_redux into master
Owner
No description provided.
anomalist added 2 commits 2025-08-27 12:35:26 +00:00
Author
Owner

ActiveDid Migration Plan - Separate Table Architecture

Author: Matthew Raymer
Date: 2025-01-27T18:30Z
Status: 🎯 PLANNING - Active migration planning phase

Objective

Move the activeDid field from the settings table to a dedicated
active_identity table to improve database architecture and separate
identity selection from user preferences.

Result

This document serves as the comprehensive planning and implementation
guide for the ActiveDid migration.

Use/Run

Reference this document during implementation to ensure all migration
steps are followed correctly and all stakeholders are aligned on the
approach.

Context & Scope

  • In scope:
    • Database schema modification for active_identity table
    • Migration of existing activeDid data
    • Updates to all platform services and mixins
    • Type definition updates
    • Testing across all platforms
  • Out of scope:
    • Changes to user interface for identity selection
    • Modifications to identity creation logic
    • Changes to authentication flow

Environment & Preconditions

  • OS/Runtime: All platforms (Web, Electron, iOS, Android)
  • Versions/Builds: Current development branch, SQLite database
  • Services/Endpoints: Local database, PlatformServiceMixin
  • Auth mode: Existing authentication system unchanged

Architecture / Process Overview

The migration follows a phased approach to minimize risk and ensure
data integrity:

flowchart TD
    A[Current State<br/>activeDid in settings] --> B[Phase 1: Schema Creation<br/>Add active_identity table]
    B --> C[Phase 2: Data Migration<br/>Copy activeDid data]
    C --> D[Phase 3: API Updates<br/>Update all access methods]
    D --> E[Phase 4: Cleanup<br/>Remove activeDid from settings]
    E --> F[Final State<br/>Separate active_identity table]

    G[Rollback Plan<br/>Keep old field until verified] --> H[Data Validation<br/>Verify integrity at each step]
    H --> I[Platform Testing<br/>Test all platforms]
    I --> J[Production Deployment<br/>Gradual rollout]

Interfaces & Contracts

Database Schema Changes

Table Current Schema New Schema Migration Required
settings activeDid TEXT Field removed Yes - data migration
active_identity Does not exist New table with activeDid TEXT Yes - table creation

API Contract Changes

Method Current Behavior New Behavior Breaking Change
$accountSettings() Returns settings with activeDid Returns settings without activeDid No - backward compatible
$saveSettings() Updates settings.activeDid Updates active_identity.activeDid Yes - requires updates
$updateActiveDid() Updates internal tracking Updates active_identity table Yes - requires updates

Repro: End-to-End Procedure

Phase 1: Schema Creation

-- Create new active_identity table
CREATE TABLE active_identity (
  id INTEGER PRIMARY KEY CHECK (id = 1),
  activeDid TEXT NOT NULL,
  lastUpdated TEXT NOT NULL DEFAULT (datetime('now'))
);

-- Insert default record (will be updated during migration)
INSERT INTO active_identity (id, activeDid) VALUES (1, '');

Phase 2: Data Migration

// Migration script to copy existing activeDid values
async function migrateActiveDidToSeparateTable(): Promise<void> {
  // Get current activeDid from settings
  const currentSettings = await retrieveSettingsForDefaultAccount();
  const activeDid = currentSettings.activeDid;

  if (activeDid) {
    // Insert into new table
    await dbExec(
      "UPDATE active_identity SET activeDid = ?, lastUpdated = datetime('now') WHERE id = 1",
      [activeDid]
    );
  }
}

Phase 3: API Updates

// Updated PlatformServiceMixin method
async $accountSettings(did?: string, defaults: Settings = {}): Promise<Settings> {
  // Get settings without activeDid
  const settings = await this._getSettingsWithoutActiveDid();

  // Get activeDid from separate table
  const activeIdentity = await this._getActiveIdentity();

  return { ...settings, activeDid: activeIdentity.activeDid };
}

What Works (Evidence)

  • Current activeDid storage in settings table

    • Time: 2025-01-27T18:30Z
    • Evidence: src/db/tables/settings.ts:25 - activeDid field exists
    • Verify at: Current database schema and Settings type definition
  • PlatformServiceMixin integration with activeDid

    • Time: 2025-01-27T18:30Z
    • Evidence: src/utils/PlatformServiceMixin.ts:108 - activeDid tracking
    • Verify at: Component usage across all platforms
  • Database migration infrastructure exists

    • Time: 2025-01-27T18:30Z
    • Evidence: src/db-sql/migration.ts:31 - migration system in place
    • Verify at: Existing migration scripts and database versioning

What Doesn't (Evidence & Hypotheses)

  • No separate active_identity table exists

    • Time: 2025-01-27T18:30Z
    • Evidence: Database schema only shows settings table
    • Hypothesis: Table needs to be created as part of migration
    • Next probe: Create migration script for new table
  • Platform services hardcoded to settings table

    • Time: 2025-01-27T18:30Z
    • Evidence: src/services/platforms/*.ts - direct settings table access
    • Hypothesis: All platform services need updates
    • Next probe: Audit all platform service files for activeDid usage

Risks, Limits, Assumptions

  • Data Loss Risk: Migration failure could lose activeDid values
  • Breaking Changes: API updates required across all platform services
  • Rollback Complexity: Schema changes make rollback difficult
  • Testing Overhead: All platforms must be tested with new structure
  • Performance Impact: Additional table join for activeDid retrieval
  • Migration Timing: Must be coordinated with other database changes

Next Steps

Owner Task Exit Criteria Target Date (UTC)
Development Team Create migration script Migration script tested and validated 2025-01-28
Development Team Update type definitions Settings type updated, ActiveIdentity type created 2025-01-28
Development Team Update platform services All services use new active_identity table 2025-01-29
Development Team Update PlatformServiceMixin Mixin methods updated and tested 2025-01-29
QA Team Platform testing All platforms tested and verified 2025-01-30
Development Team Deploy migration Production deployment successful 2025-01-31

References

Competence Hooks

  • Why this works: Separates concerns between identity selection and
    user preferences, improves database normalization, enables future
    identity management features
  • Common pitfalls: Forgetting to update all platform services, not
    testing rollback scenarios, missing data validation during migration
  • Next skill unlock: Advanced database schema design and migration
    planning
  • Teach-back: Explain the four-phase migration approach and why each
    phase is necessary

Collaboration Hooks

  • Sign-off checklist:
    • Migration script tested on development database
    • All platform services updated and tested
    • Rollback plan validated
    • Performance impact assessed
    • All stakeholders approve deployment timeline

Assumptions & Limits

  • Current activeDid values are valid and should be preserved
  • All platforms can handle the additional database table
  • Migration can be completed without user downtime
  • Rollback to previous schema is acceptable if needed
  • Performance impact of additional table join is minimal

Component & View Impact Analysis

High Impact Components

  1. IdentitySection.vue - Direct dependency on activeDid

    • Current: Uses activeDid from component data
    • Impact: Will need to update data binding and refresh logic
    • Risk: HIGH - Core identity display component

    Current Implementation:

    <template>
      <div class="text-sm text-slate-500">
        <div class="font-bold">ID:&nbsp;</div>
        <code class="truncate">{{ activeDid }}</code>
        <!-- ... rest of template -->
      </div>
    </template>
    
    <script lang="ts">
    export default class IdentitySection extends Vue {
      activeDid = ""; // Direct component data
    
      async mounted() {
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
      }
    }
    </script>
    

    Required Changes:

    <script lang="ts">
    export default class IdentitySection extends Vue {
      activeDid = ""; // Still needed for template binding
    
      async mounted() {
        // This will automatically work if $accountSettings() is updated
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
      }
    
      // Add watcher for activeDid changes
      async onActiveDidChanged(newDid: string | null) {
        if (newDid) {
          this.activeDid = newDid;
        }
      }
    }
    </script>
    
  2. DIDView.vue - Heavy activeDid usage

    • Current: Initializes activeDid in mounted() lifecycle
    • Impact: Must update initialization logic to use new table
    • Risk: HIGH - Primary DID viewing component

    Current Implementation:

    <script lang="ts">
    export default class DIDView extends Vue {
      activeDid = ""; // Component data
    
      async mounted() {
        await this.initializeSettings();
        await this.determineDIDToDisplay();
        // ... rest of initialization
      }
    
      private async initializeSettings() {
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
        this.apiServer = settings.apiServer || "";
      }
    
      private async determineDIDToDisplay() {
        const pathParam = window.location.pathname.substring("/did/".length);
        let showDid = pathParam;
    
        if (!showDid) {
          // No DID provided in URL, use active DID
          showDid = this.activeDid; // Uses component data
          this.notifyDefaultToActiveDID();
        }
        // ... rest of logic
      }
    }
    </script>
    

    Required Changes:

    <script lang="ts">
    export default class DIDView extends Vue {
      activeDid = ""; // Component data still needed
    
      async mounted() {
        await this.initializeSettings();
        await this.determineDIDToDisplay();
        // ... rest of initialization
      }
    
      private async initializeSettings() {
        // This will automatically work if $accountSettings() is updated
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
        this.apiServer = settings.apiServer || "";
      }
    
      // Add watcher for activeDid changes
      async onActiveDidChanged(newDid: string | null) {
        if (newDid && newDid !== this.activeDid) {
          this.activeDid = newDid;
          // Re-initialize if needed
          await this.determineDIDToDisplay();
        }
      }
    }
    </script>
    
  3. HomeView.vue - ActiveDid change detection

    • Current: Has onActiveDidChanged() watcher method
    • Impact: Watcher logic needs updates for new data source
    • Risk: MEDIUM - Core navigation component

    Current Implementation:

    <script lang="ts">
    export default class HomeView extends Vue {
      async onActiveDidChanged(newDid: string | null, oldDid: string | null) {
        if (newDid !== oldDid) {
          // Re-initialize identity with new settings (loads settings internally)
          await this.initializeIdentity();
        } else {
          logger.debug(
            "[HomeView Settings Trace] 📍 DID unchanged, skipping re-initialization",
          );
        }
      }
    
      private async initializeIdentity() {
        // ... identity initialization logic
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
        // ... rest of initialization
      }
    }
    </script>
    

    Required Changes:

    <script lang="ts">
    export default class HomeView extends Vue {
      async onActiveDidChanged(newDid: string | null, oldDid: string | null) {
        if (newDid !== oldDid) {
          // This will automatically work if $accountSettings() is updated
          await this.initializeIdentity();
        } else {
          logger.debug(
            "[HomeView Settings Trace] 📍 DID unchanged, skipping re-initialization",
          );
        }
      }
    
      private async initializeIdentity() {
        // ... identity initialization logic
        // This will automatically work if $accountSettings() is updated
        const settings = await this.$accountSettings();
        this.activeDid = settings.activeDid || "";
        // ... rest of initialization
      }
    }
    </script>
    

    Key Insight: HomeView will require minimal changes since it already uses
    the $accountSettings() method, which will be updated to handle the new
    table structure transparently.

Medium Impact Components

  1. InviteOneAcceptView.vue - Identity fallback logic

    • Current: Creates identity if no activeDid exists
    • Impact: Fallback logic needs to check new table
    • Risk: MEDIUM - Invite processing component
  2. ClaimView.vue - Settings retrieval

    • Current: Gets activeDid from $accountSettings()
    • Impact: Will automatically work if API is updated
    • Risk: LOW - Depends on API layer updates
  3. ContactAmountsView.vue - Direct settings access

    • Current: Accesses activeDid directly from settings
    • Impact: Must update to use new API methods
    • Risk: MEDIUM - Financial display component

Service Layer Impact

  1. WebPlatformService.ts

    • Current: Direct SQL queries to settings table
    • Impact: Must add active_identity table queries
    • Risk: HIGH - Core web platform service
  2. CapacitorPlatformService.ts

    • Current: Similar direct SQL access
    • Impact: Same updates as web service
    • Risk: HIGH - Mobile platform service
  3. PlatformServiceMixin.ts

    • Current: Core methods like $accountSettings(), $saveSettings()
    • Impact: Major refactoring required
    • Risk: CRITICAL - Used by 50+ components

API Contract Changes

  1. $saveSettings() method

    • Current: Updates settings.activeDid
    • New: Updates active_identity.activeDid
    • Impact: All components using this method
  2. $updateActiveDid() method

    • Current: Internal tracking only
    • New: Database persistence required
    • Impact: Identity switching logic

Testing Impact

  1. Unit Tests

    • All platform service methods
    • PlatformServiceMixin methods
    • Database migration scripts
  2. Integration Tests

    • Component behavior with new data source
    • Identity switching workflows
    • Settings persistence
  3. Platform Tests

    • Web, Electron, iOS, Android
    • Cross-platform data consistency
    • Migration success on all platforms

Performance Impact

  1. Additional Table Join

    • Settings queries now require active_identity table
    • Potential performance impact on frequent operations
    • Need for proper indexing
  2. Caching Considerations

    • ActiveDid changes trigger cache invalidation
    • Component re-rendering on identity switches
    • Memory usage for additional table data

Risk Assessment by Component Type

  • Critical Risk: PlatformServiceMixin, Platform Services
  • High Risk: Identity-related components, views using $accountSettings()
  • Medium Risk: Components with direct settings access, identity management
  • Low Risk: Components using only basic settings, utility components

Migration Timeline Impact

  • Phase 1: Schema Creation (1-2 days) - No component impact
  • Phase 2: Data Migration (1 day) - No component impact
  • Phase 3: API Updates (3-5 days) - All components affected
  • Phase 4: Cleanup (1-2 days) - No component impact

Update Priority Order

  1. PlatformServiceMixin - Core dependency for most components
  2. Platform Services - Ensure data access layer works
  3. Identity Components - Verify core functionality
  4. Settings-Dependent Views - Update in dependency order
  5. Utility Components - Final cleanup and testing

Deferred for depth

  • Advanced identity management features enabled by this change
  • Performance optimization strategies for the new table structure
  • Future schema evolution planning
  • Advanced rollback and recovery procedures
# ActiveDid Migration Plan - Separate Table Architecture **Author**: Matthew Raymer **Date**: 2025-01-27T18:30Z **Status**: 🎯 **PLANNING** - Active migration planning phase ## Objective Move the `activeDid` field from the `settings` table to a dedicated `active_identity` table to improve database architecture and separate identity selection from user preferences. ## Result This document serves as the comprehensive planning and implementation guide for the ActiveDid migration. ## Use/Run Reference this document during implementation to ensure all migration steps are followed correctly and all stakeholders are aligned on the approach. ## Context & Scope - **In scope**: - Database schema modification for active_identity table - Migration of existing activeDid data - Updates to all platform services and mixins - Type definition updates - Testing across all platforms - **Out of scope**: - Changes to user interface for identity selection - Modifications to identity creation logic - Changes to authentication flow ## Environment & Preconditions - **OS/Runtime**: All platforms (Web, Electron, iOS, Android) - **Versions/Builds**: Current development branch, SQLite database - **Services/Endpoints**: Local database, PlatformServiceMixin - **Auth mode**: Existing authentication system unchanged ## Architecture / Process Overview The migration follows a phased approach to minimize risk and ensure data integrity: ```mermaid flowchart TD A[Current State<br/>activeDid in settings] --> B[Phase 1: Schema Creation<br/>Add active_identity table] B --> C[Phase 2: Data Migration<br/>Copy activeDid data] C --> D[Phase 3: API Updates<br/>Update all access methods] D --> E[Phase 4: Cleanup<br/>Remove activeDid from settings] E --> F[Final State<br/>Separate active_identity table] G[Rollback Plan<br/>Keep old field until verified] --> H[Data Validation<br/>Verify integrity at each step] H --> I[Platform Testing<br/>Test all platforms] I --> J[Production Deployment<br/>Gradual rollout] ``` ## Interfaces & Contracts ### Database Schema Changes | Table | Current Schema | New Schema | Migration Required | |-------|----------------|------------|-------------------| | `settings` | `activeDid TEXT` | Field removed | Yes - data migration | | `active_identity` | Does not exist | New table with `activeDid TEXT` | Yes - table creation | ### API Contract Changes | Method | Current Behavior | New Behavior | Breaking Change | |---------|------------------|--------------|-----------------| | `$accountSettings()` | Returns settings with activeDid | Returns settings without activeDid | No - backward compatible | | `$saveSettings()` | Updates settings.activeDid | Updates active_identity.activeDid | Yes - requires updates | | `$updateActiveDid()` | Updates internal tracking | Updates active_identity table | Yes - requires updates | ## Repro: End-to-End Procedure ### Phase 1: Schema Creation ```sql -- Create new active_identity table CREATE TABLE active_identity ( id INTEGER PRIMARY KEY CHECK (id = 1), activeDid TEXT NOT NULL, lastUpdated TEXT NOT NULL DEFAULT (datetime('now')) ); -- Insert default record (will be updated during migration) INSERT INTO active_identity (id, activeDid) VALUES (1, ''); ``` ### Phase 2: Data Migration ```typescript // Migration script to copy existing activeDid values async function migrateActiveDidToSeparateTable(): Promise<void> { // Get current activeDid from settings const currentSettings = await retrieveSettingsForDefaultAccount(); const activeDid = currentSettings.activeDid; if (activeDid) { // Insert into new table await dbExec( "UPDATE active_identity SET activeDid = ?, lastUpdated = datetime('now') WHERE id = 1", [activeDid] ); } } ``` ### Phase 3: API Updates ```typescript // Updated PlatformServiceMixin method async $accountSettings(did?: string, defaults: Settings = {}): Promise<Settings> { // Get settings without activeDid const settings = await this._getSettingsWithoutActiveDid(); // Get activeDid from separate table const activeIdentity = await this._getActiveIdentity(); return { ...settings, activeDid: activeIdentity.activeDid }; } ``` ## What Works (Evidence) - ✅ **Current activeDid storage** in settings table - **Time**: 2025-01-27T18:30Z - **Evidence**: `src/db/tables/settings.ts:25` - activeDid field exists - **Verify at**: Current database schema and Settings type definition - ✅ **PlatformServiceMixin integration** with activeDid - **Time**: 2025-01-27T18:30Z - **Evidence**: `src/utils/PlatformServiceMixin.ts:108` - activeDid tracking - **Verify at**: Component usage across all platforms - ✅ **Database migration infrastructure** exists - **Time**: 2025-01-27T18:30Z - **Evidence**: `src/db-sql/migration.ts:31` - migration system in place - **Verify at**: Existing migration scripts and database versioning ## What Doesn't (Evidence & Hypotheses) - ❌ **No separate active_identity table** exists - **Time**: 2025-01-27T18:30Z - **Evidence**: Database schema only shows settings table - **Hypothesis**: Table needs to be created as part of migration - **Next probe**: Create migration script for new table - ❌ **Platform services hardcoded** to settings table - **Time**: 2025-01-27T18:30Z - **Evidence**: `src/services/platforms/*.ts` - direct settings table access - **Hypothesis**: All platform services need updates - **Next probe**: Audit all platform service files for activeDid usage ## Risks, Limits, Assumptions - **Data Loss Risk**: Migration failure could lose activeDid values - **Breaking Changes**: API updates required across all platform services - **Rollback Complexity**: Schema changes make rollback difficult - **Testing Overhead**: All platforms must be tested with new structure - **Performance Impact**: Additional table join for activeDid retrieval - **Migration Timing**: Must be coordinated with other database changes ## Next Steps | Owner | Task | Exit Criteria | Target Date (UTC) | |-------|------|---------------|-------------------| | Development Team | Create migration script | Migration script tested and validated | 2025-01-28 | | Development Team | Update type definitions | Settings type updated, ActiveIdentity type created | 2025-01-28 | | Development Team | Update platform services | All services use new active_identity table | 2025-01-29 | | Development Team | Update PlatformServiceMixin | Mixin methods updated and tested | 2025-01-29 | | QA Team | Platform testing | All platforms tested and verified | 2025-01-30 | | Development Team | Deploy migration | Production deployment successful | 2025-01-31 | ## References - [Database Migration Guide](./database-migration-guide.md) - [Dexie to SQLite Mapping](./dexie-to-sqlite-mapping.md) - [PlatformServiceMixin Documentation](./component-communication-guide.md) - [Migration Templates](./migration-templates/) ## Competence Hooks - *Why this works*: Separates concerns between identity selection and user preferences, improves database normalization, enables future identity management features - *Common pitfalls*: Forgetting to update all platform services, not testing rollback scenarios, missing data validation during migration - *Next skill unlock*: Advanced database schema design and migration planning - *Teach-back*: Explain the four-phase migration approach and why each phase is necessary ## Collaboration Hooks - **Sign-off checklist**: - [ ] Migration script tested on development database - [ ] All platform services updated and tested - [ ] Rollback plan validated - [ ] Performance impact assessed - [ ] All stakeholders approve deployment timeline ## Assumptions & Limits - Current activeDid values are valid and should be preserved - All platforms can handle the additional database table - Migration can be completed without user downtime - Rollback to previous schema is acceptable if needed - Performance impact of additional table join is minimal ## Component & View Impact Analysis ### **High Impact Components** 1. **`IdentitySection.vue`** - Direct dependency on `activeDid` - **Current**: Uses `activeDid` from component data - **Impact**: Will need to update data binding and refresh logic - **Risk**: **HIGH** - Core identity display component **Current Implementation:** ```vue <template> <div class="text-sm text-slate-500"> <div class="font-bold">ID:&nbsp;</div> <code class="truncate">{{ activeDid }}</code> <!-- ... rest of template --> </div> </template> <script lang="ts"> export default class IdentitySection extends Vue { activeDid = ""; // Direct component data async mounted() { const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; } } </script> ``` **Required Changes:** ```vue <script lang="ts"> export default class IdentitySection extends Vue { activeDid = ""; // Still needed for template binding async mounted() { // This will automatically work if $accountSettings() is updated const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; } // Add watcher for activeDid changes async onActiveDidChanged(newDid: string | null) { if (newDid) { this.activeDid = newDid; } } } </script> ``` 2. **`DIDView.vue`** - Heavy activeDid usage - **Current**: Initializes `activeDid` in `mounted()` lifecycle - **Impact**: Must update initialization logic to use new table - **Risk**: **HIGH** - Primary DID viewing component **Current Implementation:** ```vue <script lang="ts"> export default class DIDView extends Vue { activeDid = ""; // Component data async mounted() { await this.initializeSettings(); await this.determineDIDToDisplay(); // ... rest of initialization } private async initializeSettings() { const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; this.apiServer = settings.apiServer || ""; } private async determineDIDToDisplay() { const pathParam = window.location.pathname.substring("/did/".length); let showDid = pathParam; if (!showDid) { // No DID provided in URL, use active DID showDid = this.activeDid; // Uses component data this.notifyDefaultToActiveDID(); } // ... rest of logic } } </script> ``` **Required Changes:** ```vue <script lang="ts"> export default class DIDView extends Vue { activeDid = ""; // Component data still needed async mounted() { await this.initializeSettings(); await this.determineDIDToDisplay(); // ... rest of initialization } private async initializeSettings() { // This will automatically work if $accountSettings() is updated const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; this.apiServer = settings.apiServer || ""; } // Add watcher for activeDid changes async onActiveDidChanged(newDid: string | null) { if (newDid && newDid !== this.activeDid) { this.activeDid = newDid; // Re-initialize if needed await this.determineDIDToDisplay(); } } } </script> ``` 3. **`HomeView.vue`** - ActiveDid change detection - **Current**: Has `onActiveDidChanged()` watcher method - **Impact**: Watcher logic needs updates for new data source - **Risk**: **MEDIUM** - Core navigation component **Current Implementation:** ```vue <script lang="ts"> export default class HomeView extends Vue { async onActiveDidChanged(newDid: string | null, oldDid: string | null) { if (newDid !== oldDid) { // Re-initialize identity with new settings (loads settings internally) await this.initializeIdentity(); } else { logger.debug( "[HomeView Settings Trace] 📍 DID unchanged, skipping re-initialization", ); } } private async initializeIdentity() { // ... identity initialization logic const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; // ... rest of initialization } } </script> ``` **Required Changes:** ```vue <script lang="ts"> export default class HomeView extends Vue { async onActiveDidChanged(newDid: string | null, oldDid: string | null) { if (newDid !== oldDid) { // This will automatically work if $accountSettings() is updated await this.initializeIdentity(); } else { logger.debug( "[HomeView Settings Trace] 📍 DID unchanged, skipping re-initialization", ); } } private async initializeIdentity() { // ... identity initialization logic // This will automatically work if $accountSettings() is updated const settings = await this.$accountSettings(); this.activeDid = settings.activeDid || ""; // ... rest of initialization } } </script> ``` **Key Insight**: HomeView will require minimal changes since it already uses the `$accountSettings()` method, which will be updated to handle the new table structure transparently. ### **Medium Impact Components** 1. **`InviteOneAcceptView.vue`** - Identity fallback logic - **Current**: Creates identity if no `activeDid` exists - **Impact**: Fallback logic needs to check new table - **Risk**: **MEDIUM** - Invite processing component 2. **`ClaimView.vue`** - Settings retrieval - **Current**: Gets `activeDid` from `$accountSettings()` - **Impact**: Will automatically work if API is updated - **Risk**: **LOW** - Depends on API layer updates 3. **`ContactAmountsView.vue`** - Direct settings access - **Current**: Accesses `activeDid` directly from settings - **Impact**: Must update to use new API methods - **Risk**: **MEDIUM** - Financial display component ### **Service Layer Impact** 1. **`WebPlatformService.ts`** - **Current**: Direct SQL queries to settings table - **Impact**: Must add `active_identity` table queries - **Risk**: **HIGH** - Core web platform service 2. **`CapacitorPlatformService.ts`** - **Current**: Similar direct SQL access - **Impact**: Same updates as web service - **Risk**: **HIGH** - Mobile platform service 3. **`PlatformServiceMixin.ts`** - **Current**: Core methods like `$accountSettings()`, `$saveSettings()` - **Impact**: Major refactoring required - **Risk**: **CRITICAL** - Used by 50+ components ### **API Contract Changes** 1. **`$saveSettings()` method** - **Current**: Updates `settings.activeDid` - **New**: Updates `active_identity.activeDid` - **Impact**: All components using this method 2. **`$updateActiveDid()` method** - **Current**: Internal tracking only - **New**: Database persistence required - **Impact**: Identity switching logic ### **Testing Impact** 1. **Unit Tests** - All platform service methods - PlatformServiceMixin methods - Database migration scripts 2. **Integration Tests** - Component behavior with new data source - Identity switching workflows - Settings persistence 3. **Platform Tests** - Web, Electron, iOS, Android - Cross-platform data consistency - Migration success on all platforms ### **Performance Impact** 1. **Additional Table Join** - Settings queries now require active_identity table - Potential performance impact on frequent operations - Need for proper indexing 2. **Caching Considerations** - ActiveDid changes trigger cache invalidation - Component re-rendering on identity switches - Memory usage for additional table data ### **Risk Assessment by Component Type** - **Critical Risk**: PlatformServiceMixin, Platform Services - **High Risk**: Identity-related components, views using `$accountSettings()` - **Medium Risk**: Components with direct settings access, identity management - **Low Risk**: Components using only basic settings, utility components ### **Migration Timeline Impact** - **Phase 1**: Schema Creation (1-2 days) - No component impact - **Phase 2**: Data Migration (1 day) - No component impact - **Phase 3**: API Updates (3-5 days) - All components affected - **Phase 4**: Cleanup (1-2 days) - No component impact ### **Update Priority Order** 1. **PlatformServiceMixin** - Core dependency for most components 2. **Platform Services** - Ensure data access layer works 3. **Identity Components** - Verify core functionality 4. **Settings-Dependent Views** - Update in dependency order 5. **Utility Components** - Final cleanup and testing ## Deferred for depth - Advanced identity management features enabled by this change - Performance optimization strategies for the new table structure - Future schema evolution planning - Advanced rollback and recovery procedures
anomalist added 1 commit 2025-08-27 12:51:24 +00:00
anomalist added 1 commit 2025-08-28 12:32:01 +00:00
- Add master settings functions implementation strategy
- Correct IdentitySection.vue analysis (prop-based, no changes required)
- Simplify ContactAmountsView.vue (phased-out method, separate refactoring)
- Add new getMasterSettings() function with active_identity integration
- Include helper methods _getSettingsWithoutActiveDid() and _getActiveIdentity()
- Enhance evidence section with master settings architecture support
- Update risk assessment for phased-out methods
- Clean up migration timeline formatting

This commit focuses the migration plan on components requiring immediate
active_identity table changes, separating concerns from broader API refactoring.
anomalist added 1 commit 2025-08-29 07:14:56 +00:00
anomalist added 1 commit 2025-08-29 07:57:48 +00:00
- Add foreign key constraints to prevent data corruption
- Implement comprehensive migration validation and rollback
- Focus API updates on PlatformServiceMixin only (no component changes)
- Add enhanced error handling and data integrity checks
- Streamline plan to focus only on what needs to change
- Update timestamps and implementation details for current state

Breaking Changes:
- Database schema requires new active_identity table with constraints
- PlatformServiceMixin methods need updates for new table structure

Migration Impact:
- 50+ components work automatically through API layer
- Only core database and API methods require changes
- Comprehensive rollback procedures for risk mitigation
anomalist added 1 commit 2025-08-29 08:53:52 +00:00
anomalist added 1 commit 2025-08-29 10:50:55 +00:00
- Remove unnecessary complexity and focus on essential changes only
- Integrate with existing IndexedDB migration service (indexedDBMigrationService.ts)
- Maintain backward compatibility with existing migration paths
- Focus on core requirements: database schema, API methods, type definitions
- Eliminate duplicate migration logic already handled by existing service
- Preserve MASTER_SETTINGS_KEY = "1" for legacy support
- Add clear rollback strategy and integration points

The plan now focuses only on necessary changes while maintaining full
compatibility with existing systems and migration infrastructure.
anomalist added 1 commit 2025-08-29 11:05:42 +00:00
- Add data migration SQL to migration 003 for existing databases
- Automatically copy activeDid from settings table to active_identity table
- Prevent users from losing active identity selection during migration
- Include validation to ensure data exists before migration
- Maintain atomic operation: schema and data migration happen together
- Update risk assessment to reflect data loss prevention
- Add data migration strategy documentation

The migration now safely handles both new and existing databases,
ensuring no user data is lost during the activeDid table separation.
anomalist added 1 commit 2025-08-29 11:47:31 +00:00
- Add migration 003 with data migration logic to prevent data loss
- Create dedicated ActiveIdentity interface in separate file for better architecture
- Implement $getActiveIdentity method in PlatformServiceMixin
- Enhance $updateActiveDid with dual-write pattern for backward compatibility
- Maintain separation of concerns between settings and active identity types
- Follow project architectural pattern with dedicated type definition files

The migration creates active_identity table alongside existing settings,
automatically copying existing activeDid data to prevent user data loss.
Dual-write pattern ensures backward compatibility during transition.

Migration includes:
- Schema creation with proper constraints and indexes
- Automatic data transfer from settings.activeDid to active_identity.activeDid
- Validation to ensure data exists before migration
- Atomic operation: schema and data migration happen together
trentlarson reviewed 2025-08-30 03:38:40 +00:00
@@ -127,0 +130,4 @@
-- 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,
Owner

Since the activeDid can actually be a blank ('') value, I personally would prefer that this is nullable. (Saying "NOT NULL" but using '' to represent null just feels odd... like something that's trying to bypass type-checking.)

Since the activeDid can actually be a blank ('') value, I personally would prefer that this is nullable. (Saying "NOT NULL" but using '' to represent null just feels odd... like something that's trying to bypass type-checking.)
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-08-30 03:39:17 +00:00
@@ -127,0 +136,4 @@
);
-- Add performance indexes
CREATE INDEX IF NOT EXISTS idx_active_identity_activeDid ON active_identity(activeDid);
Owner

Why put an index on activeDid? It'll never be the input to a query.

Why put an index on activeDid? It'll never be the input to a query.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-08-30 03:40:14 +00:00
@@ -127,0 +137,4 @@
-- 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);
Owner

There's no reason to index the 'id' column since it's a primary key. (Even if it weren't, we'll only ever have one entry so an index is overkill.)

There's no reason to index the 'id' column since it's a primary key. (Even if it weren't, we'll only ever have one entry so an index is overkill.)
trentlarson marked this conversation as resolved
anomalist added 3 commits 2025-08-30 04:30:46 +00:00
Transform verbose planning document into actionable implementation guide:
- Replace theoretical sections with specific code changes required
- Add missing $getActiveIdentity() method implementation
- List 35+ components requiring activeDid pattern updates
- Include exact code patterns to replace in components
- Add implementation checklist with clear phases
- Remove redundant architecture diagrams and explanations

Focuses on practical implementation steps rather than planning theory.
anomalist added 1 commit 2025-08-31 00:56:24 +00:00
Updated activeDid migration plan to reflect Phase 2 API layer implementation
completion. Added critical blocker notes about IndexedDB database inspection
requirements and updated next steps with priority levels.

- Marked Phase 2 as COMPLETE with dual-write pattern implementation
- Added critical blocker for IndexedDB database inspection
- Updated next steps with priority levels and realistic timelines
- Clarified database state requirements for testing
anomalist added 2 commits 2025-08-31 03:49:04 +00:00
Update $getActiveIdentity() method to return { activeDid: string } instead
of full ActiveIdentity object. Add validation to ensure activeDid exists
in accounts table and clear corrupted values. Update migration plan to
reflect completed first step of API layer implementation.

- Change return type from Promise<ActiveIdentity> to Promise<{ activeDid: string }>
- Add account validation with automatic corruption cleanup
- Simplify query to only select activeDid field
- Improve error handling to return empty string instead of throwing
- Update migration plan documentation with current status
anomalist added 1 commit 2025-08-31 05:22:22 +00:00
- Update () to call () with fallback to settings
- Maintain backward compatibility while using new active_identity table
- Update migration plan documentation to reflect completed Step 1
- Restore Playwright workers to 4 (was accidentally set to 1)

Tests: 39/40 passing (1 unrelated UI failure)
Migration progress: Step 1 complete, ready for Step 2 dual-write implementation
anomalist added 1 commit 2025-08-31 05:27:38 +00:00
- Add database persistence to $updateActiveDid() method
- Implement dual-write to both active_identity and settings tables
- Add error handling with graceful fallback to in-memory updates
- Include debug logging for migration monitoring
anomalist added 1 commit 2025-09-01 06:05:05 +00:00
- Fix $updateActiveDid() to use MASTER_SETTINGS_KEY constant instead of hardcoded "1"
- Update migration plan to reflect current state after rollback
- Ensure backward compatibility during activeDid migration transition

The dual-write pattern now correctly updates both active_identity and settings tables
using the proper MASTER_SETTINGS_KEY constant for settings table targeting.
anomalist added 1 commit 2025-09-01 06:15:42 +00:00
- Add minimal change to prioritize activeDid from active_identity table
- Maintain all existing complex logic and backward compatibility
- Update migration plan to reflect API layer completion

The $accountSettings method now uses the new active_identity table as primary
source while preserving all existing settings merging and fallback behavior.
anomalist added 8 commits 2025-09-02 10:28:32 +00:00
- Add $getActiveIdentity() method to PlatformServiceMixin interface
- Update HomeView.vue to use new active_identity API methods
- Update ContactsView.vue to use new active_identity API methods
- Fix apiServer default handling in PlatformServiceMixin
- Ensure DEFAULT_ENDORSER_API_SERVER is used when apiServer is empty
- Add comprehensive logging for debugging ActiveDid migration
- Resolve TypeScript interface issues with Vue mixins
- Create comprehensive bug report for Vue reactivity issue
- Update README.md with known issues section
- Document workaround for numNewOffersToUser watcher requirement
- Add technical details about Vue template rendering issues
- Implement comprehensive dialog overlay handling for all test files
- Add robust page state checking for Firefox navigation issues
- Fix alert button timing issues with combined find/click approach
- Add force close dialog overlay as fallback for persistent dialogs
- Handle page close scenarios during dialog dismissal
- Add page readiness checks before interactions
- Resolve race conditions between dialog close and page navigation
- Achieve consistent 40/40 test runs with systematic fixes
- Update PlatformServiceMixin interface to include $getActiveIdentity
- Improve apiServer default handling across all platforms
- Add better error handling for platform service methods
- Ensure consistent behavior across web and electron platforms
- Update all components to use new active_identity API methods
- Ensure consistent activeDid retrieval across all views
- Add proper error handling for activeDid migration
- Update component interfaces for new API structure
- Update utility functions for new active_identity table structure
- Modify Vite configuration for improved build process
- Add support for new API endpoints and data structures
- Update cursor rules for improved development workflow
- Add guidelines for ActiveDid migration process
- Update version control workflow documentation
- Improve development process documentation
anomalist added 1 commit 2025-09-02 10:28:55 +00:00
anomalist added 31 commits 2025-09-03 06:33:18 +00:00
- Create separate Electron-specific capacitor config
- Update build script to not copy main config to Electron directory
- Fix TypeScript compilation by excluding main config from Electron tsconfig

Resolves TypeScript compilation errors in npm run build:electron:dev
- Add duplicate check in ImportAccountView before account import
- Add duplicate check in ImportDerivedAccountView for derived accounts
- Add safety check in saveNewIdentity function to prevent duplicate saves
- Implement user-friendly warning messages for duplicate attempts
- Add comprehensive error handling to catch duplicate errors from saveNewIdentity
- Create Playwright tests to verify duplicate prevention functionality
- Add documentation for duplicate prevention implementation

The system now prevents users from importing the same account multiple times
by checking for existing DIDs both before import (pre-check) and during
save (post-check). Users receive clear warning messages instead of
technical errors when attempting to import duplicate accounts.

Files modified:
- src/views/ImportAccountView.vue: Add duplicate check and error handling
- src/views/ImportDerivedAccountView.vue: Add duplicate check for derived accounts
- src/libs/util.ts: Add duplicate prevention in saveNewIdentity
- test-playwright/duplicate-import-test.spec.ts: Add comprehensive tests
- doc/duplicate-account-import-implementation.md: Add implementation docs

Resolves: Prevent duplicate account imports in IdentitySwitcherView
- Add NOTIFY_DUPLICATE_ACCOUNT_IMPORT constant for import warnings
- Add NOTIFY_DUPLICATE_DERIVED_ACCOUNT constant for derived account warnings
- Update ImportAccountView.vue to use notification constants
- Update ImportDerivedAccountView.vue to use notification constants
- Update test file to use notification constants for assertions

Centralizes notification messages for better maintainability and consistency
with the existing notification system.

Files modified:
- src/constants/notifications.ts: Add new notification constants
- src/views/ImportAccountView.vue: Replace hardcoded messages with constants
- src/views/ImportDerivedAccountView.vue: Replace hardcoded messages with constants
- test-playwright/duplicate-import-test.spec.ts: Update test assertions
- Rename the test to run it earlier in the test suite
- Remove redundant "import User Zero" action
- Remove out-of-scope actions from test (sending a gift to an unrelated entity, deleting the contact)
- Update imports based on changes
- Use the ./account route to mimic real-world use
Fixes issue where identity names were not saved when switching between
multiple identities. Names were being saved to master settings instead
of user-specific settings.

Changes:
- UserNameDialog: Load/save names from/to user-specific settings
- NewEditAccountView: Save names to user-specific settings for active DID
- Both components now use $accountSettings() and $saveUserSettings()
  instead of $settings() and $updateSettings()

Each identity now properly retains their assigned name when switching
between identities. Previously only "User Zero" would show their name
due to using master settings instead of per-identity settings.

Fixes: Identity name persistence across identity switches
- Add 'editMenu' role to AppMenuBarMenuTemplate in setup.ts and index.ts
- Enables standard keyboard shortcuts (Cmd+C, Cmd+V, etc.) in Electron app
- Fixes issue where copy/paste shortcuts were not working in text inputs
- Maintains existing clipboard service functionality for programmatic operations

Resolves keyboard shortcut functionality for better user experience in desktop app.
Reviewed-on: #187
- Replace constant usage with direct message string in ImportDerivedAccountView.vue
- Clean up import statement to remove unused import
- Remove unused constant from notifications.ts
- Remove lastName field from $saveUserSettings and $saveSettings calls
- Clean up deprecated pre v0.1.3 code
Reviewed-on: #191
Reviewed-on: #192
- Generated document reads more like a log, and does not contribute to actual documentation of app
- Extract checkForDuplicateAccount methods from ImportAccountView and ImportDerivedAccountView
- Create unified utility function in src/libs/util.ts with TypeScript overloads
- Support both direct DID checking and mnemonic+derivation path checking
- Improve error handling with centralized logging via PlatformServiceFactory
- Add comprehensive JSDoc documentation for both function overloads
- Remove unused imports (deriveAddress, newIdentifier) from ImportAccountView

The utility function now provides a clean API:
- checkForDuplicateAccount(did) - for direct DID checking
- checkForDuplicateAccount(mnemonic, derivationPath) - for derivation + checking

Both components maintain identical functionality while using centralized logic.
Replace dual string check with single unique identifier for more precise error handling
Reviewed-on: #183
Reviewed-on: #189
Reviewed-on: #190
- Fix dialog overlay handling across multiple test files
- Implement adaptive timeouts and retry logic for load resilience
- Add robust activity feed verification in gift recording tests
- Resolve Vue reactivity issues with proper type assertions
- Achieve 98% test success rate (88/90 tests passing across 3 runs)

The test suite now passes consistently under normal conditions with only
intermittent load-related timeouts remaining.
anomalist added 1 commit 2025-09-03 07:38:11 +00:00
trentlarson requested changes 2025-09-04 02:25:51 +00:00
trentlarson reviewed 2025-09-04 02:26:22 +00:00
@@ -225,0 +225,4 @@
logger.info("[GiftedDialog] Settings received:", {
activeDid: this.activeDid,
apiServer: this.apiServer,
});
Owner

I vote we make this a debug.

I vote we make this a debug.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-09-04 02:40:56 +00:00
@@ -199,0 +268,4 @@
);
}
},
Owner

I'm not convinced this is the approach we want for data consistency. If the initial migration goes wrong then we have bigger problems (and hopefully we notify the user).

This will actually pick some other value indiscriminately, and it could do it an unexpected times (eg. in the ContactsView explicitly in this PR, or any other page that accesses the getActiveIdentity). I vote we remove it, and if we feel there are migration problems then provide more feedback for the user to choose.

I'm not convinced this is the approach we want for data consistency. If the initial migration goes wrong then we have bigger problems (and hopefully we notify the user). This will actually pick some other value indiscriminately, and it could do it an unexpected times (eg. in the ContactsView explicitly in this PR, or any other page that accesses the getActiveIdentity). I vote we remove it, and if we feel there are migration problems then provide more feedback for the user to choose.
Author
Owner

I will have to give this some thought. It did seem to give the whole migration more stability -- but I feel you that it seems a bit "icky"

I will have to give this some thought. It did seem to give the whole migration more stability -- but I feel you that it seems a bit "icky"
Owner

(Unfortunately the lines have changed, but I assume this is all about the $needsActiveIdentitySelection method.)

I don't see where this is used now. Maybe the usages have been removed, in which case this could be removed. If it's still used or in planning, I'll watch for the usages... I tried to determine the purpose (like why it's good to return true if there is no active identity but there are other settings) but I don't understand.

(Unfortunately the lines have changed, but I assume this is all about the $needsActiveIdentitySelection method.) I don't see where this is used now. Maybe the usages have been removed, in which case this could be removed. If it's still used or in planning, I'll watch for the usages... I tried to determine the purpose (like why it's good to return true if there is no active identity but there are other settings) but I don't understand.
Author
Owner

$needsActiveIdentitySelection is still there as a definition but it unused. I'm removing it.

$needsActiveIdentitySelection is still there as a definition but it unused. I'm removing it.
Owner

It's gone! 💥

It's gone! 💥
trentlarson marked this conversation as resolved
Owner

I like the removal of the MASTER_SETTINGS here! 👏 Let's hope it goes well.

I vote we make all those migrations into a single one, since they're all part of the same merge when we go to master.

I like the removal of the MASTER_SETTINGS here! 👏 Let's hope it goes well. I vote we make all those migrations into a single one, since they're all part of the same merge when we go to master.
anomalist added 3 commits 2025-09-04 07:27:34 +00:00
- Replace settings.activeDid with () pattern
- Maintains backward compatibility with existing functionality
- Component now uses active_identity table as single source of truth
- Part of ActiveDid migration (1/32 components completed)
- Replace settings.activeDid with () pattern
- Maintains backward compatibility with existing functionality
- Component now uses active_identity table as single source of truth
- Part of ActiveDid migration (2/32 components completed)
- Updated migration plan to include lint-fix step
Migrate all 34 Vue components from settings.activeDid to $getActiveIdentity()
pattern. This completes the database architecture improvement that separates
identity selection from user preferences and prevents data corruption.

- Replace this.activeDid = settings.activeDid with $getActiveIdentity() calls
- Add ESLint ignore comments for TypeScript type assertions
- Update migration plan documentation to reflect completion
- All components tested with passing results

BREAKING CHANGE: Components now use active_identity table as single source
of truth for activeDid values instead of settings table
anomalist added 1 commit 2025-09-04 07:43:15 +00:00
anomalist added 1 commit 2025-09-04 10:35:56 +00:00
- Remove problematic $ensureActiveIdentityPopulated() that auto-selected identities
- Add user-friendly $needsActiveIdentitySelection() and $getAvailableAccountDids() methods
- Fix missing updateActiveDid implementation in CapacitorPlatformService
- Resolve race condition in HomeView initialization causing feed loading failures
- Improve TypeScript error handling in ContactsView invite processing

Addresses team concerns about data consistency and user control for identity selection.
trentlarson reviewed 2025-09-05 02:11:56 +00:00
@@ -551,0 +681,4 @@
await this.$dbExec(
"UPDATE active_identity SET activeDid = '', lastUpdated = datetime('now') WHERE id = 1",
);
return { activeDid: "" };
Owner

I'm still not sure that these checks are necessary but I won't let that hold up things since I don't see how it can hurt. But: instead of erasing the activeDid, I suggest we keep the value and create a blank entry for it in the settings table.

I'm still not sure that these checks are necessary but I won't let that hold up things since I don't see how it can hurt. But: instead of erasing the activeDid, I suggest we keep the value and create a blank entry for it in the settings table.
Author
Owner

I tweaked this a bit but the checks are still there. I've got it wired up to a foreign key (accounts.did).

I'll try a bit of a clean-up experiment.

I tweaked this a bit but the checks are still there. I've got it wired up to a foreign key (accounts.did). I'll try a bit of a clean-up experiment.
Owner

Looks good to me.

Looks good to me.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-09-05 02:20:45 +00:00
@@ -861,2 +1048,4 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void id;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void activeDidField;
Owner

These voids seem unnecessary. Educate me if I'm wrong.

These voids seem unnecessary. Educate me if I'm wrong.
Author
Owner

Really depends on your philosophy of typing. I vote they stay since they only make it explicit and don't survive into the actual build.

Really depends on your philosophy of typing. I vote they stay since they only make it explicit and don't survive into the actual build.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-09-05 02:20:45 +00:00
trentlarson reviewed 2025-09-05 02:25:11 +00:00
@@ -675,0 +814,4 @@
elementWillRender:
this.numNewOffersToUser + this.numNewOffersToUserProjects > 0,
timestamp: new Date().toISOString(),
});
Owner

More logging that seems like they should be "debug" statements.

More logging that seems like they should be "debug" statements.
Author
Owner

I'll be doing another pass on these before we merge into master.

I'll be doing another pass on these before we merge into master.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-09-05 02:29:07 +00:00
@@ -31,0 +55,4 @@
return true;
}
return false;
}, { timeout: 5000 });
Owner

If these timeout, do the tests fail? (I hope so. The Playwright docs don't make it obvious.)

If these timeout, do the tests fail? (I hope so. The Playwright docs don't make it obvious.)
Author
Owner

If I remember correctly (and pretty sure I do), there is a global timeout of 45s so "yes".

If I remember correctly (and pretty sure I do), there is a global timeout of 45s so "yes".
Author
Owner

Updated. Internal documentation to spell this out for you.

Updated. Internal documentation to spell this out for you.
trentlarson marked this conversation as resolved
trentlarson reviewed 2025-09-05 02:34:42 +00:00
@@ -22,0 +24,4 @@
if (process.env.NODE_ENV === 'development') {
process.env.VITE_DEFAULT_ENDORSER_API_SERVER = 'http://localhost:3000';
process.env.VITE_DEFAULT_PARTNER_API_SERVER = 'http://localhost:3000';
}
Owner

If this is necessary then it appears that something is wrong with the ".env.development" environment loading on line 9. Is there something deeper to fix here? (I ask because it's the addition of more environment logic, where it would be preferable to keep these forced settings isolated for maintainability.)

If this is necessary then it appears that something is wrong with the ".env.development" environment loading on line 9. Is there something deeper to fix here? (I ask because it's the addition of more environment logic, where it would be preferable to keep these forced settings isolated for maintainability.)
Author
Owner

Yeah I saw this as well. I'll clean this up today.

Yeah I saw this as well. I'll clean this up today.
trentlarson marked this conversation as resolved
anomalist added 2 commits 2025-09-05 04:04:21 +00:00
- Fix logging levels: change verbose debugging from info to debug level
  - TestView: component mounting, boot-time config, URL flow testing
  - main.capacitor.ts: deeplink processing steps and router state
  - HomeView: API call details, component state updates, template rendering

- Remove redundant environment variable override in vite.config.common.mts
  - Environment loading via dotenv works correctly
  - Manual override was defensive programming but unnecessary
  - Simplifies configuration and reduces maintenance burden

- Add comprehensive Playwright timeout behavior documentation
  - README.md: detailed timeout types, failure behavior, debugging guide
  - TESTING.md: timeout failure troubleshooting and common scenarios
  - Clarifies that timeout failures indicate real issues, not flaky tests

- Fix TypeScript configuration for .mts imports
  - tsconfig.node.json: add allowImportingTsExtensions for Vite config files
  - Resolves import path linting errors for .mts extensions

All changes maintain existing functionality while improving code quality
and reducing log noise in production environments.
anomalist added 1 commit 2025-09-05 04:56:07 +00:00
- Add missing migrations table creation to 001_initial migration
- Consolidate migrations 003-006 into single 003_active_did_separation migration
- Rename migration for better clarity and logical grouping
- Preserve all original SQL operations and data integrity constraints
- Reduce migration complexity while maintaining functionality

This consolidation improves maintainability by grouping related schema changes
into logical atomic operations, reducing the total migration count by 50%.
jose added 1 commit 2025-09-05 09:47:10 +00:00
The complex table rewrite approach in migration 003_active_did_separation was
failing on iOS SQLite, causing "no such table: active_identity" errors. The
migration was being marked as applied despite validation failures.

Changes:
- Simplify migration SQL to only create active_identity table and migrate data
- Remove complex table rewrite that was failing on iOS SQLite versions
- Remove foreign key constraint that could cause compatibility issues
- Update validation logic to focus on active_identity table existence only
- Remove validation check for activeDid column removal from settings table

This approach is more reliable across different SQLite versions and platforms
while maintaining the core functionality of separating activeDid into its own
table for better database architecture.

Fixes iOS build database errors and ensures migration completes successfully.
jose added 1 commit 2025-09-05 09:50:25 +00:00
- Fix line breaks and indentation for long SQL queries
- Improve readability of error message formatting
- Remove trailing whitespace and standardize spacing
- Apply consistent formatting to active_identity table validation logic
trentlarson added 1 commit 2025-09-06 01:52:06 +00:00
trentlarson added 1 commit 2025-09-06 02:02:01 +00:00
anomalist added 1 commit 2025-09-07 10:30:03 +00:00
- Consolidate migrations: merge 002/003 into 001_initial with UNIQUE did constraint
- Add foreign key: active_identity.activeDid REFERENCES accounts.did ON DELETE RESTRICT
- Replace empty string defaults with NULL for proper empty state handling
- Implement atomic smart deletion with auto-switch logic in IdentitySwitcherView
- Add DAL methods: $getAllAccountDids, $getActiveDid, $setActiveDid, $pickNextAccountDid
- Add migration bootstrapping to auto-select first account if none selected
- Block deletion of last remaining account with user notification

Refs: doc/active-pointer-smart-deletion-pattern.md
anomalist added 1 commit 2025-09-08 06:32:11 +00:00
anomalist added 2 commits 2025-09-08 11:37:59 +00:00
- Consolidate 5 notification-system-* files into doc/notification-system.md
- Add web-push cleanup guide and Start-on-Login glossary entry
- Configure markdownlint for consistent formatting
- Remove web-push references, focus on native OS scheduling

Reduces maintenance overhead while preserving all essential information
in a single, well-formatted reference document.
anomalist added 1 commit 2025-09-08 12:02:25 +00:00
**Type Safety Improvements:**
- Replace `unknown[]` with proper `SqlValue[]` type in database query methods
- Add `SqlValue` import to PlatformServiceMixin.ts for better type definitions
- Update interface definitions for `$dbGetOneRow` and `$one` methods
- Fix database row mapping to use `Array<SqlValue>` instead of `unknown[]`

**Test Reliability Fix:**
- Add backup seed modal handling to 60-new-activity.spec.ts
- Follow established dialog handling pattern from 00-noid-tests.spec.ts
- Use `waitForFunction` to detect backup seed modal appearance
- Gracefully handle modal dismissal with "No, Remind me Later" button
- Add error handling for cases where backup modal doesn't appear

**Files Changed:**
- src/utils/PlatformServiceMixin.ts: Enhanced type safety for database operations
- test-playwright/60-new-activity.spec.ts: Fixed dialog interception causing test failures

**Impact:**
- Eliminates TypeScript linting errors for database query types
- Resolves Playwright test timeout caused by backup seed modal blocking clicks
- Improves test reliability by following established dialog handling patterns
- Maintains backward compatibility while enhancing type safety

**Testing:**
- TypeScript compilation passes without errors
- Linting checks pass with improved type definitions
- Playwright test now handles backup seed modal properly
anomalist added 2 commits 2025-09-09 06:21:09 +00:00
- Split consolidated migration into 3 separate migrations
- Preserve master's 001_initial and 002_add_iViewContent structure
- Move active_identity creation to new 003_active_identity_and_seed_backup
- Add hasBackedUpSeed field from registration-prompt-parity branch
- Remove activeDid performance index for simplified migration
- Maintain foreign key constraints and smart deletion pattern
- Remove unused $getAllAccountDids method from PlatformServiceMixin

This restructure ensures backward compatibility with master branch
while adding advanced features (active_identity table, seed backup
tracking) in a clean, maintainable migration sequence.
anomalist added 1 commit 2025-09-09 06:32:44 +00:00
- Fix 50-record-offer.spec.ts multiple alert button conflict
  * Replace generic alert selector with success-specific selector
  * Use getByRole('alert').filter({ hasText: 'Success' }) pattern

- Fix 20-create-project.spec.ts onboarding dialog timeout
  * Replace unreliable div > svg.fa-xmark selector
  * Use established closeOnboardingAndFinish testId pattern
  * Add waitForFunction to ensure dialog dismissal

- Fix 25-create-project-x10.spec.ts onboarding dialog timeout
  * Apply same onboarding dismissal pattern as other tests
  * Ensure consistent dialog handling across test suite

These fixes use established patterns from working tests to resolve
6 failing tests caused by UI selector conflicts and timing issues.
anomalist added 1 commit 2025-09-09 06:43:28 +00:00
- Fix onboarding dialog handling in project creation tests
  * Replace blocking onboarding dismissal with try-catch approach
  * Use short timeout (2000ms) to detect dialog presence
  * Gracefully handle missing onboarding dialogs on projects page
  * Add console logging for debugging dialog state

- Improve project creation timing and synchronization
  * Add networkidle wait after project save operation
  * Add networkidle wait before project list search
  * Increase timeout for project visibility check (10s)
  * Add debug logging to show all projects in list

- Apply consistent pattern across both test files
  * 20-create-project.spec.ts: Enhanced with timing fixes
  * 25-create-project-x10.spec.ts: Applied onboarding fix

These changes resolve test failures caused by UI timing issues
and onboarding dialog state variability, improving test reliability
from 42/44 passing to expected 44/44 passing tests.
jose added 1 commit 2025-09-09 07:41:32 +00:00
- Add $getAllAccountDids() implementation to resolve TypeError in ProjectsView
- Method queries accounts table and returns array of DIDs
- Includes proper error handling and logging
- Fixes "this.$getAllAccountDids is not a function" console error on /projects route

The method was declared in TypeScript interfaces but never implemented,
causing runtime errors when ProjectsView tried to initialize user identities.
jose added 1 commit 2025-09-09 07:56:27 +00:00
After calling OnboardingDialog from ProjectsView, route back to projects page again

The onboarding dialog was designed to route back to HomeView when called from ProjectsView. The tests need to be updated to account for this intended behavior.
trentlarson added 1 commit 2025-09-10 12:52:45 +00:00
trentlarson added 1 commit 2025-09-10 13:04:19 +00:00
anomalist added 2 commits 2025-09-10 13:20:32 +00:00
Replace `settings.activeDid` with `$getActiveIdentity()` API call.
Updates test/prod server warning logic to use active_identity table.

- Add `const activeIdentity = await this.$getActiveIdentity();`
- Update didPrefix extraction for both warning conditions
- Maintain existing warning functionality

 TypeScript compilation passes
 Linting standards met
 Functionality preserved

Part of ActiveDid migration following "One Component + Test Pattern".
anomalist added 1 commit 2025-09-11 01:42:11 +00:00
Replace `settings.activeDid` with `$getActiveIdentity()` API call.
Updates discover search functionality to use active_identity table.

- Add `const activeIdentity = await this.$getActiveIdentity();`
- Update activeDid assignment in mounted() lifecycle
- Maintain existing search and discovery functionality

 TypeScript compilation passes
 Linting standards met
 Functionality preserved

Part of ActiveDid migration following "One Component + Test Pattern".
anomalist added 1 commit 2025-09-11 02:00:48 +00:00
Replace `settings.activeDid` with `$getActiveIdentity()` API call across 8 components.
All Vue components now use the new active_identity table pattern.

Components migrated:
- TestView.vue: Update logging to use new pattern consistently
- ShareMyContactInfoView.vue: Refactor retrieveAccount method signature
- UserNameDialog.vue: Update user settings save logic
- SeedBackupView.vue: Update both created() and revealSeed() methods
- HelpView.vue: Update onboarding reset functionality
- ImportAccountView.vue: Update post-import settings check
- NewEditAccountView.vue: Update account save logic
- QuickActionBvcBeginView.vue: Update BVC recording functionality

 TypeScript compilation passes
 Linting standards met
 Functionality preserved across all components

Part of ActiveDid migration following "One Component + Test Pattern".
All Vue components now use centralized active_identity table.
anomalist added 2 commits 2025-09-11 05:08:30 +00:00
- Fix $getActiveIdentity() logic flow preventing false "empty table" warnings
- Implement auto-selection of first account when activeDid is null after migration
- Consolidate 003 and 003b migrations into single 003 migration
- Re-introduce foreign key constraint for activeDid referential integrity
- Add comprehensive debug logging for migration troubleshooting
- Remove 003b validation logic and update migration name mapping

Fixes migration from master to active_did_redux branch and ensures system
always has valid activeDid for proper functionality.
anomalist added 3 commits 2025-09-11 06:13:58 +00:00
## Changes Made

### Code Cleanup
- Remove unused $needsActiveIdentitySelection() method (36 lines)
- Remove method signature from IPlatformServiceMixin interface
- Remove method signature from Vue module declaration

### Database Consistency Fix
- Change activeDid clearing from empty string ('') to NULL for consistency
- Ensures proper foreign key constraint compatibility
- Maintains API compatibility by still returning empty string to components

## Impact
- Reduces codebase complexity by removing unused functionality
- Improves database integrity with consistent NULL usage
- No breaking changes to component APIs
- Migration and auto-selection now handle all identity management

## Files Changed
- src/utils/PlatformServiceMixin.ts: -42 lines, +1 line
- Remove excessive debug logging statements
- Fix critical bug: cast activeDid as string | null instead of string
- Refactor to use early return pattern, reducing nesting from 4 to 2-3 levels
- Eliminate redundant logic and improve code readability
- Maintain all original functionality while simplifying flow
- Fix null activeDid case that was breaking app initialization
anomalist added 1 commit 2025-09-11 07:20:40 +00:00
jose added 1 commit 2025-09-11 09:38:19 +00:00
The migration 003_active_identity_and_seed_backup was failing on iOS when
switching from master to active_did_redux branch because it attempted to
execute multiple SQL operations in a single block. When the ALTER TABLE
statement for hasBackedUpSeed failed (due to column already existing),
the entire migration was marked as "already applied" even though the
active_identity table was never created.

Changes:
- Split migration 003 into two separate migrations:
  - 003_active_identity_and_seed_backup: Creates active_identity table
  - 003b_add_hasBackedUpSeed_to_settings: Adds hasBackedUpSeed column
- Added data migration logic to copy existing activeDid from settings
  to active_identity table during migration
- Added debug logging to track migration results
- Ensured atomic operations so table creation doesn't depend on column addition

This fix ensures that:
- The active_identity table is always created successfully
- Existing activeDid values are preserved during migration
- The app remembers the active identity between master and active_did_redux builds
- Migration errors are handled gracefully without affecting other operations

Fixes iOS migration issue where app would lose active identity state
when switching between branches, causing users to lose their selected
identity and requiring manual re-selection.

Tested: Migration now works correctly on iOS simulator when switching
from master branch (with old schema) to active_did_redux branch.
anomalist added 1 commit 2025-09-11 13:07:47 +00:00
- 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
anomalist added 1 commit 2025-09-12 08:18:43 +00:00
anomalist added 1 commit 2025-09-12 08:56:48 +00:00
trentlarson added 1 commit 2025-09-14 23:24:42 +00:00
trentlarson added 1 commit 2025-09-14 23:45:15 +00:00
anomalist added 2 commits 2025-09-15 06:44:13 +00:00
- Fix syntax error in logger.ts: change 'typeof import' to 'typeof import.meta'
  to resolve ESBuild compilation error preventing web build

- Align CapacitorPlatformService.insertNewDidIntoSettings with WebPlatformService:
  * Add dynamic constants import to avoid circular dependencies
  * Use INSERT OR REPLACE for data integrity
  * Set proper default values (finishedOnboarding=false, API servers)
  * Remove TODO comment as implementation is now parallel

- Fix Playwright test timing issues in 60-new-activity.spec.ts:
  * Replace generic alert selectors with specific alert type targeting
  * Change Info alerts from 'Success' to 'Info' filter for proper targeting
  * Fix "strict mode violation" errors caused by multiple simultaneous alerts
  * Improve test reliability by using established alert handling patterns

- Update migrationService.ts and vite.config.common.mts with related improvements

Test Results: Improved from 2 failed tests to 42/44 passing (95.5% success rate)
Build Status: Web build now compiles successfully without syntax errors
anomalist added 1 commit 2025-09-15 07:23:08 +00:00
- Add Migration 005 to fix critical security vulnerability
- Change foreign key constraint from ON DELETE SET NULL to ON DELETE RESTRICT
- Prevents accidental account deletion through database constraints
- Update Active Pointer pattern documentation with current state analysis
- Achieve 83% compliance with Active Pointer + Smart Deletion Pattern

Security Impact: HIGH - Fixes critical data loss vulnerability
Migration: 005_active_identity_constraint_fix
Pattern Compliance: 5/6 components (83%)

Author: Matthew Raymer
anomalist added 1 commit 2025-09-15 07:37:13 +00:00
- Add Migration 006: Settings cleanup to remove orphaned records
- Remove orphaned settings records (accountDid=null)
- Clear legacy activeDid values from settings table
- Update documentation with current state analysis and compliance metrics
- Achieve 100% compliance with Active Pointer + Smart Deletion Pattern

Security Impact: COMPLETE - All critical vulnerabilities fixed
Migrations: 005 (constraint fix) + 006 (settings cleanup)
Pattern Compliance: 6/6 components (100%)

Performance: All migrations execute instantly with no delays
Architecture: Complete separation of identity management vs user settings

Author: Matthew Raymer
anomalist added 1 commit 2025-09-15 10:13:03 +00:00
anomalist added 1 commit 2025-09-16 03:19:22 +00:00
- Consolidate migrations 004, 005, and 006 into single 004_active_identity_management
- Remove redundant migrations 005 (constraint_fix) and 006 (settings_cleanup)
- Implement security-first approach with ON DELETE RESTRICT constraint from start
- Include comprehensive data migration from settings.activeDid to active_identity.activeDid
- Add proper cleanup of orphaned settings records and legacy activeDid values
- Update migrationService.ts validation logic to reflect consolidated structure
- Fix migration name references and enhance validation for hasBackedUpSeed column
- Reduce migration complexity from 3 separate operations to 1 atomic operation
- Maintain data integrity with foreign key constraints and performance indexes

Migration successfully tested on web platform with no data loss or corruption.
Active DID properly migrated: did:ethr:0xCA26A3959D32D2eB5459cE08203DbC4e62e79F5D

Files changed:
- src/db-sql/migration.ts: Consolidated 3 migrations into 1 (-46 lines)
- src/services/migrationService.ts: Updated validation logic (+13 lines)
anomalist added 1 commit 2025-09-16 08:21:03 +00:00
anomalist added 1 commit 2025-09-16 08:21:51 +00:00
jose added 1 commit 2025-09-16 12:13:55 +00:00
- Fix multi-statement SQL execution issue in Capacitor SQLite
- Add individual statement execution for migration 004_active_identity_management
- Implement automatic recovery for missing active_identity table
- Enhance migration system with better error handling and logging

Problem:
Migration 004 was marked as applied but active_identity table wasn't created
due to multi-statement SQL execution failing silently in Capacitor SQLite.

Solution:
- Extended Migration interface with optional statements array
- Modified migration execution to handle individual statements
- Added bootstrapping hook recovery for missing tables
- Enhanced logging for better debugging

Files changed:
- src/services/migrationService.ts: Enhanced migration execution logic
- src/db-sql/migration.ts: Added recovery mechanism and individual statements

This fix ensures the app automatically recovers from the current broken state
and prevents similar issues in future migrations.
trentlarson added 1 commit 2025-09-17 01:53:29 +00:00
trentlarson added 1 commit 2025-09-17 02:25:28 +00:00
trentlarson added 1 commit 2025-09-17 03:07:44 +00:00
anomalist added 1 commit 2025-09-17 06:33:12 +00:00
- Phase 1: Simplify Migration Definition 
  * Remove duplicate SQL definitions from migration 004
  * Eliminate recovery logic that could cause duplicate execution
  * Establish single source of truth for migration SQL

- Phase 2: Fix Database Result Handling 
  * Remove DatabaseResult type assumptions from migration code
  * Implement database-agnostic result extraction with extractSingleValue()
  * Normalize results from AbsurdSqlDatabaseService and CapacitorPlatformService

- Phase 3: Ensure Atomic Execution 
  * Remove individual statement execution logic
  * Execute migrations as single atomic SQL blocks only
  * Add explicit rollback instructions and failure cause logging
  * Ensure migration tracking is accurate

- Phase 4: Remove Excessive Debugging 
  * Move detailed logging to development-only mode
  * Preserve essential error logging for production
  * Optimize startup performance by reducing logging overhead
  * Maintain full debugging capability in development

Migration system now follows single-source, atomic execution principle
with improved performance and comprehensive error handling.

Timestamp: 2025-09-17 05:08:05 UTC
anomalist added 2 commits 2025-09-17 06:51:49 +00:00
- Single SQL source: Define MIG_004_SQL constant to eliminate duplicate SQL definitions
- Atomic execution: Add BEGIN IMMEDIATE/COMMIT/ROLLBACK around migration execution
- Name-only check: Skip migrations already recorded in migrations table
- Guarded operations: Replace table-wide cleanups with conditional UPDATE/DELETE

Changes:
- migration.ts: Extract migration 004 SQL into MIG_004_SQL constant
- migration.ts: Use guarded DELETE/UPDATE to prevent accidental data loss
- migrationService.ts: Wrap migration execution in explicit transactions
- migrationService.ts: Reorder checks to prioritize name-only skipping

Benefits:
- Prevents partial migration failures from corrupting database state
- Eliminates SQL duplication and maintenance overhead
- Maintains existing APIs and logging behavior
- Reduces risk of data loss during migration execution

Test results: All migration tests passing, ID generation working correctly
jose added 1 commit 2025-09-17 09:06:09 +00:00
- Remove explicit transaction wrapping in migration service that caused
  "cannot start a transaction within a transaction" errors
- Fix executeSet method call format to include both statement and values
  properties as required by Capacitor SQLite plugin
- Update CapacitorPlatformService to properly handle multi-statement SQL
  using executeSet for migration SQL blocks
- Ensure migration 004 (active_identity_management) executes atomically
  without nested transaction conflicts
- Remove unnecessary try/catch wrapper

Fixes iOS simulator migration failures where:
- Migration 004 would fail with transaction errors
- executeSet would fail with "Must provide a set as Array of {statement,values}"
- Database initialization would fail after migration errors

Tested on iOS simulator with successful migration completion and
active_identity table creation with proper data migration.
anomalist added 1 commit 2025-09-18 03:24:44 +00:00
- Remove isDevelopment environment checks and migrationLog variable
- Replace conditional logging with consistent logger.debug() calls
- Remove development-only validation restrictions
- Maintain all error handling and warning messages
- Let existing logger handle development mode behavior automatically

This simplifies the migration service logging while preserving all
functionality. The existing logger already handles development vs
production mode appropriately.
This branch is already included in the target branch. There is nothing to merge.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin active_did_redux:active_did_redux
git checkout active_did_redux
Sign in to join this conversation.
No Reviewers
No Label
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: trent_larson/crowd-funder-for-time-pwa#188