forked from trent_larson/crowd-funder-for-time-pwa
docs: add active identity migration implementation and progress tracking
- Add comprehensive implementation overview document - Track Phase B component migration progress - Document migration strategy and architecture decisions - Include testing and validation procedures Provides complete documentation for the Active Identity table separation migration project.
This commit is contained in:
347
doc/active-identity-implementation-overview.md
Normal file
347
doc/active-identity-implementation-overview.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# 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: | `Promise<string \| null>` |
|
||||
| | | 'default') | |
|
||||
| `$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 | 2025-08-22 |
|
||||
| | | methods | |
|
||||
| Developer | Performance testing | Read/write performance meets | 2025-08-23 |
|
||||
| | | requirements | |
|
||||
| Developer | Phase C activation | Feature flag enables column | 2025-08-24 |
|
||||
| | | removal | |
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user