feat(db): implement active identity table separation #180

Open
anomalist wants to merge 24 commits from activedid_migration into master
Owner

Active Identity Implementation Overview

Author: Matthew Raymer
Date: 2025-08-21T13:40Z
Status: 🚧 IN PROGRESS - Implementation Complete, Testing Pending

Objective

Separate the activeDid field from the monolithic settings table into a
dedicated active_identity table to achieve:

  • Data normalization and reduced cache drift
  • Simplified identity management with dedicated table
  • Zero breaking API surface for existing components
  • Phased migration with rollback capability

Result

This document provides a comprehensive overview of the implemented Active
Identity table separation system, including architecture, migration strategy,
and component integration.

Use/Run

The implementation is ready for testing. Components can immediately use the new
façade methods while maintaining backward compatibility through dual-write
triggers.

Context & Scope

  • Audience: Developers working with identity management and database
    migrations
  • In scope: Active DID management, database schema evolution, Vue component
    integration
  • Out of scope: Multi-profile support beyond basic scope framework, complex
    identity hierarchies
  • Implementation: src/db/tables/activeIdentity.ts,
    src/utils/PlatformServiceMixin.ts
  • Migrations: src/db-sql/migration.ts (migrations 003 & 004)
  • Configuration: src/config/featureFlags.ts
  • Documentation: This document and progress tracking

Environment & Preconditions

  • Database: SQLite (Absurd-SQL for Web, Capacitor SQLite for Mobile)
  • Framework: Vue.js with PlatformServiceMixin
  • Migration System: Built-in migrationService.ts with automatic execution

Architecture / Process Overview

The Active Identity separation follows a phased migration pattern with
dual-write triggers to ensure zero downtime and backward compatibility.

flowchart TD
    A[Legacy State] --> B[Phase A: Dual-Write]
    B --> C[Phase B: Component Cutover]
    C --> D[Phase C: Legacy Cleanup]

    A --> A1[settings.activeDid]
    B --> B1[active_identity table]
    B --> B2[Dual-write trigger]
    B --> B3[Fallback support]
    C --> C1[Components use façade]
    C --> C2[Legacy fallback disabled]
    D --> D1[Drop activeDid column]
    D --> D2[Remove triggers]

Interfaces & Contracts

Database Schema

Table Purpose Key Fields Constraints
active_identity Store active DID per scope scope, active_did, Unique scope, FK to accounts.did
updated_at
settings User preferences (legacy) id, accountDid, apiServer, activeDid removed in Phase C
etc.

Service Façade API

Method Purpose Parameters Returns
$getActiveDid(scope?) Retrieve active DID scope (default: 'default') Promise<string | null>
$setActiveDid(did, scope?) Set active DID did, scope (default: Promise<void>
'default')
$switchActiveIdentity(did) Switch to different DID did Promise<void>
$getActiveIdentityScopes() Get available scopes None Promise<string[]>

Repro: End-to-End Procedure

1. Database Migration Execution

# Migrations run automatically on app startup
# Migration 003: Creates active_identity table
# Migration 004: Drops settings.activeDid column (Phase C)

2. Component Usage

// Before (legacy)
const activeDid = settings.activeDid || "";
await this.$saveSettings({ activeDid: newDid });

// After (new façade)
const activeDid = await this.$getActiveDid() || "";
await this.$setActiveDid(newDid);

3. Feature Flag Control

// Enable/disable migration phases
FLAGS.USE_ACTIVE_IDENTITY_ONLY = false;      // Allow legacy fallback
FLAGS.DROP_SETTINGS_ACTIVEDID = false;       // Keep legacy column
FLAGS.LOG_ACTIVE_ID_FALLBACK = true;         // Log fallback usage

What Works (Evidence)

  • Migration Infrastructure: Migrations 003 and 004 integrated into
    migrationService.ts
  • Table Creation: active_identity table schema with proper constraints
    and indexes
  • Service Façade: PlatformServiceMixin extended with all required methods
  • Feature Flags: Comprehensive flag system for controlling rollout phases
  • Dual-Write Support: One-way trigger from settings.activeDid
    active_identity.active_did
  • Validation: DID existence validation before setting as active
  • Error Handling: Comprehensive error handling with logging

