# 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**

1. **Single circular dependency**: `memoryLogs` import from databaseUtil
2. **Missing utility functions**: `generateInsertStatement`, `generateUpdateStatement`
3. **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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```typescript
// Create test file: src/test/PlatformServiceMixin.test.ts
// Test all methods including new utility functions
```

#### **Step 4.2: Run Linting and Type Checking**

```bash
npm run lint
npx tsc --noEmit
```

---

## 🎯 **DAY 2: Migrate All 52 Files (6-8 hours)**

### **Migration Strategy**

#### **Priority Order:**

1. **Views** (25 files) - User-facing components
2. **Components** (15 files) - Reusable UI components  
3. **Services** (8 files) - Business logic
4. **Utils** (4 files) - Utility functions

#### **Migration Pattern for Each File:**

**Step 1: Add PlatformServiceMixin**

```typescript
// 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**

```typescript
// 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**

```typescript
// 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**

```bash
#!/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**

```bash
#!/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**

1. **80% reduction** in database boilerplate code
2. **Centralized caching** for improved performance
3. **Type-safe** database operations
4. **Eliminated circular dependencies**
5. **Simplified testing** with mockable mixin
6. **Consistent error handling** across all components
7. **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
