Skip to content

Enforce Alphabetical Ordering Standards Across Codebase #369

Description

@jjalan

Problem Statement

Inconsistent ordering of code elements makes the codebase harder to navigate and increases merge conflicts. We need to enforce alphabetical ordering for:

  • Import statements (with React first in TypeScript)
  • Function parameters and arguments
  • Class properties
  • Enum values
  • Dataclass fields

Current State

Frontend (TypeScript)

  • Import statements are randomly ordered
  • React imports not consistently placed first
  • Interface/type properties in random order
  • Enum values not alphabetically sorted

Backend (Python)

  • Dataclass fields in random order
  • Function parameters not consistently ordered
  • Class attributes not alphabetically sorted
  • No tooling to enforce ordering

Examples

TypeScript Issues

// ❌ Current State - Unordered
import { Link } from 'react-router-dom';
import { Button } from './components';
import React from 'react';
import axios from 'axios';

interface UserData {
  email: string;
  userId: string;
  firstName: string;
  lastName: string;
  age: number;
}

enum UserRole {
  ADMIN = 'admin',
  USER = 'user',
  MODERATOR = 'moderator',
}

function createUser(email: string, name: string, age: number) { }
// ✅ Expected - Ordered
import React from 'react';

import axios from 'axios';
import { Link } from 'react-router-dom';

import { Button } from './components';

interface UserData {
  age: number;
  email: string;
  firstName: string;
  lastName: string;
  userId: string;
}

enum UserRole {
  ADMIN = 'admin',
  MODERATOR = 'moderator',
  USER = 'user',
}

function createUser(age: number, email: string, name: string) { }

Python Issues

# ❌ Current State - Unordered
@dataclass(frozen=True)
class User:
    email: str
    user_id: str
    first_name: str
    last_name: str
    age: int

def create_user(email: str, name: str, age: int, role: str):
    pass
# ✅ Expected - Ordered
@dataclass(frozen=True)
class User:
    age: int
    email: str
    first_name: str
    last_name: str
    user_id: str

def create_user(age: int, email: str, name: str, role: str):
    pass

Proposed Solution

1. Frontend - ESLint Configuration

{
  "plugins": ["simple-import-sort", "sort-keys-fix", "@typescript-eslint"],
  "rules": {
    // Import ordering with React first
    "simple-import-sort/imports": ["error", {
      "groups": [
        ["^react", "^@?\\w"],
        ["^(@|@@)/"],
        ["^frontend/"],
        ["^\\.\\.(?!/?$)", "^\\.\\./?$"],
        ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
        ["^.+\\.?(css|scss)$"]
      ]
    }],
    "simple-import-sort/exports": "error",
    
    // Sort object keys
    "sort-keys-fix/sort-keys-fix": ["error", "asc", {
      "natural": true,
      "caseSensitive": false
    }],
    
    // Sort TypeScript members
    "@typescript-eslint/member-ordering": ["error", {
      "default": {
        "memberTypes": "never",
        "order": "alphabetically"
      }
    }],
    
    // Sort type properties
    "@typescript-eslint/sort-type-constituents": "error"
  }
}

2. Backend - Custom Pylint Plugin

# pylint_plugins/alphabetical_ordering.py
class AlphabeticalOrderingChecker(BaseChecker):
    """Check for alphabetical ordering in various constructs"""
    
    msgs = {
        'C0401': (
            'Class attributes are not in alphabetical order. Expected: %s',
            'unordered-class-attributes',
            'Class attributes should be in alphabetical order'
        ),
        'C0402': (
            'Dataclass fields are not in alphabetical order. Expected: %s',
            'unordered-dataclass-fields',
            'Dataclass fields should be in alphabetical order'
        ),
        'C0403': (
            'Function parameters are not in alphabetical order. Expected: %s',
            'unordered-function-params',
            'Function parameters should be in alphabetical order (except self, cls)'
        ),
        'C0404': (
            'Enum values are not in alphabetical order. Expected: %s',
            'unordered-enum-values',
            'Enum values should be in alphabetical order'
        )
    }
    
    def visit_classdef(self, node):
        """Check dataclass fields and enum values"""
        if self._is_dataclass(node):
            self._check_dataclass_fields(node)
        elif self._is_enum(node):
            self._check_enum_values(node)
        else:
            self._check_class_attributes(node)
    
    def visit_functiondef(self, node):
        """Check function parameter ordering"""
        params = [arg.name for arg in node.args.args 
                  if arg.name not in ('self', 'cls')]
        sorted_params = sorted(params)
        
        if params != sorted_params:
            self.add_message(
                'unordered-function-params',
                node=node,
                args=(', '.join(sorted_params),)
            )

3. Auto-fix Scripts

# scripts/fix_alphabetical_ordering.py
"""Auto-fix alphabetical ordering issues"""

def fix_typescript_files():
    """Run ESLint with auto-fix"""
    subprocess.run(['npm', 'run', 'lint:ts', '--', '--fix'])

def fix_python_dataclasses():
    """Parse and reorder dataclass fields"""
    # Implementation using AST manipulation

def fix_python_functions():
    """Reorder function parameters maintaining logic"""
    # Complex implementation considering default values

4. Pre-commit Configuration

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: check-alphabetical-order-py
        name: Check Python alphabetical ordering
        entry: pylint --load-plugins=pylint_plugins.alphabetical_ordering
        language: system
        types: [python]
      
      - id: check-alphabetical-order-ts
        name: Check TypeScript alphabetical ordering
        entry: npm run lint:ts
        language: system
        types: [typescript, javascript]

Implementation Plan

Frontend Setup

  1. Install ESLint plugins: npm install -D eslint-plugin-simple-import-sort eslint-plugin-sort-keys-fix
  2. Update .eslintrc with sorting rules
  3. Run npm run lint:ts -- --fix to auto-fix TypeScript files
  4. Commit the mass update

Backend Setup

  1. Write minimal Pylint plugin for alphabetical ordering (focus on dataclasses only)
  2. Run analysis to find violations
  3. Decide: manual fix now or add to tech debt backlog

Enforcement

  1. Enable rules in pre-commit hooks
  2. Add to CI/CD with warnings first (not blocking)
  3. Schedule team discussion about making it blocking

Success Criteria

  • All new code follows alphabetical ordering
  • Auto-fix available for TypeScript (ESLint --fix)
  • Python linting shows violations (manual fix)
  • Team agrees on enforcement timeline

Benefits

  1. Consistency: Predictable code structure
  2. Reduced Conflicts: Less chance of merge conflicts
  3. Easier Navigation: Find properties/parameters quickly
  4. Code Reviews: Easier to spot missing items
  5. Maintainability: Clear structure for additions

Exceptions

  • Constructor parameters may follow logical order
  • React lifecycle methods maintain standard order
  • Python __init__ parameters may follow logical grouping

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions