You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							11 KiB
						
					
					
				PlatformServiceMixin Completion Plan: 2-Day Sprint
Overview
This document outlines the complete plan to finish PlatformServiceMixin implementation and migrate all 52 remaining files from databaseUtil imports to PlatformServiceMixin usage within 2 days.
Current Status
✅ PlatformServiceMixin - 95% Complete
- Core functionality: ✅ Implemented
 - Caching system: ✅ Implemented
 - Database methods: ✅ Implemented
 - Utility methods: ✅ Implemented
 - Type definitions: ✅ Implemented
 
⚠️ Remaining Issues
- Single circular dependency: 
memoryLogsimport from databaseUtil - Missing utility functions: 
generateInsertStatement,generateUpdateStatement - 52 files still importing databaseUtil
 
🎯 DAY 1: Complete PlatformServiceMixin (4-6 hours)
Phase 1: Remove Circular Dependency (30 minutes)
Step 1.1: Create Self-Contained memoryLogs
// In PlatformServiceMixin.ts - Replace line 50:
// Remove: import { memoryLogs } from "@/db/databaseUtil";
// Add self-contained implementation:
const _memoryLogs: string[] = [];
// Update $memoryLogs computed property:
$memoryLogs(): string[] {
  return _memoryLogs;
},
// Add method to append to memory logs:
$appendToMemoryLogs(message: string): void {
  _memoryLogs.push(`${new Date().toISOString()}: ${message}`);
  // Keep only last 1000 entries to prevent memory leaks
  if (_memoryLogs.length > 1000) {
    _memoryLogs.splice(0, _memoryLogs.length - 1000);
  }
},
Step 1.2: Update logger.ts
// In logger.ts - Replace memoryLogs usage:
// Remove: import { memoryLogs } from "@/db/databaseUtil";
// Add self-contained implementation:
const _memoryLogs: string[] = [];
export function appendToMemoryLogs(message: string): void {
  _memoryLogs.push(`${new Date().toISOString()}: ${message}`);
  if (_memoryLogs.length > 1000) {
    _memoryLogs.splice(0, _memoryLogs.length - 1000);
  }
}
export function getMemoryLogs(): string[] {
  return [..._memoryLogs];
}
Phase 2: Add Missing Utility Functions (1 hour)
Step 2.1: Add generateInsertStatement to PlatformServiceMixin
// Add to PlatformServiceMixin methods:
_generateInsertStatement(
  model: Record<string, unknown>,
  tableName: string,
): { sql: string; params: unknown[] } {
  const columns = Object.keys(model).filter((key) => model[key] !== undefined);
  const values = Object.values(model)
    .filter((value) => value !== undefined)
    .map((value) => {
      if (value === null || value === undefined) return null;
      if (typeof value === "object" && value !== null) {
        return JSON.stringify(value);
      }
      if (typeof value === "boolean") return value ? 1 : 0;
      return value;
    });
  const placeholders = values.map(() => "?").join(", ");
  const insertSql = `INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${placeholders})`;
  
  return { sql: insertSql, params: values };
},
Step 2.2: Add generateUpdateStatement to PlatformServiceMixin
// Add to PlatformServiceMixin methods:
_generateUpdateStatement(
  model: Record<string, unknown>,
  tableName: string,
  whereClause: string,
  whereParams: unknown[] = [],
): { sql: string; params: unknown[] } {
  const setClauses: string[] = [];
  const params: unknown[] = [];
  Object.entries(model).forEach(([key, value]) => {
    setClauses.push(`${key} = ?`);
    let convertedValue = value ?? null;
    if (convertedValue !== null) {
      if (typeof convertedValue === "object") {
        convertedValue = JSON.stringify(convertedValue);
      } else if (typeof convertedValue === "boolean") {
        convertedValue = convertedValue ? 1 : 0;
      }
    }
    params.push(convertedValue);
  });
  if (setClauses.length === 0) {
    throw new Error("No valid fields to update");
  }
  const sql = `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE ${whereClause}`;
  return { sql, params: [...params, ...whereParams] };
},
Step 2.3: Add Public Wrapper Methods
// Add to PlatformServiceMixin methods:
$generateInsertStatement(
  model: Record<string, unknown>,
  tableName: string,
): { sql: string; params: unknown[] } {
  return this._generateInsertStatement(model, tableName);
},
$generateUpdateStatement(
  model: Record<string, unknown>,
  tableName: string,
  whereClause: string,
  whereParams: unknown[] = [],
): { sql: string; params: unknown[] } {
  return this._generateUpdateStatement(model, tableName, whereClause, whereParams);
},
Phase 3: Update Type Definitions (30 minutes)
Step 3.1: Update IPlatformServiceMixin Interface
// Add to IPlatformServiceMixin interface:
$generateInsertStatement(
  model: Record<string, unknown>,
  tableName: string,
): { sql: string; params: unknown[] };
$generateUpdateStatement(
  model: Record<string, unknown>,
  tableName: string,
  whereClause: string,
  whereParams?: unknown[],
): { sql: string; params: unknown[] };
$appendToMemoryLogs(message: string): void;
Step 3.2: Update ComponentCustomProperties
// Add to ComponentCustomProperties interface:
$generateInsertStatement(
  model: Record<string, unknown>,
  tableName: string,
): { sql: string; params: unknown[] };
$generateUpdateStatement(
  model: Record<string, unknown>,
  tableName: string,
  whereClause: string,
  whereParams?: unknown[],
): { sql: string; params: unknown[] };
$appendToMemoryLogs(message: string): void;
Phase 4: Test PlatformServiceMixin (1 hour)
Step 4.1: Create Test Component
// Create test file: src/test/PlatformServiceMixin.test.ts
// Test all methods including new utility functions
Step 4.2: Run Linting and Type Checking
npm run lint
npx tsc --noEmit
🎯 DAY 2: Migrate All 52 Files (6-8 hours)
Migration Strategy
Priority Order:
- Views (25 files) - User-facing components
 - Components (15 files) - Reusable UI components
 - Services (8 files) - Business logic
 - Utils (4 files) - Utility functions
 