What Doesn't (Evidence & Hypotheses)

  • Component Migration: No components yet updated to use new façade
    methods
  • Testing: No automated tests for new functionality
  • Performance Validation: No benchmarks for read/write performance
  • Cross-Platform Validation: Not tested on mobile platforms yet

Risks, Limits, Assumptions

Migration Risks

  • Data Loss: If migration fails mid-process, could lose active DID state
  • Rollback Complexity: Phase C (column drop) requires table rebuild, not
    easily reversible
  • Trigger Dependencies: Dual-write trigger could fail if active_identity
    table is corrupted

Performance Limits

  • Dual-Write Overhead: Each activeDid change triggers additional
    database operations
  • Fallback Queries: Legacy fallback requires additional database queries
  • Transaction Scope: Active DID changes wrapped in transactions for
    consistency

Security Boundaries

  • DID Validation: Only validates DID exists in accounts table, not
    ownership
  • Scope Isolation: No current scope separation enforcement beyond table
    constraints
  • Access Control: No row-level security on active_identity table

Next Steps

Owner Task Exit Criteria Target Date (UTC)
Developer Test migrations Migrations execute without errors 2025-08-21
Developer Update components All components use new façade methods 2025-08-22
Developer Performance testing Read/write performance meets requirements 2025-08-23
Developer Phase C activation Feature flag enables column removal 2025-08-24

References

Competence Hooks

  • Why this works: Phased migration with dual-write triggers ensures zero
    downtime while maintaining data consistency through foreign key constraints
    and validation
  • Common pitfalls: Forgetting to update components before enabling
    USE_ACTIVE_IDENTITY_ONLY, not testing rollback scenarios, ignoring
    cross-platform compatibility
  • Next skill unlock: Implement automated component migration using codemods
    and ESLint rules
  • Teach-back: Explain how the dual-write trigger prevents data divergence
    during the transition phase

Collaboration Hooks

  • Reviewers: Database team for migration logic, Vue team for component
    integration, DevOps for deployment strategy
  • Sign-off checklist: Migrations tested in staging, components updated,
    performance validated, rollback plan documented

Assumptions & Limits

  • Single User Focus: Current implementation assumes single-user mode with
    'default' scope
  • Vue Compatibility: Assumes vue-facing-decorator compatibility (needs
    validation)
  • Migration Timing: Assumes migrations run on app startup (automatic
    execution)
  • Platform Support: Assumes same behavior across Web (Absurd-SQL) and
    Mobile (Capacitor SQLite)

Implementation Details

Migration 003: Table Creation

Creates the active_identity table with:

  • Primary Key: Auto-incrementing ID
  • Scope Field: For future multi-profile support (currently 'default')
  • Active DID: Foreign key to accounts.did with CASCADE UPDATE
  • Timestamps: ISO format timestamps for audit trail
  • Indexes: Performance optimization for scope and DID lookups

Migration 004: Column Removal

Implements Phase C by:

  • Table Rebuild: Creates new settings table without activeDid column
  • Data Preservation: Copies all other data from legacy table
  • Index Recreation: Rebuilds necessary indexes
  • Trigger Cleanup: Removes dual-write triggers

Service Façade Implementation

The PlatformServiceMixin extension provides:

  • Dual-Read Logic: Prefers new table, falls back to legacy during
    transition
  • Dual-Write Logic: Updates both tables during Phase A/B
  • Validation: Ensures DID exists before setting as active
  • Transaction Safety: Wraps operations in database transactions
  • Error Handling: Comprehensive logging and error propagation

Feature Flag System

Controls migration phases through:

  • USE_ACTIVE_IDENTITY_ONLY: Disables legacy fallback reads
  • DROP_SETTINGS_ACTIVEDID: Enables Phase C column removal
  • LOG_ACTIVE_ID_FALLBACK: Logs when legacy fallback is used
  • ENABLE_ACTIVE_IDENTITY_MIGRATION: Master switch for migration
    system

Security Considerations

Data Validation

  • DID format validation (basic "did:" prefix check)
  • Foreign key constraints ensure referential integrity
  • Transaction wrapping prevents partial updates

Access Control

  • No row-level security implemented
  • Scope isolation framework in place for future use
  • Validation prevents setting non-existent DIDs as active

