# 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}`); } ``` ## Notification Migration (Additional Step) If component uses `this.$notify()` calls, also migrate to notification helpers: ### Import and Setup ```typescript // Add imports import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify"; import { NOTIFY_CONTACT_LOADING_ISSUE, NOTIFY_FEED_LOADING_ISSUE, // Add other constants as needed } from "@/constants/notifications"; // Add property notify!: ReturnType; // Initialize in created() created() { this.notify = createNotifyHelpers(this.$notify); } ``` ### Replace Notification Calls ```typescript // ❌ BEFORE this.$notify({ group: "alert", type: "warning", title: "Warning", text: "Something went wrong" }, 5000); // ✅ AFTER - Use constants for reusable messages this.notify.warning(NOTIFY_CONTACT_LOADING_ISSUE.message, TIMEOUTS.LONG); // ✅ AFTER - Literal strings for dynamic content this.notify.error(userMessage || "Fallback error message", TIMEOUTS.LONG); ``` ### Common Notification Patterns - Warning: `this.notify.warning(NOTIFY_CONSTANT.message, TIMEOUTS.LONG)` - Error: `this.notify.error(NOTIFY_CONSTANT.message, TIMEOUTS.LONG)` - Success: `this.notify.success(NOTIFY_CONSTANT.message, TIMEOUTS.STANDARD)` - Toast: `this.notify.toast(title, message, TIMEOUTS.SHORT)` - Confirm: `this.notify.confirm(message, onYes)` - Standard patterns: `this.notify.confirmationSubmitted()`, `this.notify.sent()`, etc. ### Notification Constants Guidelines - **Use constants** for static, reusable messages (defined in `src/constants/notifications.ts`) - **Use literal strings** for dynamic messages with variables - **Add new constants** to `notifications.ts` for new reusable messages ## After Migration Checklist ⚠️ **CRITICAL**: Use `docs/migration-templates/COMPLETE_MIGRATION_CHECKLIST.md` for comprehensive validation ### Phase 1: Database Migration - [ ] 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`) ### Phase 2: SQL Abstraction (if applicable) - [ ] All raw SQL queries replaced with service methods - [ ] Contact operations use `$getContact()`, `$deleteContact()`, `$updateContact()` - [ ] Settings operations use `$accountSettings()`, `$saveSettings()` - [ ] **NO raw SQL queries remain** (`SELECT`, `INSERT`, `UPDATE`, `DELETE`) ### Phase 3: Notification Migration (if applicable) - [ ] `createNotifyHelpers` imported and initialized - [ ] `notify!` property declared and created in `created()` - [ ] **All `this.$notify()` calls replaced with helper methods** - [ ] **Hardcoded timeouts replaced with `TIMEOUTS` constants** - [ ] **Static messages use notification constants from `@/constants/notifications`** - [ ] **Dynamic messages use literal strings appropriately** ### Final Validation - [ ] Error handling includes component name context - [ ] Component compiles without TypeScript errors - [ ] Component functionality works as expected - [ ] `scripts/validate-migration.sh` shows "Technically Compliant" - [ ] `scripts/validate-notification-completeness.sh` shows as complete ### Validation Commands ```bash # Check overall migration status scripts/validate-migration.sh # Check notification migration completeness scripts/validate-notification-completeness.sh # Check for compilation errors npm run lint-fix ``` ## 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 ## Phase 4: Testing and Validation ### 4.1 Multi-Platform Testing Requirements **ALL MIGRATIONS MUST BE TESTED ON ALL SUPPORTED PLATFORMS:** #### Web Platform Testing (Required) - [ ] Test in Chrome/Chromium (primary browser) - [ ] Test in Firefox (secondary browser) - [ ] Test in Safari (if applicable) - [ ] Verify PWA functionality works correctly - [ ] Test responsive design on different screen sizes #### Desktop Platform Testing (Required) - [ ] Test Electron app functionality - [ ] Verify desktop-specific features work - [ ] Test file system access (if applicable) - [ ] Verify native desktop integrations #### Mobile Platform Testing (Required) - [ ] Test iOS app via Capacitor - [ ] Test Android app via Capacitor - [ ] Verify mobile-specific features (camera, contacts, etc.) - [ ] Test deep linking functionality - [ ] Verify push notifications work ### 4.2 Functional Testing Per Platform For each platform, test these core scenarios: #### Database Operations - [ ] Create/Read/Update/Delete operations work - [ ] Data persistence across app restarts - [ ] Database migration handling (if applicable) #### Logging and Error Handling - [ ] Errors are logged correctly to console - [ ] Errors are stored in database logs - [ ] Error messages display appropriately to users - [ ] Network errors are handled gracefully #### User Interface - [ ] All buttons and interactions work - [ ] Loading states display correctly - [ ] Error states display appropriately - [ ] Responsive design works on platform ### 4.3 Platform-Specific Testing Notes #### Web Platform - Test offline/online scenarios - Verify IndexedDB storage works - Test service worker functionality - Check browser developer tools for errors #### Desktop Platform - Test native menu integrations - Verify file system permissions - Test auto-updater functionality - Check Electron developer tools #### Mobile Platform - Test device permissions (camera, storage, etc.) - Verify app store compliance - Test background/foreground transitions - Check native debugging tools ### 4.4 Sign-Off Requirements **MIGRATION IS NOT COMPLETE UNTIL ALL PLATFORMS ARE TESTED AND SIGNED OFF:** ```markdown ## Testing Sign-Off Checklist ### Web Platform ✅/❌ - [ ] Chrome: Tested by [Name] on [Date] - [ ] Firefox: Tested by [Name] on [Date] - [ ] Safari: Tested by [Name] on [Date] - [ ] Notes: [Any platform-specific issues or observations] ### Desktop Platform ✅/❌ - [ ] Windows: Tested by [Name] on [Date] - [ ] macOS: Tested by [Name] on [Date] - [ ] Linux: Tested by [Name] on [Date] - [ ] Notes: [Any platform-specific issues or observations] ### Mobile Platform ✅/❌ - [ ] iOS: Tested by [Name] on [Date] - [ ] Android: Tested by [Name] on [Date] - [ ] Notes: [Any platform-specific issues or observations] ### Final Sign-Off - [ ] All platforms tested and working - [ ] No regressions identified - [ ] Performance is acceptable - [ ] Migration completed by: [Name] on [Date] ```