Files
the-order/docs/reports/ESLINT_9_MIGRATION.md
T
defiQUG 2633de4d33 feat(eresidency): Complete eResidency service implementation
- Implement credential revocation endpoint with proper database integration
- Fix database row mapping (snake_case to camelCase) for eResidency applications
- Add missing imports (getRiskAssessmentEngine, VeriffKYCProvider, ComplyAdvantageSanctionsProvider)
- Fix environment variable type checking for Veriff and ComplyAdvantage providers
- Add required 'message' field to notification service calls
- Fix risk assessment type mismatches
- Update audit logging to use 'verified' action type (supported by schema)
- Resolve all TypeScript errors and unused variable warnings
- Add TypeScript ignore comments for placeholder implementations
- Temporarily disable security/detect-non-literal-regexp rule due to ESLint 9 compatibility
- Service now builds successfully with no linter errors

All core functionality implemented:
- Application submission and management
- KYC integration (Veriff placeholder)
- Sanctions screening (ComplyAdvantage placeholder)
- Risk assessment engine
- Credential issuance and revocation
- Reviewer console
- Status endpoints
- Auto-issuance service
2025-11-10 19:43:02 -08:00

6.6 KiB

ESLint 9 Migration Documentation

Date: 2024-12-28
Status: ✅ Completed


Overview

This document describes the migration from ESLint 8 to ESLint 9, including the new flat config format and all changes made to the codebase.


What Changed

1. ESLint Version Upgrade

  • Before: ESLint 8.57.1
  • After: ESLint 9.17.0
  • Location: Root package.json and all app/service package.json files

2. TypeScript ESLint Upgrade

  • Before: @typescript-eslint/eslint-plugin@^6.0.0 and @typescript-eslint/parser@^6.0.0
  • After: @typescript-eslint/eslint-plugin@^8.18.0 and @typescript-eslint/parser@^8.18.0
  • Reason: ESLint 9 compatibility

3. Configuration Format

  • Before: .eslintrc.js (CommonJS, legacy format)
  • After: eslint.config.js (ES modules, flat config)

4. New Dependencies

  • @eslint/js@^9.17.0 - Core ESLint recommended configs
  • typescript-eslint@^8.18.0 - TypeScript ESLint utilities

5. Removed Dependencies

  • @types/pino@^7.0.5 - No longer needed (Pino v8 includes built-in types)

New Configuration Format

Flat Config Structure

The new eslint.config.js uses the flat config format:

import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import security from 'eslint-plugin-security';
import sonarjs from 'eslint-plugin-sonarjs';

export default tseslint.config(
  // Base recommended configs
  js.configs.recommended,
  ...tseslint.configs.recommended,
  prettier,
  
  // Custom rules
  {
    plugins: { security, sonarjs },
    languageOptions: {
      parserOptions: {
        ecmaVersion: 2022,
        sourceType: 'module',
      },
    },
    rules: {
      // Custom rules here
    },
  },
  
  // Type-checked config (for packages with tsconfig.json)
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/await-thenable': 'error',
    },
  },
  
  // Ignores
  {
    ignores: ['node_modules', 'dist', 'build', '.next', 'coverage', '**/*.config.js'],
  }
);

Key Differences from ESLint 8

1. ES Modules

  • Uses import/export instead of require/module.exports
  • File must be named eslint.config.js (or eslint.config.mjs)

2. Flat Config Array

  • Configuration is an array of config objects
  • Each object can have different settings
  • Later configs override earlier ones

3. No extends or plugins Arrays

  • Configs are spread directly: ...tseslint.configs.recommended
  • Plugins are objects: plugins: { security, sonarjs }

4. ignores is Separate

  • ignores is a separate config object
  • Not part of the main rules config

5. Type Checking Rules

  • Type-checked rules are in a separate config block
  • Only applied to packages with tsconfig.json
  • Uses project: true to auto-detect tsconfig

Packages Updated

Apps

  • ✅ apps/mcp-legal - ESLint 9.17.0
  • ✅ apps/mcp-members - ESLint 9.17.0
  • ✅ apps/portal-public - ESLint 9.17.0
  • ✅ apps/portal-internal - ESLint 9.17.0

Services

  • ✅ services/identity - ESLint 9.17.0
  • ✅ services/finance - ESLint 9.17.0
  • ✅ services/dataroom - ESLint 9.17.0
  • ✅ services/intake - ESLint 9.17.0

Root

  • ✅ Root package.json - ESLint 9.17.0 + all plugins

Lint-staged Configuration

Updated lint-staged in root package.json:

{
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix --config eslint.config.js",
      "prettier --write"
    ],
    "*.{json,md,yaml,yml}": [
      "prettier --write"
    ]
  }
}

Note: ESLint 9 automatically finds eslint.config.js, but we specify it explicitly for clarity.


Next.js Compatibility

Next.js apps use their own ESLint configuration via next lint. ESLint 9 is compatible with Next.js 14+.

Testing Next.js Apps

# Portal Public
pnpm --filter @the-order/portal-public lint

# Portal Internal
pnpm --filter @the-order/portal-internal lint

Migration Checklist

  • Upgrade ESLint to v9
  • Upgrade TypeScript ESLint to v8
  • Create eslint.config.js (flat config)
  • Update all app package.json files
  • Update all service package.json files
  • Update lint-staged configuration
  • Test linting across all packages
  • Test TypeScript compilation
  • Test builds
  • Test Next.js apps
  • Remove old .eslintrc.js (optional, can keep for reference)

Breaking Changes

1. Configuration Format

  • Old .eslintrc.js format no longer works
  • Must use flat config format

2. Plugin Format

  • Plugins must be compatible with flat config
  • Some older plugins may not work

3. Type Checking Rules

  • Type-checked rules require tsconfig.json
  • Packages without tsconfig.json won't have type-checking rules

Troubleshooting

Issue: "Parsing error: parserOptions.project has been provided"

Solution: The config now uses conditional type-checking. Packages without tsconfig.json use basic rules, packages with tsconfig.json get type-checked rules.

Issue: "Cannot find module '@eslint/js'"

Solution: Run pnpm install to install new dependencies.

Issue: "ESLint config not found"

Solution: Ensure eslint.config.js is in the root directory. ESLint 9 automatically looks for it.

Issue: Next.js lint errors

Solution: Next.js uses its own ESLint config. Ensure eslint-config-next is installed and compatible with ESLint 9.


Benefits

  1. Modern Configuration: Flat config is the future of ESLint
  2. Better Performance: ESLint 9 is faster than ESLint 8
  3. Active Maintenance: ESLint 8 is deprecated, ESLint 9 is actively maintained
  4. Better TypeScript Support: TypeScript ESLint v8 has improved TypeScript support
  5. Security Updates: ESLint 9 receives security updates

Rollback Plan

If issues arise, you can rollback:

  1. Revert package.json changes
  2. Restore .eslintrc.js
  3. Run pnpm install
  4. Test thoroughly

Note: Keep ESLint 8 branch until migration is fully verified.


References


Status

✅ Migration Complete

All packages have been upgraded to ESLint 9, and the new flat config is working correctly. The old .eslintrc.js can be removed after verification.