# Component Migration Template ## Overview This template provides step-by-step instructions for migrating Vue components from legacy patterns to PlatformServiceMixin. ## Before Migration Checklist - [ ] Component uses `import * as databaseUtil` - [ ] Component uses `import { logConsoleAndDb }` - [ ] Component has direct `PlatformServiceFactory.getInstance()` calls - [ ] Component has manual error handling for database operations - [ ] Component has verbose SQL result processing ## Step-by-Step Migration ### Step 1: Update Imports ```typescript // ❌ BEFORE - Legacy imports import * as databaseUtil from "../db/databaseUtil"; import { logConsoleAndDb } from "../db/databaseUtil"; import { PlatformServiceFactory } from "../services/PlatformServiceFactory"; // ✅ AFTER - Clean imports import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin"; import { Contact } from "@/db/tables/contacts"; import { Settings } from "@/db/tables/settings"; ``` ### Step 2: Add Mixin to Component ```typescript // ❌ BEFORE - No mixin @Component({ components: { /* ... */ } }) export default class MyComponent extends Vue { // ... } // ✅ AFTER - With mixin @Component({ components: { /* ... */ } }) export default class MyComponent extends Vue { mixins: [PlatformServiceMixin], // ... } ``` ### Step 3: Replace Database Operations ```typescript // ❌ BEFORE - Legacy database access async loadContacts() { try { const platformService = PlatformServiceFactory.getInstance(); const result = await platformService.dbQuery("SELECT * FROM contacts"); const contacts = databaseUtil.mapQueryResultToValues(result); await logConsoleAndDb("Contacts loaded successfully"); return contacts; } catch (error) { await logConsoleAndDb("Error loading contacts: " + error, true); throw error; } } // ✅ AFTER - Mixin methods async loadContacts() { try { const contacts = await this.$getAllContacts(); await this.$log("Contacts loaded successfully"); return contacts; } catch (error) { await this.$logError(`[${this.$options.name}] Error loading contacts: ${error}`); throw error; } } ``` ### Step 4: Replace Settings Operations ```typescript // ❌ BEFORE - Legacy settings access async loadSettings() { const settingsRow = await databaseUtil.retrieveSettingsForActiveAccount(); const settings = settingsRow || {}; return settings; } async saveSettings(changes: Partial) { await databaseUtil.updateDefaultSettings(changes); await logConsoleAndDb("Settings saved"); } // ✅ AFTER - Mixin methods async loadSettings() { return await this.$settings(); } async saveSettings(changes: Partial) { await this.$saveSettings(changes); await this.$log("Settings saved"); } ``` ### Step 5: Replace Logging Operations ```typescript // ❌ BEFORE - Legacy logging try { // operation } catch (error) { console.error("Error occurred:", error); await logConsoleAndDb("Error: " + error, true); } // ✅ AFTER - Mixin logging try { // operation } catch (error) { await this.$logError(`[${this.$options.name}] Error: ${error}`); } ``` ## Common Migration Patterns ### Pattern 1: Database Query + Result Processing ```typescript // ❌ BEFORE const platformService = PlatformServiceFactory.getInstance(); const result = await platformService.dbQuery(sql, params); const processed = databaseUtil.mapQueryResultToValues(result); // ✅ AFTER const processed = await this.$query(sql, params); ``` ### Pattern 2: Settings Retrieval ```typescript // ❌ BEFORE const settingsRow = await databaseUtil.retrieveSettingsForActiveAccount(); const value = settingsRow?.[field] || defaultValue; // ✅ AFTER const settings = await this.$settings(); const value = settings[field] || defaultValue; ``` ### Pattern 3: Contact Operations ```typescript // ❌ BEFORE const platformService = PlatformServiceFactory.getInstance(); const contacts = await platformService.dbQuery("SELECT * FROM contacts"); const mappedContacts = databaseUtil.mapQueryResultToValues(contacts); // ✅ AFTER const contacts = await this.$getAllContacts(); ``` ### Pattern 4: Error Handling ```typescript // ❌ BEFORE try { // operation } catch (error) { console.error("[MyComponent] Error:", error); await databaseUtil.logToDb("Error: " + error, "error"); } // ✅ AFTER try { // operation } catch (error) { await this.$logError(`[${this.$options.name}] Error: ${error}`); } ``` ## After Migration Checklist - [ ] All `databaseUtil` imports removed - [ ] All `logConsoleAndDb` imports removed - [ ] All direct `PlatformServiceFactory.getInstance()` calls removed - [ ] Component includes `PlatformServiceMixin` in mixins array - [ ] Database operations use mixin methods (`$db`, `$query`, `$getAllContacts`, etc.) - [ ] Settings operations use mixin methods (`$settings`, `$saveSettings`) - [ ] Logging uses mixin methods (`$log`, `$logError`, `$logAndConsole`) - [ ] Error handling includes component name context - [ ] Component compiles without TypeScript errors - [ ] Component functionality works as expected ## Testing Migration 1. **Compile Check**: `npm run build` should complete without errors 2. **Runtime Check**: Component should load and function normally 3. **Logging Check**: Verify logs appear in console and database 4. **Error Handling Check**: Verify errors are properly logged and handled ## Troubleshooting ### Common Issues 1. **Missing Mixin Methods**: Ensure component properly extends PlatformServiceMixin 2. **TypeScript Errors**: Check that all types are properly imported 3. **Runtime Errors**: Verify all async operations are properly awaited 4. **Missing Context**: Add component name to error messages for better debugging ### Performance Considerations - Mixin methods include caching for frequently accessed data - Database operations are queued and optimized - Error logging includes proper context and formatting