Audit Trail

  • Timestamps on all active identity changes
  • Logging of fallback usage and errors
  • Migration tracking through built-in system

Performance Characteristics

Read Operations

  • Primary Path: Single query to active_identity table
  • Fallback Path: Additional query to settings table (Phase A only)
  • Indexed Fields: Both scope and active_did are indexed

Write Operations

  • Dual-Write: Updates both tables during transition (Phase A/B)
  • Transaction Overhead: All operations wrapped in transactions
  • Trigger Execution: Additional database operations per update

Migration Impact

  • Table Creation: Minimal impact (runs once)
  • Column Removal: Moderate impact (table rebuild required)
  • Data Seeding: Depends on existing data volume

Testing Strategy

Unit Testing

  • Service façade method validation
  • Error handling and edge cases
  • Transaction rollback scenarios

Integration Testing

  • Migration execution and rollback
  • Cross-platform compatibility
  • Performance under load

End-to-End Testing

  • Component integration
  • User workflow validation
  • Migration scenarios

Deployment Considerations

Rollout Strategy

  • Phase A: Deploy with dual-write enabled
  • Phase B: Update components to use new methods
  • Phase C: Enable column removal (irreversible)

Rollback Plan

  • Phase A/B: Disable feature flags, revert to legacy methods
  • Phase C: Requires database restore (no automatic rollback)

Monitoring

  • Track fallback usage through logging
  • Monitor migration success rates
  • Alert on validation failures

Status: Implementation complete, ready for testing and component migration
Next Review: After initial testing and component updates
Maintainer: Development team

