forked from jsnbuchanan/crowd-funder-for-time-pwa
- Add TODO annotation to MembersList.vue requiring human testing validation - Create migration templates for systematic component migration - Add best practices guide for PlatformServiceMixin usage - Create ESLint rules template for pattern enforcement - Add validation script to track migration progress - Document Phase 1 completion summary with current state Migration Infrastructure: - Component migration checklist template - Automated validation script (validate-migration.sh) - Best practices documentation - ESLint rules for preventing regression Status: MembersList.vue migration complete but requires human testing Next: Select next component for migration when ready to continue
216 lines
5.8 KiB
Markdown
216 lines
5.8 KiB
Markdown
# 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<Settings>) {
|
|
await databaseUtil.updateDefaultSettings(changes);
|
|
await logConsoleAndDb("Settings saved");
|
|
}
|
|
|
|
// ✅ AFTER - Mixin methods
|
|
async loadSettings() {
|
|
return await this.$settings();
|
|
}
|
|
|
|
async saveSettings(changes: Partial<Settings>) {
|
|
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 |