forked from jsnbuchanan/crowd-funder-for-time-pwa
- Create logical sub-folder classification for all documentation - Organize 91 migration files into component-specific folders - Separate user guides, build system, migration, and development docs - Maintain maximum 7 items per folder for easy navigation - Add comprehensive README and reorganization summary - Ensure all changes tracked in git with proper versioning Structure: - user-guides/ (3 items): user-facing documentation - build-system/ (3 items): core, platforms, automation - migration/ (6 items): assessments, testing, templates - development/ (4 items): tools and standards - architecture/, testing/, examples/ (ready for future docs) Total: 24 folders created, all within 7-item limits
307 lines
8.4 KiB
Markdown
307 lines
8.4 KiB
Markdown
# ESLint Rules for PlatformServiceMixin Migration
|
|
|
|
## Overview
|
|
Custom ESLint rules to enforce PlatformServiceMixin patterns and prevent regression to legacy patterns.
|
|
|
|
## Rules Configuration
|
|
|
|
Add to `.eslintrc.js`:
|
|
|
|
```javascript
|
|
module.exports = {
|
|
// ... existing config
|
|
rules: {
|
|
// ... existing rules
|
|
|
|
// Custom rules for PlatformServiceMixin migration
|
|
'timesafari/no-direct-database-util': 'error',
|
|
'timesafari/no-legacy-logging': 'error',
|
|
'timesafari/require-mixin-for-database': 'error',
|
|
'timesafari/no-direct-platform-service': 'warn',
|
|
'timesafari/prefer-mixin-methods': 'warn',
|
|
},
|
|
|
|
// Custom rules plugin
|
|
plugins: ['timesafari'],
|
|
}
|
|
```
|
|
|
|
## Custom Rules Implementation
|
|
|
|
Create `eslint-plugin-timesafari/index.js`:
|
|
|
|
```javascript
|
|
module.exports = {
|
|
rules: {
|
|
'no-direct-database-util': {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description: 'Disallow direct imports from databaseUtil',
|
|
category: 'Migration',
|
|
recommended: true,
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
ImportDeclaration(node) {
|
|
if (node.source.value.includes('databaseUtil')) {
|
|
context.report({
|
|
node,
|
|
message: 'Direct databaseUtil imports are deprecated. Use PlatformServiceMixin instead.',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
},
|
|
|
|
'no-legacy-logging': {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description: 'Disallow legacy logging methods',
|
|
category: 'Migration',
|
|
recommended: true,
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
ImportDeclaration(node) {
|
|
if (node.specifiers.some(spec => spec.imported?.name === 'logConsoleAndDb')) {
|
|
context.report({
|
|
node,
|
|
message: 'logConsoleAndDb is deprecated. Use PlatformServiceMixin $log methods instead.',
|
|
});
|
|
}
|
|
},
|
|
CallExpression(node) {
|
|
if (node.callee.name === 'logConsoleAndDb') {
|
|
context.report({
|
|
node,
|
|
message: 'logConsoleAndDb is deprecated. Use this.$logAndConsole() instead.',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
},
|
|
|
|
'require-mixin-for-database': {
|
|
meta: {
|
|
type: 'suggestion',
|
|
docs: {
|
|
description: 'Require PlatformServiceMixin for components using database operations',
|
|
category: 'Migration',
|
|
recommended: true,
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
let hasDbOperations = false;
|
|
let hasMixin = false;
|
|
|
|
return {
|
|
CallExpression(node) {
|
|
// Check for database operations
|
|
if (node.callee.property &&
|
|
['dbQuery', 'dbExec', 'dbGetOneRow'].includes(node.callee.property.name)) {
|
|
hasDbOperations = true;
|
|
}
|
|
},
|
|
Property(node) {
|
|
// Check for mixin usage
|
|
if (node.key.name === 'mixins' &&
|
|
node.value.elements?.some(el => el.name === 'PlatformServiceMixin')) {
|
|
hasMixin = true;
|
|
}
|
|
},
|
|
'Program:exit'() {
|
|
if (hasDbOperations && !hasMixin) {
|
|
context.report({
|
|
node: context.getSourceCode().ast,
|
|
message: 'Components using database operations should include PlatformServiceMixin.',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
},
|
|
|
|
'no-direct-platform-service': {
|
|
meta: {
|
|
type: 'suggestion',
|
|
docs: {
|
|
description: 'Discourage direct PlatformServiceFactory usage',
|
|
category: 'Migration',
|
|
recommended: false,
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
CallExpression(node) {
|
|
if (node.callee.object?.name === 'PlatformServiceFactory' &&
|
|
node.callee.property?.name === 'getInstance') {
|
|
context.report({
|
|
node,
|
|
message: 'Consider using PlatformServiceMixin methods instead of direct PlatformServiceFactory.',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
},
|
|
|
|
'prefer-mixin-methods': {
|
|
meta: {
|
|
type: 'suggestion',
|
|
docs: {
|
|
description: 'Prefer mixin convenience methods over direct database calls',
|
|
category: 'Migration',
|
|
recommended: false,
|
|
},
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
return {
|
|
CallExpression(node) {
|
|
// Check for patterns that could use mixin methods
|
|
if (node.callee.property?.name === 'dbQuery') {
|
|
const arg = node.arguments[0];
|
|
if (arg && arg.type === 'Literal') {
|
|
const sql = arg.value.toLowerCase();
|
|
if (sql.includes('select * from contacts')) {
|
|
context.report({
|
|
node,
|
|
message: 'Consider using this.$getAllContacts() instead of direct SQL.',
|
|
});
|
|
}
|
|
if (sql.includes('select * from settings')) {
|
|
context.report({
|
|
node,
|
|
message: 'Consider using this.$settings() instead of direct SQL.',
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
},
|
|
},
|
|
};
|
|
```
|
|
|
|
## Pre-commit Hook
|
|
|
|
Create `.pre-commit-config.yaml`:
|
|
|
|
```yaml
|
|
repos:
|
|
- repo: local
|
|
hooks:
|
|
- id: eslint-migration-check
|
|
name: ESLint Migration Check
|
|
entry: npx eslint --ext .vue --rule 'timesafari/no-direct-database-util: error'
|
|
language: system
|
|
files: \.vue$
|
|
|
|
- id: no-legacy-logging
|
|
name: No Legacy Logging
|
|
entry: bash -c 'if grep -r "logConsoleAndDb" src/ --include="*.vue" --include="*.ts"; then echo "Found legacy logging imports"; exit 1; fi'
|
|
language: system
|
|
pass_filenames: false
|
|
```
|
|
|
|
## Migration Validation Script
|
|
|
|
Create `scripts/validate-migration.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
echo "🔍 Validating PlatformServiceMixin migration..."
|
|
|
|
# Check for legacy patterns
|
|
echo "Checking for legacy databaseUtil imports..."
|
|
LEGACY_DB_IMPORTS=$(grep -r "import.*databaseUtil" src/ --include="*.vue" --include="*.ts" | wc -l)
|
|
echo "Found $LEGACY_DB_IMPORTS legacy databaseUtil imports"
|
|
|
|
echo "Checking for legacy logging imports..."
|
|
LEGACY_LOG_IMPORTS=$(grep -r "logConsoleAndDb" src/ --include="*.vue" --include="*.ts" | wc -l)
|
|
echo "Found $LEGACY_LOG_IMPORTS legacy logging imports"
|
|
|
|
# Check for mixin usage
|
|
echo "Checking for PlatformServiceMixin usage..."
|
|
MIXIN_USAGE=$(grep -r "PlatformServiceMixin" src/ --include="*.vue" | wc -l)
|
|
echo "Found $MIXIN_USAGE files using PlatformServiceMixin"
|
|
|
|
# Check for direct PlatformService usage
|
|
echo "Checking for direct PlatformService usage..."
|
|
DIRECT_PLATFORM=$(grep -r "PlatformServiceFactory.getInstance" src/ --include="*.vue" --include="*.ts" | wc -l)
|
|
echo "Found $DIRECT_PLATFORM direct PlatformService usages"
|
|
|
|
# Summary
|
|
echo ""
|
|
echo "📊 Migration Status Summary:"
|
|
echo "- Legacy databaseUtil imports: $LEGACY_DB_IMPORTS (should be 0)"
|
|
echo "- Legacy logging imports: $LEGACY_LOG_IMPORTS (should be 0)"
|
|
echo "- Mixin usage: $MIXIN_USAGE (should be high)"
|
|
echo "- Direct PlatformService usage: $DIRECT_PLATFORM (should be low)"
|
|
|
|
# Set exit code based on legacy usage
|
|
if [ $LEGACY_DB_IMPORTS -gt 0 ] || [ $LEGACY_LOG_IMPORTS -gt 0 ]; then
|
|
echo "❌ Migration validation failed - legacy patterns found"
|
|
exit 1
|
|
else
|
|
echo "✅ Migration validation passed - no legacy patterns found"
|
|
exit 0
|
|
fi
|
|
```
|
|
|
|
## Usage
|
|
|
|
1. **Install ESLint rules**:
|
|
```bash
|
|
npm install --save-dev eslint-plugin-timesafari
|
|
```
|
|
|
|
2. **Run validation**:
|
|
```bash
|
|
npm run lint
|
|
./scripts/validate-migration.sh
|
|
```
|
|
|
|
3. **Fix issues automatically**:
|
|
```bash
|
|
npm run lint -- --fix
|
|
```
|
|
|
|
## IDE Integration
|
|
|
|
### VS Code Settings
|
|
|
|
Add to `.vscode/settings.json`:
|
|
|
|
```json
|
|
{
|
|
"eslint.validate": [
|
|
"javascript",
|
|
"typescript",
|
|
"vue"
|
|
],
|
|
"eslint.options": {
|
|
"extensions": [".js", ".ts", ".vue"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### WebStorm Settings
|
|
|
|
1. Go to Settings → Languages & Frameworks → JavaScript → Code Quality Tools → ESLint
|
|
2. Enable ESLint
|
|
3. Set configuration file to `.eslintrc.js`
|
|
4. Add `.vue` to file extensions |