# Active Identity Implementation Overview **Author**: Matthew Raymer **Date**: 2025-08-21T13:40Z **Status**: 🚧 **IN PROGRESS** - Implementation Complete, Testing Pending ## Objective Separate the `activeDid` field from the monolithic `settings` table into a dedicated `active_identity` table to achieve: - **Data normalization** and reduced cache drift - **Simplified identity management** with dedicated table - **Zero breaking API surface** for existing components - **Phased migration** with rollback capability ## Result This document provides a comprehensive overview of the implemented Active Identity table separation system, including architecture, migration strategy, and component integration. ## Use/Run The implementation is ready for testing. Components can immediately use the new façade methods while maintaining backward compatibility through dual-write triggers. ## Context & Scope - **Audience**: Developers working with identity management and database migrations - **In scope**: Active DID management, database schema evolution, Vue component integration - **Out of scope**: Multi-profile support beyond basic scope framework, complex identity hierarchies ## Artifacts & Links - **Implementation**: `src/db/tables/activeIdentity.ts`, `src/utils/PlatformServiceMixin.ts` - **Migrations**: `src/db-sql/migration.ts` (migrations 003 & 004) - **Configuration**: `src/config/featureFlags.ts` - **Documentation**: This document and progress tracking ## Environment & Preconditions - **Database**: SQLite (Absurd-SQL for Web, Capacitor SQLite for Mobile) - **Framework**: Vue.js with PlatformServiceMixin - **Migration System**: Built-in migrationService.ts with automatic execution ## Architecture / Process Overview The Active Identity separation follows a **phased migration pattern** with dual-write triggers to ensure zero downtime and backward compatibility. ```mermaid flowchart TD A[Legacy State] --> B[Phase A: Dual-Write] B --> C[Phase B: Component Cutover] C --> D[Phase C: Legacy Cleanup] A --> A1[settings.activeDid] B --> B1[active_identity table] B --> B2[Dual-write trigger] B --> B3[Fallback support] C --> C1[Components use façade] C --> C2[Legacy fallback disabled] D --> D1[Drop activeDid column] D --> D2[Remove triggers] ``` ## Interfaces & Contracts ### Database Schema | Table | Purpose | Key Fields | Constraints | |-------|---------|------------|-------------| | `active_identity` | Store active DID per scope | `scope`, `active_did`, | Unique scope, FK to accounts.did | | | | `updated_at` | | | `settings` | User preferences (legacy) | `id`, `accountDid`, `apiServer`, | `activeDid` removed in Phase C | | | | etc. | | ### Service Façade API | Method | Purpose | Parameters | Returns | |--------|---------|------------|---------| | `$getActiveDid(scope?)` | Retrieve active DID | `scope` (default: 'default') | `Promise<string \| null>` | | `$setActiveDid(did, scope?)` | Set active DID | `did`, `scope` (default: | `Promise<void>` | | | | 'default') | | | `$switchActiveIdentity(did)` | Switch to different DID | `did` | `Promise<void>` | | `$getActiveIdentityScopes()` | Get available scopes | None | `Promise<string[]>` | ## Repro: End-to-End Procedure ### 1. Database Migration Execution ```bash # Migrations run automatically on app startup # Migration 003: Creates active_identity table # Migration 004: Drops settings.activeDid column (Phase C) ``` ### 2. Component Usage ```typescript // Before (legacy) const activeDid = settings.activeDid || ""; await this.$saveSettings({ activeDid: newDid }); // After (new façade) const activeDid = await this.$getActiveDid() || ""; await this.$setActiveDid(newDid); ``` ### 3. Feature Flag Control ```typescript // Enable/disable migration phases FLAGS.USE_ACTIVE_IDENTITY_ONLY = false; // Allow legacy fallback FLAGS.DROP_SETTINGS_ACTIVEDID = false; // Keep legacy column FLAGS.LOG_ACTIVE_ID_FALLBACK = true; // Log fallback usage ``` ## What Works (Evidence) - ✅ **Migration Infrastructure**: Migrations 003 and 004 integrated into `migrationService.ts` - ✅ **Table Creation**: `active_identity` table schema with proper constraints and indexes - ✅ **Service Façade**: PlatformServiceMixin extended with all required methods - ✅ **Feature Flags**: Comprehensive flag system for controlling rollout phases - ✅ **Dual-Write Support**: One-way trigger from `settings.activeDid` → `active_identity.active_did` - ✅ **Validation**: DID existence validation before setting as active - ✅ **Error Handling**: Comprehensive error handling with logging ## What Doesn't (Evidence & Hypotheses) - ❌ **Component Migration**: No components yet updated to use new façade methods - ❌ **Testing**: No automated tests for new functionality - ❌ **Performance Validation**: No benchmarks for read/write performance - ❌ **Cross-Platform Validation**: Not tested on mobile platforms yet ## Risks, Limits, Assumptions ### **Migration Risks** - **Data Loss**: If migration fails mid-process, could lose active DID state - **Rollback Complexity**: Phase C (column drop) requires table rebuild, not easily reversible - **Trigger Dependencies**: Dual-write trigger could fail if `active_identity` table is corrupted ### **Performance Limits** - **Dual-Write Overhead**: Each `activeDid` change triggers additional database operations - **Fallback Queries**: Legacy fallback requires additional database queries - **Transaction Scope**: Active DID changes wrapped in transactions for consistency ### **Security Boundaries** - **DID Validation**: Only validates DID exists in accounts table, not ownership - **Scope Isolation**: No current scope separation enforcement beyond table constraints - **Access Control**: No row-level security on `active_identity` table ## Next Steps | Owner | Task | Exit Criteria | Target Date (UTC) | |-------|------|---------------|-------------------| | Developer | Test migrations | Migrations execute without errors | 2025-08-21 | | Developer | Update components | All components use new façade methods | 2025-08-22 | | Developer | Performance testing | Read/write performance meets requirements | 2025-08-23 | | Developer | Phase C activation | Feature flag enables column removal | 2025-08-24 | ## References - [Database Migration Guide](../database-migration-guide.md) - [PlatformServiceMixin Documentation](../component-communication-guide.md) - [Feature Flags Configuration](../feature-flags.md) ## Competence Hooks - **Why this works**: Phased migration with dual-write triggers ensures zero downtime while maintaining data consistency through foreign key constraints and validation - **Common pitfalls**: Forgetting to update components before enabling `USE_ACTIVE_IDENTITY_ONLY`, not testing rollback scenarios, ignoring cross-platform compatibility - **Next skill unlock**: Implement automated component migration using codemods and ESLint rules - **Teach-back**: Explain how the dual-write trigger prevents data divergence during the transition phase ## Collaboration Hooks - **Reviewers**: Database team for migration logic, Vue team for component integration, DevOps for deployment strategy - **Sign-off checklist**: Migrations tested in staging, components updated, performance validated, rollback plan documented ## Assumptions & Limits - **Single User Focus**: Current implementation assumes single-user mode with 'default' scope - **Vue Compatibility**: Assumes `vue-facing-decorator` compatibility (needs validation) - **Migration Timing**: Assumes migrations run on app startup (automatic execution) - **Platform Support**: Assumes same behavior across Web (Absurd-SQL) and Mobile (Capacitor SQLite) ## Implementation Details ### **Migration 003: Table Creation** Creates the `active_identity` table with: - **Primary Key**: Auto-incrementing ID - **Scope Field**: For future multi-profile support (currently 'default') - **Active DID**: Foreign key to accounts.did with CASCADE UPDATE - **Timestamps**: ISO format timestamps for audit trail - **Indexes**: Performance optimization for scope and DID lookups ### **Migration 004: Column Removal** Implements Phase C by: - **Table Rebuild**: Creates new settings table without activeDid column - **Data Preservation**: Copies all other data from legacy table - **Index Recreation**: Rebuilds necessary indexes - **Trigger Cleanup**: Removes dual-write triggers ### **Service Façade Implementation** The PlatformServiceMixin extension provides: - **Dual-Read Logic**: Prefers new table, falls back to legacy during transition - **Dual-Write Logic**: Updates both tables during Phase A/B - **Validation**: Ensures DID exists before setting as active - **Transaction Safety**: Wraps operations in database transactions - **Error Handling**: Comprehensive logging and error propagation ### **Feature Flag System** Controls migration phases through: - **`USE_ACTIVE_IDENTITY_ONLY`**: Disables legacy fallback reads - **`DROP_SETTINGS_ACTIVEDID`**: Enables Phase C column removal - **`LOG_ACTIVE_ID_FALLBACK`**: Logs when legacy fallback is used - **`ENABLE_ACTIVE_IDENTITY_MIGRATION`**: Master switch for migration system ## Security Considerations ### **Data Validation** - DID format validation (basic "did:" prefix check) - Foreign key constraints ensure referential integrity - Transaction wrapping prevents partial updates ### **Access Control** - No row-level security implemented - Scope isolation framework in place for future use - Validation prevents setting non-existent DIDs as active ### **Audit Trail** - Timestamps on all active identity changes - Logging of fallback usage and errors - Migration tracking through built-in system ## Performance Characteristics ### **Read Operations** - **Primary Path**: Single query to `active_identity` table - **Fallback Path**: Additional query to `settings` table (Phase A only) - **Indexed Fields**: Both scope and active_did are indexed ### **Write Operations** - **Dual-Write**: Updates both tables during transition (Phase A/B) - **Transaction Overhead**: All operations wrapped in transactions - **Trigger Execution**: Additional database operations per update ### **Migration Impact** - **Table Creation**: Minimal impact (runs once) - **Column Removal**: Moderate impact (table rebuild required) - **Data Seeding**: Depends on existing data volume ## Testing Strategy ### **Unit Testing** - Service façade method validation - Error handling and edge cases - Transaction rollback scenarios ### **Integration Testing** - Migration execution and rollback - Cross-platform compatibility - Performance under load ### **End-to-End Testing** - Component integration - User workflow validation - Migration scenarios ## Deployment Considerations ### **Rollout Strategy** - **Phase A**: Deploy with dual-write enabled - **Phase B**: Update components to use new methods - **Phase C**: Enable column removal (irreversible) ### **Rollback Plan** - **Phase A/B**: Disable feature flags, revert to legacy methods - **Phase C**: Requires database restore (no automatic rollback) ### **Monitoring** - Track fallback usage through logging - Monitor migration success rates - Alert on validation failures --- **Status**: Implementation complete, ready for testing and component migration **Next Review**: After initial testing and component updates **Maintainer**: Development team
anomalist added 1 commit 1 month ago
b2e678dc2f feat(db): implement active identity table separation
anomalist added 10 commits 4 weeks ago
6013b8e167 feat(migration): migrate core identity views to Active Identity façade
4a63ff6838 feat(migration): extend Phase 1 with invite and certificate components
628469b1bb feat: Enable Phase C feature flag for Active Identity migration
211de332db feat: re-enable migration 004 for active identity phase c
c3534b54ae fix: update legacy utility functions to use active identity façade
e172faaaf2 fix: correct active identity fallback logic for phase c
09e6a7107a feat: migrate phase 1 critical identity components to active identity façade
17951d8cb8 docs: add active identity migration implementation and progress tracking
552196c18f test: add active identity migration end-to-end testing
453c791036 chore: remove dangerous migration scripts and clean up code formatting
anomalist added 6 commits 4 weeks ago
0277b65caa feat: migrate batch 3 components to active identity façade
bdac9e0da3 feat: migrate batch 4 components to active identity façade
80a76dadb7 feat: complete batch 5 components migration to active identity façade
c2f2ef4a09 feat: complete missing components from previous batches
63024f6e89 feat: migrate batch 7 missing components from previous batches
cf41665629 fix: migrate critical components causing test failures
trentlarson reviewed 4 weeks ago
- [Database Migration Guide](../database-migration-guide.md)
- [PlatformServiceMixin Documentation](../component-communication-guide.md)
- [Feature Flags Configuration](../feature-flags.md)
Poster
Owner