Migration Pattern for Each File:
Step 1: Add PlatformServiceMixin
// Add to component imports:
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
// Add to component definition:
export default class ComponentName extends Vue {
  // Add mixin
  mixins = [PlatformServiceMixin];
}
Step 2: Replace databaseUtil Imports
// Remove:
import { 
  generateInsertStatement, 
  generateUpdateStatement, 
  parseJsonField,
  mapColumnsToValues,
  logToDb,
  logConsoleAndDb 
} from "@/db/databaseUtil";
// Replace with mixin methods:
// generateInsertStatement → this.$generateInsertStatement
// generateUpdateStatement → this.$generateUpdateStatement  
// parseJsonField → this._parseJsonField
// mapColumnsToValues → this._mapColumnsToValues
// logToDb → this.$log
// logConsoleAndDb → this.$logAndConsole
Step 3: Update Method Calls
// Before:
const { sql, params } = generateInsertStatement(contact, 'contacts');
// After:
const { sql, params } = this.$generateInsertStatement(contact, 'contacts');
File Migration Checklist
Views (25 files) - Priority 1
- QuickActionBvcEndView.vue
 - ProjectsView.vue
 - ClaimReportCertificateView.vue
 - NewEditAccountView.vue
 - OnboardMeetingSetupView.vue
 - SearchAreaView.vue
 - TestView.vue
 - InviteOneView.vue
 - IdentitySwitcherView.vue
 - HelpNotificationsView.vue
 - StartView.vue
 - OfferDetailsView.vue
 - ContactEditView.vue
 - SharedPhotoView.vue
 - ContactQRScanShowView.vue
 - ContactGiftingView.vue
 - DiscoverView.vue
 - ImportAccountView.vue
 - ConfirmGiftView.vue
 - SeedBackupView.vue
 - [5 more view files]
 
