# 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 