Protokoll #11802

ID11802
Zeitstempel2025-12-23 21:42:41.063824
Clientroot
IP
Warning: Undefined array key "request_ip" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens4,227 (Input: 0, Output: 0)
Dauer85 ms
Request-Zeit
Warning: Undefined array key "request_timestamp" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 18
Response-Zeit-

Warning: Undefined array key "error_message" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 22

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/CodeAnalysis\/CodeQualityChecker.php",
        "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\CodeAnalysis;\n\n\/\/ @responsibility: Code-Qualitätsanalyse (Hardcoded, Complexity, Metrics)\n\nfinal class CodeQualityChecker\n{\n    \/** @var array<string, string> Regex patterns for hardcoded detection *\/\n    private const HARDCODED_PATTERNS = [\n        'password' => '\/[\"\\'](?:password|passwd|pwd)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{3,}[\"\\']\/i',\n        'api_key' => '\/[\"\\'](?:api[_-]?key|apikey|secret[_-]?key)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{8,}[\"\\']\/i',\n        'token' => '\/[\"\\'](?:token|auth[_-]?token|access[_-]?token)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{8,}[\"\\']\/i',\n        'ip_address' => '\/[\"\\']\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}[\"\\']\/i',\n        'url_with_creds' => '\/https?:\\\\\/\\\\\/[^:]+:[^@]+@\/i',\n        'magic_number' => '\/(?<![\\\\w])(?:100|1000|60|24|365|3600|86400)(?![\\\\w])\/',\n    ];\n\n    \/** @var array<string, int> Thresholds for scoring *\/\n    private const THRESHOLDS = [\n        'loc_excellent' => 100,\n        'loc_good' => 200,\n        'loc_acceptable' => 400,\n        'loc_poor' => 600,\n        'methods_excellent' => 5,\n        'methods_good' => 10,\n        'methods_acceptable' => 15,\n        'methods_poor' => 20,\n        'deps_excellent' => 3,\n        'deps_good' => 7,\n        'deps_acceptable' => 12,\n        'deps_poor' => 20,\n    ];\n\n    \/**\n     * Analysiert eine Datei auf Qualitätsprobleme.\n     *\n     * @param array<string, mixed> $analysisData Daten aus code_analysis\n     * @return array{\n     *     complexity_score: int,\n     *     loc_score: int,\n     *     dependency_score: int,\n     *     hardcoded_count: int,\n     *     issues_count: int,\n     *     warnings_count: int,\n     *     quality_grade: string,\n     *     issues_json: string\n     * }\n     *\/\n    public function analyze(array $analysisData): array\n    {\n        $issues = [];\n        $warnings = [];\n\n        $filePath = $analysisData['file_path'] ?? '';\n        $content = file_exists($filePath) ? file_get_contents($filePath) : '';\n\n        \/\/ LOC Analysis\n        $lineCount = $analysisData['line_count'] ?? 0;\n        $locScore = $this->calculateLocScore($lineCount);\n        if ($lineCount > self::THRESHOLDS['loc_poor']) {\n            $issues[] = [\n                'type' => 'complexity',\n                'rule' => 'file-too-long',\n                'message' => \"Datei hat {$lineCount} Zeilen (max empfohlen: \" . self::THRESHOLDS['loc_acceptable'] . \")\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Method Count Analysis\n        $functions = json_decode($analysisData['functions'] ?? '[]', true);\n        $methodCount = is_array($functions) ? count($functions) : 0;\n        $methodScore = $this->calculateMethodScore($methodCount);\n        if ($methodCount > self::THRESHOLDS['methods_poor']) {\n            $issues[] = [\n                'type' => 'srp',\n                'rule' => 'too-many-methods',\n                'message' => \"Klasse hat {$methodCount} Methoden (SRP-Verletzung möglich)\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Dependency Analysis\n        $uses = json_decode($analysisData['uses'] ?? '[]', true);\n        $depsCount = is_array($uses) ? count($uses) : 0;\n        $depScore = $this->calculateDependencyScore($depsCount);\n        if ($depsCount > self::THRESHOLDS['deps_poor']) {\n            $issues[] = [\n                'type' => 'coupling',\n                'rule' => 'too-many-dependencies',\n                'message' => \"Klasse hat {$depsCount} Dependencies (hohe Kopplung)\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Hardcoded Detection\n        $hardcodedIssues = $this->detectHardcoded($content, $filePath);\n        $hardcodedCount = count($hardcodedIssues);\n        $issues = array_merge($issues, $hardcodedIssues);\n\n        \/\/ Calculate complexity score (weighted average)\n        $complexityScore = (int) (($locScore * 0.3 + $methodScore * 0.3 + $depScore * 0.4));\n\n        \/\/ Penalize for hardcoded values\n        $complexityScore = max(0, $complexityScore - ($hardcodedCount * 10));\n\n        \/\/ Determine grade\n        $totalIssues = count($issues);\n        $totalWarnings = count(array_filter($issues, fn($i) => ($i['severity'] ?? '') === 'warning'));\n        $grade = $this->calculateGrade($complexityScore, $totalIssues);\n\n        return [\n            'complexity_score' => $complexityScore,\n            'loc_score' => $locScore,\n            'dependency_score' => $depScore,\n            'hardcoded_count' => $hardcodedCount,\n            'issues_count' => $totalIssues,\n            'warnings_count' => $totalWarnings,\n            'quality_grade' => $grade,\n            'issues_json' => json_encode($issues, JSON_UNESCAPED_UNICODE),\n        ];\n    }\n\n    private function calculateLocScore(int $loc): int\n    {\n        if ($loc <= self::THRESHOLDS['loc_excellent']) {\n            return 100;\n        }\n        if ($loc <= self::THRESHOLDS['loc_good']) {\n            return 80;\n        }\n        if ($loc <= self::THRESHOLDS['loc_acceptable']) {\n            return 60;\n        }\n        if ($loc <= self::THRESHOLDS['loc_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    private function calculateMethodScore(int $count): int\n    {\n        if ($count <= self::THRESHOLDS['methods_excellent']) {\n            return 100;\n        }\n        if ($count <= self::THRESHOLDS['methods_good']) {\n            return 80;\n        }\n        if ($count <= self::THRESHOLDS['methods_acceptable']) {\n            return 60;\n        }\n        if ($count <= self::THRESHOLDS['methods_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    private function calculateDependencyScore(int $count): int\n    {\n        if ($count <= self::THRESHOLDS['deps_excellent']) {\n            return 100;\n        }\n        if ($count <= self::THRESHOLDS['deps_good']) {\n            return 80;\n        }\n        if ($count <= self::THRESHOLDS['deps_acceptable']) {\n            return 60;\n        }\n        if ($count <= self::THRESHOLDS['deps_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    \/**\n     * @return array<array{type: string, rule: string, message: string, severity: string, line?: int}>\n     *\/\n    private function detectHardcoded(string $content, string $filePath): array\n    {\n        $issues = [];\n\n        \/\/ Skip config files and test files\n        $filename = basename($filePath);\n        if (preg_match('\/^(config|\\.env|test|spec)\/i', $filename)) {\n            return [];\n        }\n\n        foreach (self::HARDCODED_PATTERNS as $type => $pattern) {\n            \/\/ Skip magic numbers in config\/constant files\n            if ($type === 'magic_number' && preg_match('\/const|config\/i', $filePath)) {\n                continue;\n            }\n\n            if (preg_match_all($pattern, $content, $matches, PREG_OFFSET_CAPTURE)) {\n                foreach ($matches[0] as $match) {\n                    $line = substr_count(substr($content, 0, $match[1]), \"\\n\") + 1;\n                    $issues[] = [\n                        'type' => 'hardcoded',\n                        'rule' => \"hardcoded-{$type}\",\n                        'message' => \"Möglicher hardcoded {$type}: \" . substr($match[0], 0, 30) . '...',\n                        'severity' => $type === 'magic_number' ? 'info' : 'warning',\n                        'line' => $line,\n                    ];\n                }\n            }\n        }\n\n        return $issues;\n    }\n\n    private function calculateGrade(int $score, int $issueCount): string\n    {\n        \/\/ Penalize for issues\n        $adjustedScore = $score - ($issueCount * 5);\n\n        if ($adjustedScore >= 90) {\n            return 'A';\n        }\n        if ($adjustedScore >= 75) {\n            return 'B';\n        }\n        if ($adjustedScore >= 60) {\n            return 'C';\n        }\n        if ($adjustedScore >= 40) {\n            return 'D';\n        }\n\n        return 'F';\n    }\n}\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/CodeAnalysis\/CodeQualityChecker.php",
        "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\CodeAnalysis;\n\n\/\/ @responsibility: Code-Qualitätsanalyse (Hardcoded, Complexity, Metrics)\n\nfinal class CodeQualityChecker\n{\n    \/** @var array<string, string> Regex patterns for hardcoded detection *\/\n    private const HARDCODED_PATTERNS = [\n        'password' => '\/[\"\\'](?:password|passwd|pwd)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{3,}[\"\\']\/i',\n        'api_key' => '\/[\"\\'](?:api[_-]?key|apikey|secret[_-]?key)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{8,}[\"\\']\/i',\n        'token' => '\/[\"\\'](?:token|auth[_-]?token|access[_-]?token)[\"\\']\\\\s*[=:]\\\\s*[\"\\'][^\"\\']{8,}[\"\\']\/i',\n        'ip_address' => '\/[\"\\']\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}[\"\\']\/i',\n        'url_with_creds' => '\/https?:\\\\\/\\\\\/[^:]+:[^@]+@\/i',\n        'magic_number' => '\/(?<![\\\\w])(?:100|1000|60|24|365|3600|86400)(?![\\\\w])\/',\n    ];\n\n    \/** @var array<string, int> Thresholds for scoring *\/\n    private const THRESHOLDS = [\n        'loc_excellent' => 100,\n        'loc_good' => 200,\n        'loc_acceptable' => 400,\n        'loc_poor' => 600,\n        'methods_excellent' => 5,\n        'methods_good' => 10,\n        'methods_acceptable' => 15,\n        'methods_poor' => 20,\n        'deps_excellent' => 3,\n        'deps_good' => 7,\n        'deps_acceptable' => 12,\n        'deps_poor' => 20,\n    ];\n\n    \/**\n     * Analysiert eine Datei auf Qualitätsprobleme.\n     *\n     * @param array<string, mixed> $analysisData Daten aus code_analysis\n     * @return array{\n     *     complexity_score: int,\n     *     loc_score: int,\n     *     dependency_score: int,\n     *     hardcoded_count: int,\n     *     issues_count: int,\n     *     warnings_count: int,\n     *     quality_grade: string,\n     *     issues_json: string\n     * }\n     *\/\n    public function analyze(array $analysisData): array\n    {\n        $issues = [];\n        $warnings = [];\n\n        $filePath = $analysisData['file_path'] ?? '';\n        $content = file_exists($filePath) ? file_get_contents($filePath) : '';\n\n        \/\/ LOC Analysis\n        $lineCount = $analysisData['line_count'] ?? 0;\n        $locScore = $this->calculateLocScore($lineCount);\n        if ($lineCount > self::THRESHOLDS['loc_poor']) {\n            $issues[] = [\n                'type' => 'complexity',\n                'rule' => 'file-too-long',\n                'message' => \"Datei hat {$lineCount} Zeilen (max empfohlen: \" . self::THRESHOLDS['loc_acceptable'] . \")\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Method Count Analysis\n        $functions = json_decode($analysisData['functions'] ?? '[]', true);\n        $methodCount = is_array($functions) ? count($functions) : 0;\n        $methodScore = $this->calculateMethodScore($methodCount);\n        if ($methodCount > self::THRESHOLDS['methods_poor']) {\n            $issues[] = [\n                'type' => 'srp',\n                'rule' => 'too-many-methods',\n                'message' => \"Klasse hat {$methodCount} Methoden (SRP-Verletzung möglich)\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Dependency Analysis\n        $uses = json_decode($analysisData['uses'] ?? '[]', true);\n        $depsCount = is_array($uses) ? count($uses) : 0;\n        $depScore = $this->calculateDependencyScore($depsCount);\n        if ($depsCount > self::THRESHOLDS['deps_poor']) {\n            $issues[] = [\n                'type' => 'coupling',\n                'rule' => 'too-many-dependencies',\n                'message' => \"Klasse hat {$depsCount} Dependencies (hohe Kopplung)\",\n                'severity' => 'warning',\n            ];\n        }\n\n        \/\/ Hardcoded Detection\n        $hardcodedIssues = $this->detectHardcoded($content, $filePath);\n        $hardcodedCount = count($hardcodedIssues);\n        $issues = array_merge($issues, $hardcodedIssues);\n\n        \/\/ Calculate complexity score (weighted average)\n        $complexityScore = (int) (($locScore * 0.3 + $methodScore * 0.3 + $depScore * 0.4));\n\n        \/\/ Penalize for hardcoded values\n        $complexityScore = max(0, $complexityScore - ($hardcodedCount * 10));\n\n        \/\/ Determine grade\n        $totalIssues = count($issues);\n        $totalWarnings = count(array_filter($issues, fn($i) => ($i['severity'] ?? '') === 'warning'));\n        $grade = $this->calculateGrade($complexityScore, $totalIssues);\n\n        return [\n            'complexity_score' => $complexityScore,\n            'loc_score' => $locScore,\n            'dependency_score' => $depScore,\n            'hardcoded_count' => $hardcodedCount,\n            'issues_count' => $totalIssues,\n            'warnings_count' => $totalWarnings,\n            'quality_grade' => $grade,\n            'issues_json' => json_encode($issues, JSON_UNESCAPED_UNICODE),\n        ];\n    }\n\n    private function calculateLocScore(int $loc): int\n    {\n        if ($loc <= self::THRESHOLDS['loc_excellent']) {\n            return 100;\n        }\n        if ($loc <= self::THRESHOLDS['loc_good']) {\n            return 80;\n        }\n        if ($loc <= self::THRESHOLDS['loc_acceptable']) {\n            return 60;\n        }\n        if ($loc <= self::THRESHOLDS['loc_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    private function calculateMethodScore(int $count): int\n    {\n        if ($count <= self::THRESHOLDS['methods_excellent']) {\n            return 100;\n        }\n        if ($count <= self::THRESHOLDS['methods_good']) {\n            return 80;\n        }\n        if ($count <= self::THRESHOLDS['methods_acceptable']) {\n            return 60;\n        }\n        if ($count <= self::THRESHOLDS['methods_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    private function calculateDependencyScore(int $count): int\n    {\n        if ($count <= self::THRESHOLDS['deps_excellent']) {\n            return 100;\n        }\n        if ($count <= self::THRESHOLDS['deps_good']) {\n            return 80;\n        }\n        if ($count <= self::THRESHOLDS['deps_acceptable']) {\n            return 60;\n        }\n        if ($count <= self::THRESHOLDS['deps_poor']) {\n            return 40;\n        }\n\n        return 20;\n    }\n\n    \/**\n     * @return array<array{type: string, rule: string, message: string, severity: string, line?: int}>\n     *\/\n    private function detectHardcoded(string $content, string $filePath): array\n    {\n        $issues = [];\n\n        \/\/ Skip config files and test files\n        $filename = basename($filePath);\n        if (preg_match('\/^(config|\\.env|test|spec)\/i', $filename)) {\n            return [];\n        }\n\n        foreach (self::HARDCODED_PATTERNS as $type => $pattern) {\n            \/\/ Skip magic numbers in config\/constant files\n            if ($type === 'magic_number' && preg_match('\/const|config\/i', $filePath)) {\n                continue;\n            }\n\n            if (preg_match_all($pattern, $content, $matches, PREG_OFFSET_CAPTURE)) {\n                foreach ($matches[0] as $match) {\n                    $line = substr_count(substr($content, 0, $match[1]), \"\\n\") + 1;\n                    $issues[] = [\n                        'type' => 'hardcoded',\n                        'rule' => \"hardcoded-{$type}\",\n                        'message' => \"Möglicher hardcoded {$type}: \" . substr($match[0], 0, 30) . '...',\n                        'severity' => $type === 'magic_number' ? 'info' : 'warning',\n                        'line' => $line,\n                    ];\n                }\n            }\n        }\n\n        return $issues;\n    }\n\n    private function calculateGrade(int $score, int $issueCount): string\n    {\n        \/\/ Penalize for issues\n        $adjustedScore = $score - ($issueCount * 5);\n\n        if ($adjustedScore >= 90) {\n            return 'A';\n        }\n        if ($adjustedScore >= 75) {\n            return 'B';\n        }\n        if ($adjustedScore >= 60) {\n            return 'C';\n        }\n        if ($adjustedScore >= 40) {\n            return 'D';\n        }\n\n        return 'F';\n    }\n}\n",
        "structuredPatch": [],
        "originalFile": null
    }
}
← Vorheriger Zur Liste Nächster →