{ "dimension": "readability", "prefix": "READ", "description": "Rules for detecting code readability issues including naming, complexity, and documentation", "rules": [ { "id": "long-function", "category": "function-length", "severity": "medium", "pattern": "function\\s+\\w+\\s*\\([^)]*\\)\\s*\\{|=>\\s*\\{", "patternType": "regex", "lineThreshold": 50, "description": "Functions longer than 50 lines are difficult to understand and maintain", "recommendation": "Break down into smaller, focused functions. Each function should do one thing well", "fixExample": "// Before - 100 line function\nfunction processData(data) {\n // validation\n // transformation\n // calculation\n // formatting\n // output\n}\n\n// After - composed functions\nfunction processData(data) {\n const validated = validateData(data);\n const transformed = transformData(validated);\n return formatOutput(calculateResults(transformed));\n}" }, { "id": "single-letter-variable", "category": "naming", "severity": "low", "pattern": "(?:const|let|var)\\s+[a-z]\\s*=", "patternType": "regex", "negativePatterns": ["for\\s*\\(", "\\[\\w,\\s*\\w\\]", "catch\\s*\\(e\\)"], "description": "Single letter variable names reduce code readability except in specific contexts (loop counters, catch)", "recommendation": "Use descriptive names that convey the variable's purpose", "fixExample": "// Before\nconst d = getData();\nconst r = d.map(x => x.value);\n\n// After\nconst userData = getData();\nconst userValues = userData.map(user => user.value);" }, { "id": "deep-nesting", "category": "complexity", "severity": "high", "pattern": "\\{[^}]*\\{[^}]*\\{[^}]*\\{", "patternType": "regex", "description": "Deeply nested code (4+ levels) is hard to follow and maintain", "recommendation": "Use early returns, extract functions, or flatten conditionals", "fixExample": "// Before\nif (user) {\n if (user.permissions) {\n if (user.permissions.canEdit) {\n if (document.isEditable) {\n // do work\n }\n }\n }\n}\n\n// After\nif (!user?.permissions?.canEdit) return;\nif (!document.isEditable) return;\n// do work" }, { "id": "magic-number", "category": "magic-value", "severity": "low", "pattern": "[^\\d]\\d{2,}[^\\d]|setTimeout\\s*\\([^,]+,\\s*\\d{4,}\\)", "patternType": "regex", "negativePatterns": ["const", "let", "enum", "0x", "100", "1000"], "description": "Magic numbers without explanation make code hard to understand", "recommendation": "Extract magic numbers into named constants with descriptive names", "fixExample": "// Before\nif (status === 403) { ... }\nsetTimeout(callback, 86400000);\n\n// After\nconst HTTP_FORBIDDEN = 403;\nconst ONE_DAY_MS = 24 * 60 * 60 * 1000;\nif (status === HTTP_FORBIDDEN) { ... }\nsetTimeout(callback, ONE_DAY_MS);" }, { "id": "commented-code", "category": "dead-code", "severity": "low", "pattern": "//\\s*(const|let|var|function|if|for|while|return)\\s+", "patternType": "regex", "description": "Commented-out code adds noise and should be removed. Use version control for history", "recommendation": "Remove commented code. If needed for reference, add a comment explaining why with a link to relevant commit/issue", "fixExample": "// Before\n// function oldImplementation() { ... }\n// const legacyConfig = {...};\n\n// After\n// See PR #123 for previous implementation\n// removed 2024-01-01" } ] }