{
"event": "PreToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_constants.py",
"content": "#!\/usr\/bin\/env python3\n\"\"\"\nConstants Rules (W7) - Magic Number Warnings.\n\nRegeln für benannte Konstanten: Warnt bei Magic Numbers,\nempfiehlt die Verwendung von Domain\\Constants.\n\"\"\"\n\nimport re\nfrom typing import List\nfrom .rule_base import Rule, COMMON_NUMBERS\n\n\n# =============================================================================\n# CONSTANTS ALLOWLIST\n# =============================================================================\n\nCONSTANTS_ALLOWLIST = [\n \"\/Constants.php\",\n \"\/constants.py\",\n \"\/config.py\",\n \"\/Config.php\",\n \"\/config\/\",\n \"CodeQualityChecker.php\",\n]\n\n# Suspicious magic numbers that should be named\nSUSPICIOUS_MAGIC = {\n '100': 'DEFAULT_LIMIT or PERCENT_FULL',\n '1000': 'BATCH_LIMIT or MS_PER_SECOND',\n '60': 'SECONDS_PER_MINUTE',\n '24': 'HOURS_PER_DAY',\n '365': 'DAYS_PER_YEAR',\n '30': 'HTTP_TIMEOUT',\n '120': 'LLM_TIMEOUT',\n}\n\n\n# =============================================================================\n# W7: CONSTANTS - Named Constants\n# =============================================================================\n\nclass W7_1_MagicNumbers(Rule):\n \"\"\"W7.1: Magic Numbers sollten benannte Konstanten sein.\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=CONSTANTS_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Nur PHP und Python\n if not (file_path.endswith('.php') or file_path.endswith('.py')):\n return []\n\n warnings = []\n lines = content.split('\\n')\n\n for line_num, line in enumerate(lines, 1):\n # Skip Kommentare\n stripped = line.strip()\n if stripped.startswith('\/\/') or stripped.startswith('#') or stripped.startswith('*'):\n continue\n\n # Skip const\/define\/Constants\n if re.search(r'\\bconst\\b|\\bdefine\\b|Constants::|from constants import', line, re.IGNORECASE):\n continue\n\n # Prüfe auf verdächtige Magic Numbers\n for magic, suggestion in SUSPICIOUS_MAGIC.items():\n # Nur alleinstehende Zahlen (nicht in größeren Zahlen)\n pattern = rf'(?<![0-9]){magic}(?![0-9])'\n if re.search(pattern, line):\n # Nicht warnen wenn bereits Constants verwendet wird\n if 'Constants::' in line or 'CONSTANTS' in line.upper():\n continue\n\n warnings.append(\n f\"W7.1: Magic number {magic} at line {line_num}. \"\n f\"Consider using Constants::{suggestion}\"\n )\n break # Eine Warnung pro Zeile reicht\n\n # Maximal 5 Warnungen pro Datei\n return warnings[:5]\n\n\nclass W7_2_MissingConstantsImport(Rule):\n \"\"\"W7.2: Constants Import fehlt aber Magic Numbers verwendet.\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=CONSTANTS_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n if file_path.endswith('.php'):\n # PHP: Prüfe auf use Domain\\Constants\n has_import = 'use Domain\\\\Constants' in content or 'Domain\\\\Constants::' in content\n\n if not has_import:\n # Hat die Datei verdächtige Magic Numbers?\n for magic in ['3600', '86400', '1000']:\n if re.search(rf'\\b{magic}\\b', content):\n return [\n f\"W7.2: File uses magic number {magic} but missing 'use Domain\\\\Constants'. \"\n \"Add import and use named constants.\"\n ]\n\n elif file_path.endswith('.py'):\n # Python: Prüfe auf from constants import\n has_import = 'from constants import' in content or 'import constants' in content\n\n if not has_import:\n for magic in ['3600', '86400', '1000']:\n if re.search(rf'\\b{magic}\\b', content):\n return [\n f\"W7.2: File uses magic number {magic} but missing constants import. \"\n \"Add 'from constants import ...' and use named constants.\"\n ]\n\n return []\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n W7_1_MagicNumbers(),\n W7_2_MissingConstantsImport(),\n]\n"
}
}
{
"tool_response": {
"type": "create",
"filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_constants.py",
"content": "#!\/usr\/bin\/env python3\n\"\"\"\nConstants Rules (W7) - Magic Number Warnings.\n\nRegeln für benannte Konstanten: Warnt bei Magic Numbers,\nempfiehlt die Verwendung von Domain\\Constants.\n\"\"\"\n\nimport re\nfrom typing import List\nfrom .rule_base import Rule, COMMON_NUMBERS\n\n\n# =============================================================================\n# CONSTANTS ALLOWLIST\n# =============================================================================\n\nCONSTANTS_ALLOWLIST = [\n \"\/Constants.php\",\n \"\/constants.py\",\n \"\/config.py\",\n \"\/Config.php\",\n \"\/config\/\",\n \"CodeQualityChecker.php\",\n]\n\n# Suspicious magic numbers that should be named\nSUSPICIOUS_MAGIC = {\n '100': 'DEFAULT_LIMIT or PERCENT_FULL',\n '1000': 'BATCH_LIMIT or MS_PER_SECOND',\n '60': 'SECONDS_PER_MINUTE',\n '24': 'HOURS_PER_DAY',\n '365': 'DAYS_PER_YEAR',\n '30': 'HTTP_TIMEOUT',\n '120': 'LLM_TIMEOUT',\n}\n\n\n# =============================================================================\n# W7: CONSTANTS - Named Constants\n# =============================================================================\n\nclass W7_1_MagicNumbers(Rule):\n \"\"\"W7.1: Magic Numbers sollten benannte Konstanten sein.\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=CONSTANTS_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Nur PHP und Python\n if not (file_path.endswith('.php') or file_path.endswith('.py')):\n return []\n\n warnings = []\n lines = content.split('\\n')\n\n for line_num, line in enumerate(lines, 1):\n # Skip Kommentare\n stripped = line.strip()\n if stripped.startswith('\/\/') or stripped.startswith('#') or stripped.startswith('*'):\n continue\n\n # Skip const\/define\/Constants\n if re.search(r'\\bconst\\b|\\bdefine\\b|Constants::|from constants import', line, re.IGNORECASE):\n continue\n\n # Prüfe auf verdächtige Magic Numbers\n for magic, suggestion in SUSPICIOUS_MAGIC.items():\n # Nur alleinstehende Zahlen (nicht in größeren Zahlen)\n pattern = rf'(?<![0-9]){magic}(?![0-9])'\n if re.search(pattern, line):\n # Nicht warnen wenn bereits Constants verwendet wird\n if 'Constants::' in line or 'CONSTANTS' in line.upper():\n continue\n\n warnings.append(\n f\"W7.1: Magic number {magic} at line {line_num}. \"\n f\"Consider using Constants::{suggestion}\"\n )\n break # Eine Warnung pro Zeile reicht\n\n # Maximal 5 Warnungen pro Datei\n return warnings[:5]\n\n\nclass W7_2_MissingConstantsImport(Rule):\n \"\"\"W7.2: Constants Import fehlt aber Magic Numbers verwendet.\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=CONSTANTS_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n if file_path.endswith('.php'):\n # PHP: Prüfe auf use Domain\\Constants\n has_import = 'use Domain\\\\Constants' in content or 'Domain\\\\Constants::' in content\n\n if not has_import:\n # Hat die Datei verdächtige Magic Numbers?\n for magic in ['3600', '86400', '1000']:\n if re.search(rf'\\b{magic}\\b', content):\n return [\n f\"W7.2: File uses magic number {magic} but missing 'use Domain\\\\Constants'. \"\n \"Add import and use named constants.\"\n ]\n\n elif file_path.endswith('.py'):\n # Python: Prüfe auf from constants import\n has_import = 'from constants import' in content or 'import constants' in content\n\n if not has_import:\n for magic in ['3600', '86400', '1000']:\n if re.search(rf'\\b{magic}\\b', content):\n return [\n f\"W7.2: File uses magic number {magic} but missing constants import. \"\n \"Add 'from constants import ...' and use named constants.\"\n ]\n\n return []\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n W7_1_MagicNumbers(),\n W7_2_MissingConstantsImport(),\n]\n",
"structuredPatch": [],
"originalFile": null
}
}