Note that these links point to the parent directory, but I think these would be in this directory.

Note that these links point to the parent directory, but I think these would be in this directory.
anomalist added 5 commits 4 weeks ago
4ea72162ec fix(active-identity): complete component migration to new Active Identity system
28c541e682 test(playwright): fix Active Identity migration test element selectors
135023d17b test(playwright): fix Active Identity migration test infrastructure and document findings
anomalist added 1 commit 4 weeks ago
7231ad18a6 refactor(active-identity): remove scope parameter and simplify to single-identity management
anomalist added 80 commits 4 weeks ago
c18a6b334f Added: native clipboard service
c3bd22fb83 Fix: iOS copy function
bed2c7106a Added: current user in ContactGiftingView
ec1a725832 Refactor: improve dialog logic and entity handling
a4528c5703 Refactor: eliminate "special" entity type and use DID-based logic
ca8d72e1c9 Fix: remove non-applicable IDs
eb44e7b51e Chore: convert "unnamed" into constant
9f976f011a Fix: account for new Export Data dialog
e3cc22245c fix(build): resolve web build script export error and add missing serve dependency
74c70c7fa0 fix(DIDView): validate DID format before processing URL parameters
4391cb2881 feat(harbor-pilot): add Playwright test investigation directive
7f5a64dceb UI: update HomeView onboard alert style
47a7b03cca Refactor: simplify RegistrationNotice component interface
25e79249dd Feat: integrate RegistrationNotice component into ProjectsView
8f5111d100 Refactor: unify dialog styles across components
a6a71628ec fix: resolve mapfile compatibility issue in build architecture guard
82ef4eba64 refactor: move README-BUILD-GUARD.md to doc/ folder
8fc9118d50 feat: Add automatic Android asset validation to prevent build failures
9f2ef24b2b feat(guard): enhance build architecture guard with Android protection and feedback system
4ba58145d0 feat: implement safe area insets for Android and add development tooling
ceefd454ce feat: add Minimalist Solution Principle cursor rule
57ea7f67c5 docs(readme): merge comprehensive project documentation and build guard
a224aced85 refactor(cursor-rules): restructure rules architecture with meta-rule system
c2aaf3a20d feat: Add documentation meta-rule system with educational focus
0c9ede9fc9 fix/deep-link-views: use proper #Content wrapper
4d89042997 Fix: re-organized dialog and notification z-indices
1893c2af1b fix: downgrade commitlint strict rules to warnings
cc50c38d13 Chore: simplify wording for person entities
427660d686 docs: enhance serve command documentation in BUILDING.md
This pull request has changes conflicting with the target branch.
src/db-sql/migration.ts
src/db/tables/activeIdentity.ts
src/libs/util.ts
src/views/ClaimAddRawView.vue
playwright.config-local.ts
src/components/OfferDialog.vue
src/components/OnboardingDialog.vue
src/views/AccountViewView.vue
src/views/ClaimCertificateView.vue
src/components/GiftedDialog.vue
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This pull request currently doesn't have any dependencies.

Loading…
There is no content yet.