Components (15 files) - Priority 2
- ActivityListItem.vue
 - AmountInput.vue
 - ChoiceButtonDialog.vue
 - ContactNameDialog.vue
 - DataExportSection.vue
 - EntityGrid.vue
 - EntityIcon.vue
 - EntitySelectionStep.vue
 - EntitySummaryButton.vue
 - FeedFilters.vue
 - GiftDetailsStep.vue
 - GiftedDialog.vue
 - GiftedPrompts.vue
 - HiddenDidDialog.vue
 - IconRenderer.vue
 
Services (8 files) - Priority 3
- api.ts
 - endorserServer.ts
 - partnerServer.ts
 - [5 more service files]
 
Utils (4 files) - Priority 4
- LogCollector.ts
 - [3 more util files]
 
Migration Tools
Automated Script for Common Patterns
#!/bin/bash
# migration-helper.sh
# Find all databaseUtil imports
echo "Files with databaseUtil imports:"
find src -name "*.vue" -o -name "*.ts" | xargs grep -l "import.*databaseUtil"
# Common replacement patterns
echo "Common replacement patterns:"
echo "generateInsertStatement → this.\$generateInsertStatement"
echo "generateUpdateStatement → this.\$generateUpdateStatement"
echo "parseJsonField → this._parseJsonField"
echo "mapColumnsToValues → this._mapColumnsToValues"
echo "logToDb → this.\$log"
echo "logConsoleAndDb → this.\$logAndConsole"
Validation Script
#!/bin/bash
# validate-migration.sh
# Check for remaining databaseUtil imports
echo "Checking for remaining databaseUtil imports..."
find src -name "*.vue" -o -name "*.ts" | xargs grep -l "import.*databaseUtil"
# Run linting
echo "Running linting..."
npm run lint
# Run type checking
echo "Running type checking..."
npx tsc --noEmit
echo "Migration validation complete!"
🎯 Success Criteria
Day 1 Success Criteria:
- PlatformServiceMixin has no circular dependencies
 - All utility functions implemented and tested
 - Type definitions complete and accurate
 - Linting passes with no errors
 - TypeScript compilation passes
 
Day 2 Success Criteria:
- 0 files importing databaseUtil
 - All 52 files migrated to PlatformServiceMixin
 - No runtime errors in migrated components
 - All tests passing
 - Performance maintained or improved
 
Overall Success Criteria:
- Complete elimination of databaseUtil dependency
 - PlatformServiceMixin is the single source of truth for database operations
 - Migration fence is fully implemented
 - Ready for Phase 3: Cleanup and Optimization
 
🚀 Post-Migration Benefits
- 80% reduction in database boilerplate code
 - Centralized caching for improved performance
 - Type-safe database operations
 - Eliminated circular dependencies
 - Simplified testing with mockable mixin
 - Consistent error handling across all components
 - Ready for SQLite-only mode
 
📋 Daily Progress Tracking
Day 1 Progress:
- Phase 1: Circular dependency resolved
 - Phase 2: Utility functions added
 - Phase 3: Type definitions updated
 - Phase 4: Testing completed
 
Day 2 Progress:
- Views migrated (0/25)
 - Components migrated (0/15)
 - Services migrated (0/8)
 - Utils migrated (0/4)
 - Validation completed
 
🆘 Contingency Plans
If Day 1 Takes Longer:
- Focus on core functionality first
 - Defer advanced utility functions to Day 2
 - Prioritize circular dependency resolution
 
If Day 2 Takes Longer:
- Focus on high-impact views first
 - Batch similar components together
 - Use automated scripts for common patterns
 
If Issues Arise:
- Document specific problems
 - Create targeted fixes
 - Maintain backward compatibility during transition