{
"tool_response": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/docs\/plan-code-quality-gates.md",
"oldString": "# Prüfung 2-6\n\n*Werden nach Abnahme von Prüfung 1 definiert.*",
"newString": "# Prüfung 2: MVC + CRUD\n\n## Ziel\n\n**MVC:** Klare Rollentrennung.\n- Controller: Orchestrierung (nimmt Request, ruft UseCase, gibt Response)\n- View: Darstellung (keine Logik)\n- Model: Geschäftslogik (Domain + UseCases)\n\n**CRUD:** Persistenz-Disziplin.\n- Create\/Read\/Update\/Delete gehören in Repository\n- Transaktionen gehören in UseCase oder Repository, nicht Controller\n- Controller orchestriert, persistiert nicht\n\n## Grundsatz\n\nMVC ist strukturell. Die Rollen sind durch Pfade definiert:\n- `\/Controller\/` = Presentation Layer\n- `\/View\/`, `\/templates\/` = Templates\n- `\/Domain\/` = Business Logic\n- `\/UseCases\/`, `\/Application\/` = Application Logic\n- `\/Infrastructure\/Persistence\/` = Repositories\n\n## Abgrenzung zu anderen Prüfungen\n\n| Aspekt | Prüfung | Begründung |\n|--------|---------|------------|\n| Klassen-Größe | 1 (SRP) | Strukturelle Metrik |\n| Methoden-Anzahl | 1 (SRP) | Strukturelle Metrik |\n| Abhängigkeits-Richtung | 6 (DIP) | Dependency Inversion |\n| **Rollen-Einhaltung** | **2 (MVC)** | Controller\/View\/Model Trennung |\n| **Persistenz-Ort** | **2 (CRUD)** | Wer darf DB anfassen |\n\n---\n\n## Pre-Hook (BLOCK)\n\n### P2.1: Keine SQL-Statements in Controller\n\n**Regel:** Controller dürfen keine direkten SQL-Queries enthalten.\n\n**Scope:** `\/Controller\/`\n\n**Pattern:**\n```python\nsql_patterns = [\n r\"\\bSELECT\\s+.+\\s+FROM\\b\",\n r\"\\bINSERT\\s+INTO\\b\",\n r\"\\bUPDATE\\s+\\w+\\s+SET\\b\",\n r\"\\bDELETE\\s+FROM\\b\",\n]\n```\n\n**Warum diese Pattern:**\n- Spezifisch genug um False Positives zu vermeiden\n- `SELECT your country` matcht nicht (kein FROM)\n- `INSERT INTO users` matcht (eindeutig SQL)\n\n**Unterschied zu Prüfung 1\/6:**\n- H-Regeln prüfen Objekte (new Repository, DatabaseFactory)\n- P2.1 prüft String-Literale (SQL-Statements)\n\n---\n\n### P2.2: Keine Transaktionen in Controller\n\n**Regel:** Transaktions-Kontrolle gehört nicht in Controller.\n\n**Scope:** `\/Controller\/`\n\n**Pattern:**\n```python\ntransaction_patterns = [\n r\"\\bbeginTransaction\\s*\\(\",\n r\"\\bcommit\\s*\\(\",\n r\"\\brollBack\\s*\\(\",\n r\"\\brollback\\s*\\(\",\n]\n```\n\n**Begründung:**\n- Transaktionen sind Infrastruktur-Concern\n- Controller soll Request→Response orchestrieren, nicht DB-Konsistenz managen\n- Transaktionen gehören in UseCase oder Repository\n\n---\n\n### P2.3: Kein direktes Rendering in Controller\n\n**Regel:** Controller erzeugen keine direkte Ausgabe.\n\n**Scope:** `\/Controller\/`\n\n**Pattern:**\n```python\noutput_patterns = [\n r\"\\becho\\s\",\n r\"\\becho\\(\",\n r\"\\bprint\\s\",\n r\"\\bprint\\(\",\n]\n```\n\n**Nicht blockiert:**\n- `print_r` (Debug)\n- `printf` (Formatierung, selten)\n- `return json_encode()` (Response-Objekt)\n\n**Begründung:**\n- Output gehört in View oder Response-Objekt\n- echo\/print in Controller = MVC-Verletzung\n- CLI-Code gehört in `\/Console\/` oder `\/Command\/`, nicht `\/Controller\/`\n\n---\n\n### P2.4: Keine DB-Artefakte in UseCases\n\n**Regel:** UseCases nutzen Repository-Interfaces, nicht direkte DB.\n\n**Scope:** `\/UseCases\/`, `\/Application\/`\n\n**Pattern:**\n```python\ndb_patterns = [\n r\"\\bnew\\s+PDO\\b\",\n r\"\\bPDO::\",\n r\"\\bDatabaseFactory::\",\n r\"\\bSELECT\\s+.+\\s+FROM\\b\",\n r\"\\bINSERT\\s+INTO\\b\",\n r\"\\bUPDATE\\s+\\w+\\s+SET\\b\",\n r\"\\bDELETE\\s+FROM\\b\",\n]\n```\n\n**Nicht blockiert:**\n- `PDOException` (Exception-Handling ist okay)\n- `use Infrastructure\\Persistence\\*Repository` (Interface-Import okay)\n\n**Begründung:**\n- UseCases definieren WAS passiert, nicht WIE\n- DB-Zugriff ist Infrastruktur-Detail\n- Repository-Abstraktion ermöglicht Austauschbarkeit\n\n---\n\n## Post-Hook (WARN)\n\n### W2.1: Business-Keywords in Controller\n\n**Regel:** Bestimmte Verben deuten auf Business-Logik hin, die nicht in Controller gehört.\n\n**Scope:** `\/Controller\/`\n\n**Pattern:**\n```python\nbusiness_keywords = [\n r\"\\bcalculate\\w*\\s*\\(\",\n r\"\\bcompute\\w*\\s*\\(\",\n r\"\\bvalidate\\w*\\s*\\(\",\n r\"\\bprocess\\w*\\s*\\(\",\n r\"\\btransform\\w*\\s*\\(\",\n r\"\\bconvert\\w*\\s*\\(\",\n]\n```\n\n**Warum Warnung statt Block:**\n- `validateRequest()` im Controller kann legitim sein (Input-Validation)\n- `processUpload()` könnte Orchestrierung sein\n- Menschliche Entscheidung erforderlich\n\n**Indikator für:**\n- Business-Logik die in Domain gehört\n- Zu viel Verantwortung im Controller\n\n---\n\n### W2.2: Viele private Methoden in Controller\n\n**Regel:** Controller sollten dünn sein. Viele private Methoden = versteckte Logik.\n\n**Scope:** `\/Controller\/`\n\n**Schwelle:** > 5 private methods\n\n**Pattern:**\n```python\nprivate_methods = re.findall(r\"private\\s+function\\s+\\w+\", content)\nif len(private_methods) > 5:\n warn(f\"Controller has {len(private_methods)} private methods. Consider extracting to Service.\")\n```\n\n**Begründung:**\n- Controller-Actions sollten kurz sein\n- Private Methoden = ausgelagerte Logik die woanders hingehört\n- > 5 ist Zeichen für Feature Creep\n\n**Unterschied zu W1.2 (Public Methods):**\n- W1.2: Viele public = breite API = SRP-Problem\n- W2.2: Viele private = versteckte Komplexität = MVC-Problem\n\n---\n\n## Gestrichen\n\n### Komplexe Bedingungen in View\/Templates\n\n**Ursprüngliche Idee:** Verschachtelte if-Statements in Templates erkennen.\n\n**Warum gestrichen:**\n- Ohne AST nicht zuverlässig prüfbar\n- Template-Engines variieren stark (Twig, Blade, PHP)\n- Gleiche Problematik wie Verschachtelungstiefe in Prüfung 1\n\n**Alternative:** Erst implementieren wenn Template-Engine standardisiert.\n\n---\n\n## Zusammenfassung\n\n### Pre-Hook\n\n| ID | Prüfung | Scope | Aktion |\n|----|---------|-------|--------|\n| P2.1 | SQL-Statements | \/Controller\/ | BLOCK |\n| P2.2 | Transaktions-Steuerung | \/Controller\/ | BLOCK |\n| P2.3 | echo\/print | \/Controller\/ | BLOCK |\n| P2.4 | DB-Artefakte | \/UseCases\/, \/Application\/ | BLOCK |\n\n### Post-Hook\n\n| ID | Prüfung | Scope | Schwelle | Aktion |\n|----|---------|-------|----------|--------|\n| W2.1 | Business-Keywords | \/Controller\/ | - | WARN |\n| W2.2 | Private Methods | \/Controller\/ | > 5 | WARN |\n\n### Allowlist\n\n| Pfad | Grund |\n|------|-------|\n| \/vendor\/ | Third-party |\n| \/tests\/ | Test-Code |\n| \/Test\/ | PHPUnit |\n| \/Infrastructure\/ | Darf DB nutzen (per Definition) |\n\n---\n\n## Selbstkritik und Entscheidungen\n\n| Frage | Entscheidung | Begründung |\n|-------|--------------|------------|\n| Ist echo\/print zu strikt? | Nein | Produktionscode hat keine direkte Ausgabe. Debug gehört nicht in Controller. |\n| Ist \"validate\" als Keyword problematisch? | Ja, aber Warnung | Input-Validation okay, Business-Validation nicht. Menschliche Entscheidung. |\n| Warum PDOException erlauben? | Exception-Handling ist okay | UseCase darf Fehler behandeln, nur nicht DB direkt nutzen. |\n| Fehlt View-Logik-Prüfung? | Ja, bewusst | Ohne standardisierte Template-Engine nicht prüfbar. |\n\n---\n\n# Prüfung 3-6\n\n*Werden nach Abnahme von Prüfung 2 definiert.*",
"originalFile": "# Code Quality Gates\n\n## Prüfungsreihenfolge\n\n| # | Prinzip | Begründung der Reihenfolge |\n|---|---------|---------------------------|\n| 1 | SRP + KISS | Grundlage für alles. Ohne klare Verantwortung ist nichts anderes prüfbar. |\n| 2 | MVC + CRUD | Strukturelle Trennung. Setzt SRP voraus. |\n| 3 | PSR + Types | Typdisziplin. Muss VOR DIP kommen, weil Interfaces ohne Typen wirkungslos sind. |\n| 4 | OOP | Verhalten + Zustand. Setzt Typen voraus. |\n| 5 | DRY | Duplikationserkennung. Setzt funktionierende Struktur voraus. |\n| 6 | SOLID + DIP | Abhängigkeitsrichtung. Setzt Typen und Interfaces voraus. Kommt zuletzt. |\n\n---\n\n# Prüfung 1: SRP + KISS\n\n## Ziel\n\n**SRP:** Eine Klasse hat genau einen Grund sich zu ändern.\n\n**KISS:** Einfachste Lösung die funktioniert. Keine vorzeitigen Abstraktionen.\n\n## Grundsatz\n\nSRP ist semantisch. Maschinen können \"Verantwortung\" nicht verstehen.\n\nDaher:\n- **Pre-Hook:** Erzwingt explizite Deklaration + blockiert eindeutige Symptome\n- **Post-Hook:** Warnt bei statistischen Indikatoren\n\n---\n\n## Pre-Hook (BLOCK)\n\n### P1.1: Verantwortungs-Header\n\n**Regel:** Jede PHP-Datei muss ihre Verantwortung explizit deklarieren.\n\n**Format:**\n```php\n<?php\ndeclare(strict_types=1);\n\n\/\/ @responsibility: <genau-eine-verantwortung>\n```\n\n**Validierung:**\n\n| Check | Begründung |\n|-------|------------|\n| Header vorhanden | Ohne Deklaration entsteht Scope Creep |\n| Nicht leer | Leerer Header ist wertlos |\n| Keine Multi-Responsibility-Wörter | \"und\", \"sowie\", \"außerdem\", \"zusätzlich\" im Header = mehrere Verantwortungen |\n\n**Pattern:**\n```python\nheader_pattern = r\"\/\/\\s*@responsibility:\\s*(.+)\"\nmulti_words = r\"\\b(und|sowie|außerdem|also|zusätzlich)\\b\"\n\nmatch = re.search(header_pattern, content)\nif not match:\n block(\"Missing @responsibility header\")\n\nresponsibility_text = match.group(1)\nif re.search(multi_words, responsibility_text, re.IGNORECASE):\n block(\"@responsibility contains multi-responsibility indicator\")\n```\n\n**Warum diese Wörter:**\n- \"Validiert Benutzer und erstellt Sessions\" = 2 Verantwortungen\n- \"Lädt Daten sowie formatiert Ausgabe\" = 2 Verantwortungen\n- Erzwingt Nachdenken über Singular-Verantwortung\n\n**Allowlist:** `\/vendor\/`, `\/tests\/`, `\/Test\/`\n\n---\n\n### P1.2: Müllhalden-Namen\n\n**Regel:** Bestimmte Begriffe im Dateinamen sind immer Symptome für fehlende klare Verantwortung.\n\n**Blockiert (case-insensitive):**\n\n| Begriff | Begründung |\n|---------|------------|\n| Helper | \"Hilft bei allem\" = keine klare Verantwortung |\n| Utils | Sammelbecken für Funktionen ohne Heimat |\n| Common | \"Wird überall gebraucht\" = gehört nirgends hin |\n| Misc | Explizit: \"Verschiedenes\" |\n| Base | Oft Gott-Klasse mit Shared-State |\n\n**Nicht blockiert:**\n- \"Manager\" → Kann legitim sein (TransactionManager, EntityManager)\n- \"And\" im Namen → Sprachlich, nicht strukturell\n\n**Pattern:**\n```python\nforbidden = [\"helper\", \"utils\", \"common\", \"misc\", \"base\"]\nfilename_lower = filename.lower()\nfor term in forbidden:\n if term in filename_lower:\n block(f\"Forbidden name: '{term}' indicates unclear responsibility\")\n```\n\n**Keine Ausnahmen.** Diese Begriffe sind niemals architektonisch sauber.\n\n---\n\n## Post-Hook (WARN)\n\n### W1.1: Klassengröße (LOC)\n\n**Regel:** Große Klassen haben oft mehrere Verantwortungen.\n\n| LOC | Aktion |\n|-----|--------|\n| > 200 | Hinweis |\n| > 300 | Warnung |\n\n**Warum zwei Schwellen:**\n- 200: \"Du näherst dich dem Limit\"\n- 300: \"Hier stimmt strukturell etwas nicht\"\n\n**Messung:** Nicht-leere Zeilen.\n\n---\n\n### W1.2: Public-Method-Count\n\n**Regel:** Viele öffentliche Methoden = viele Interaktionspunkte = breite Verantwortung.\n\n| Count | Aktion |\n|-------|--------|\n| > 10 | Warnung |\n\n**Warum 10:**\n- Ein fokussiertes Interface hat 3-7 Methoden\n- 10+ deutet auf Feature Creep\n\n---\n\n### W1.3: Constructor-Parameter\n\n**Regel:** Viele Dependencies = viele Gründe sich zu ändern.\n\n| Count | Aktion |\n|-------|--------|\n| > 5 | Warnung |\n\n**Warum 5:**\n- 1-3: Normal\n- 4-5: Grenzwertig\n- 6+: Fast immer strukturelles Problem\n\n---\n\n### W1.4: Dependency-Count (use-Statements)\n\n**Regel:** Viele Imports = Kopplung an viele Module = viele Änderungsgründe.\n\n| Count | Aktion |\n|-------|--------|\n| > 10 | Warnung |\n\n**Warum 10:**\n- PHP-interne Classes zählen mit\n- Framework-Imports zählen mit\n- 10+ externe Abhängigkeiten ist ein Warnsignal\n\n---\n\n### W1.5: Verdächtige Namen\n\n**Regel:** Manche Begriffe sind nicht eindeutig Müll, aber verdächtig.\n\n| Begriff | Aktion |\n|---------|--------|\n| Manager | Hinweis |\n| And (als Wort) | Hinweis |\n\n**Warum Hinweis statt Block:**\n- \"UserManager\" kann legitim sein\n- \"ReadAndWrite\" kann legitim sein (obwohl fragwürdig)\n- Menschliche Entscheidung erforderlich\n\n---\n\n## Gestrichen\n\n### Verschachtelungstiefe\n\n**Ursprüngliche Idee:** > 4 Ebenen = Warnung\n\n**Warum gestrichen:**\n- Indent-basierte Messung ist nicht zuverlässig\n- PHP erlaubt verschiedene Styles (2, 4, Tabs)\n- Fluent Interfaces erzeugen tiefe Indents ohne Kontrollfluss\n- Array-Definitionen erzeugen tiefe Indents\n- False Positives zu hoch\n\n**Alternative:** Erst implementieren wenn AST-Parsing verfügbar.\n\n---\n\n## Zusammenfassung\n\n### Pre-Hook\n\n| ID | Prüfung | Aktion |\n|----|---------|--------|\n| P1.1 | @responsibility fehlt oder Multi-Responsibility | BLOCK |\n| P1.2 | Müllhalden-Name (Helper, Utils, Common, Misc, Base) | BLOCK |\n\n### Post-Hook\n\n| ID | Prüfung | Schwelle | Aktion |\n|----|---------|----------|--------|\n| W1.1 | LOC | > 300 | WARN |\n| W1.2 | Public Methods | > 10 | WARN |\n| W1.3 | Constructor Params | > 5 | WARN |\n| W1.4 | Dependencies (use) | > 10 | WARN |\n| W1.5 | Verdächtige Namen | Manager, And | HINT |\n\n### Allowlist\n\n| Pfad | Grund |\n|------|-------|\n| \/vendor\/ | Third-party Code |\n| \/tests\/ | Test-Konventionen anders |\n| \/Test\/ | PHPUnit |\n\n---\n\n## Selbstkritik und Entscheidungen\n\n| Frage | Entscheidung | Begründung |\n|-------|--------------|------------|\n| Ist Multi-Word-Check im Header Over-Engineering? | Nein | Ein Regex. Verhindert \"Macht A und B\". Minimaler Aufwand, hoher Nutzen. |\n| Ist Dependency-Count SRP? | Ja | Viele Dependencies = viele Änderungsgründe = SRP-Verletzung per Definition. |\n| Sollen Factories in Allowlist? | Nein | Auch Factories sollten nicht 50 Methoden haben. Wenn zu groß, aufteilen. |\n| Warum keine Kontext-Schwellen für Repositories? | YAGNI | Komplexität ohne klaren Nutzen. Wer > 10 Methoden braucht, soll bewusst entscheiden. |\n\n---\n\n## Implementierung\n\n**Dateien:**\n- `\/var\/www\/tools\/ki-protokoll\/claude-hook\/srp_kiss_guard.py` (Pre-Hook)\n- `\/var\/www\/tools\/ki-protokoll\/claude-hook\/srp_kiss_metrics.py` (Post-Hook)\n\n**Hooks in settings.json:**\n```json\n{\n \"PreToolUse\": [\n {\n \"matcher\": \"Write\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"\/var\/www\/tools\/ki-protokoll\/claude-hook\/srp_kiss_guard.py\",\n \"timeout\": 5\n }\n ]\n }\n ],\n \"PostToolUse\": [\n {\n \"matcher\": \"Write|Edit\",\n \"hooks\": [\n {\n \"type\": \"command\",\n \"command\": \"\/var\/www\/tools\/ki-protokoll\/claude-hook\/srp_kiss_metrics.py\",\n \"timeout\": 5\n }\n ]\n }\n ]\n}\n```\n\n---\n\n# Prüfung 2-6\n\n*Werden nach Abnahme von Prüfung 1 definiert.*\n",
"structuredPatch": [
{
"oldStart": 281,
"oldLines": 6,
"newStart": 281,
"newLines": 263,
"lines": [
" ",
" ---",
" ",
"-# Prüfung 2-6",
"+# Prüfung 2: MVC + CRUD",
" ",
"-*Werden nach Abnahme von Prüfung 1 definiert.*",
"+## Ziel",
"+",
"+**MVC:** Klare Rollentrennung.",
"+- Controller: Orchestrierung (nimmt Request, ruft UseCase, gibt Response)",
"+- View: Darstellung (keine Logik)",
"+- Model: Geschäftslogik (Domain + UseCases)",
"+",
"+**CRUD:** Persistenz-Disziplin.",
"+- Create\/Read\/Update\/Delete gehören in Repository",
"+- Transaktionen gehören in UseCase oder Repository, nicht Controller",
"+- Controller orchestriert, persistiert nicht",
"+",
"+## Grundsatz",
"+",
"+MVC ist strukturell. Die Rollen sind durch Pfade definiert:",
"+- `\/Controller\/` = Presentation Layer",
"+- `\/View\/`, `\/templates\/` = Templates",
"+- `\/Domain\/` = Business Logic",
"+- `\/UseCases\/`, `\/Application\/` = Application Logic",
"+- `\/Infrastructure\/Persistence\/` = Repositories",
"+",
"+## Abgrenzung zu anderen Prüfungen",
"+",
"+| Aspekt | Prüfung | Begründung |",
"+|--------|---------|------------|",
"+| Klassen-Größe | 1 (SRP) | Strukturelle Metrik |",
"+| Methoden-Anzahl | 1 (SRP) | Strukturelle Metrik |",
"+| Abhängigkeits-Richtung | 6 (DIP) | Dependency Inversion |",
"+| **Rollen-Einhaltung** | **2 (MVC)** | Controller\/View\/Model Trennung |",
"+| **Persistenz-Ort** | **2 (CRUD)** | Wer darf DB anfassen |",
"+",
"+---",
"+",
"+## Pre-Hook (BLOCK)",
"+",
"+### P2.1: Keine SQL-Statements in Controller",
"+",
"+**Regel:** Controller dürfen keine direkten SQL-Queries enthalten.",
"+",
"+**Scope:** `\/Controller\/`",
"+",
"+**Pattern:**",
"+```python",
"+sql_patterns = [",
"+ r\"\\bSELECT\\s+.+\\s+FROM\\b\",",
"+ r\"\\bINSERT\\s+INTO\\b\",",
"+ r\"\\bUPDATE\\s+\\w+\\s+SET\\b\",",
"+ r\"\\bDELETE\\s+FROM\\b\",",
"+]",
"+```",
"+",
"+**Warum diese Pattern:**",
"+- Spezifisch genug um False Positives zu vermeiden",
"+- `SELECT your country` matcht nicht (kein FROM)",
"+- `INSERT INTO users` matcht (eindeutig SQL)",
"+",
"+**Unterschied zu Prüfung 1\/6:**",
"+- H-Regeln prüfen Objekte (new Repository, DatabaseFactory)",
"+- P2.1 prüft String-Literale (SQL-Statements)",
"+",
"+---",
"+",
"+### P2.2: Keine Transaktionen in Controller",
"+",
"+**Regel:** Transaktions-Kontrolle gehört nicht in Controller.",
"+",
"+**Scope:** `\/Controller\/`",
"+",
"+**Pattern:**",
"+```python",
"+transaction_patterns = [",
"+ r\"\\bbeginTransaction\\s*\\(\",",
"+ r\"\\bcommit\\s*\\(\",",
"+ r\"\\brollBack\\s*\\(\",",
"+ r\"\\brollback\\s*\\(\",",
"+]",
"+```",
"+",
"+**Begründung:**",
"+- Transaktionen sind Infrastruktur-Concern",
"+- Controller soll Request→Response orchestrieren, nicht DB-Konsistenz managen",
"+- Transaktionen gehören in UseCase oder Repository",
"+",
"+---",
"+",
"+### P2.3: Kein direktes Rendering in Controller",
"+",
"+**Regel:** Controller erzeugen keine direkte Ausgabe.",
"+",
"+**Scope:** `\/Controller\/`",
"+",
"+**Pattern:**",
"+```python",
"+output_patterns = [",
"+ r\"\\becho\\s\",",
"+ r\"\\becho\\(\",",
"+ r\"\\bprint\\s\",",
"+ r\"\\bprint\\(\",",
"+]",
"+```",
"+",
"+**Nicht blockiert:**",
"+- `print_r` (Debug)",
"+- `printf` (Formatierung, selten)",
"+- `return json_encode()` (Response-Objekt)",
"+",
"+**Begründung:**",
"+- Output gehört in View oder Response-Objekt",
"+- echo\/print in Controller = MVC-Verletzung",
"+- CLI-Code gehört in `\/Console\/` oder `\/Command\/`, nicht `\/Controller\/`",
"+",
"+---",
"+",
"+### P2.4: Keine DB-Artefakte in UseCases",
"+",
"+**Regel:** UseCases nutzen Repository-Interfaces, nicht direkte DB.",
"+",
"+**Scope:** `\/UseCases\/`, `\/Application\/`",
"+",
"+**Pattern:**",
"+```python",
"+db_patterns = [",
"+ r\"\\bnew\\s+PDO\\b\",",
"+ r\"\\bPDO::\",",
"+ r\"\\bDatabaseFactory::\",",
"+ r\"\\bSELECT\\s+.+\\s+FROM\\b\",",
"+ r\"\\bINSERT\\s+INTO\\b\",",
"+ r\"\\bUPDATE\\s+\\w+\\s+SET\\b\",",
"+ r\"\\bDELETE\\s+FROM\\b\",",
"+]",
"+```",
"+",
"+**Nicht blockiert:**",
"+- `PDOException` (Exception-Handling ist okay)",
"+- `use Infrastructure\\Persistence\\*Repository` (Interface-Import okay)",
"+",
"+**Begründung:**",
"+- UseCases definieren WAS passiert, nicht WIE",
"+- DB-Zugriff ist Infrastruktur-Detail",
"+- Repository-Abstraktion ermöglicht Austauschbarkeit",
"+",
"+---",
"+",
"+## Post-Hook (WARN)",
"+",
"+### W2.1: Business-Keywords in Controller",
"+",
"+**Regel:** Bestimmte Verben deuten auf Business-Logik hin, die nicht in Controller gehört.",
"+",
"+**Scope:** `\/Controller\/`",
"+",
"+**Pattern:**",
"+```python",
"+business_keywords = [",
"+ r\"\\bcalculate\\w*\\s*\\(\",",
"+ r\"\\bcompute\\w*\\s*\\(\",",
"+ r\"\\bvalidate\\w*\\s*\\(\",",
"+ r\"\\bprocess\\w*\\s*\\(\",",
"+ r\"\\btransform\\w*\\s*\\(\",",
"+ r\"\\bconvert\\w*\\s*\\(\",",
"+]",
"+```",
"+",
"+**Warum Warnung statt Block:**",
"+- `validateRequest()` im Controller kann legitim sein (Input-Validation)",
"+- `processUpload()` könnte Orchestrierung sein",
"+- Menschliche Entscheidung erforderlich",
"+",
"+**Indikator für:**",
"+- Business-Logik die in Domain gehört",
"+- Zu viel Verantwortung im Controller",
"+",
"+---",
"+",
"+### W2.2: Viele private Methoden in Controller",
"+",
"+**Regel:** Controller sollten dünn sein. Viele private Methoden = versteckte Logik.",
"+",
"+**Scope:** `\/Controller\/`",
"+",
"+**Schwelle:** > 5 private methods",
"+",
"+**Pattern:**",
"+```python",
"+private_methods = re.findall(r\"private\\s+function\\s+\\w+\", content)",
"+if len(private_methods) > 5:",
"+ warn(f\"Controller has {len(private_methods)} private methods. Consider extracting to Service.\")",
"+```",
"+",
"+**Begründung:**",
"+- Controller-Actions sollten kurz sein",
"+- Private Methoden = ausgelagerte Logik die woanders hingehört",
"+- > 5 ist Zeichen für Feature Creep",
"+",
"+**Unterschied zu W1.2 (Public Methods):**",
"+- W1.2: Viele public = breite API = SRP-Problem",
"+- W2.2: Viele private = versteckte Komplexität = MVC-Problem",
"+",
"+---",
"+",
"+## Gestrichen",
"+",
"+### Komplexe Bedingungen in View\/Templates",
"+",
"+**Ursprüngliche Idee:** Verschachtelte if-Statements in Templates erkennen.",
"+",
"+**Warum gestrichen:**",
"+- Ohne AST nicht zuverlässig prüfbar",
"+- Template-Engines variieren stark (Twig, Blade, PHP)",
"+- Gleiche Problematik wie Verschachtelungstiefe in Prüfung 1",
"+",
"+**Alternative:** Erst implementieren wenn Template-Engine standardisiert.",
"+",
"+---",
"+",
"+## Zusammenfassung",
"+",
"+### Pre-Hook",
"+",
"+| ID | Prüfung | Scope | Aktion |",
"+|----|---------|-------|--------|",
"+| P2.1 | SQL-Statements | \/Controller\/ | BLOCK |",
"+| P2.2 | Transaktions-Steuerung | \/Controller\/ | BLOCK |",
"+| P2.3 | echo\/print | \/Controller\/ | BLOCK |",
"+| P2.4 | DB-Artefakte | \/UseCases\/, \/Application\/ | BLOCK |",
"+",
"+### Post-Hook",
"+",
"+| ID | Prüfung | Scope | Schwelle | Aktion |",
"+|----|---------|-------|----------|--------|",
"+| W2.1 | Business-Keywords | \/Controller\/ | - | WARN |",
"+| W2.2 | Private Methods | \/Controller\/ | > 5 | WARN |",
"+",
"+### Allowlist",
"+",
"+| Pfad | Grund |",
"+|------|-------|",
"+| \/vendor\/ | Third-party |",
"+| \/tests\/ | Test-Code |",
"+| \/Test\/ | PHPUnit |",
"+| \/Infrastructure\/ | Darf DB nutzen (per Definition) |",
"+",
"+---",
"+",
"+## Selbstkritik und Entscheidungen",
"+",
"+| Frage | Entscheidung | Begründung |",
"+|-------|--------------|------------|",
"+| Ist echo\/print zu strikt? | Nein | Produktionscode hat keine direkte Ausgabe. Debug gehört nicht in Controller. |",
"+| Ist \"validate\" als Keyword problematisch? | Ja, aber Warnung | Input-Validation okay, Business-Validation nicht. Menschliche Entscheidung. |",
"+| Warum PDOException erlauben? | Exception-Handling ist okay | UseCase darf Fehler behandeln, nur nicht DB direkt nutzen. |",
"+| Fehlt View-Logik-Prüfung? | Ja, bewusst | Ohne standardisierte Template-Engine nicht prüfbar. |",
"+",
"+---",
"+",
"+# Prüfung 3-6",
"+",
"+*Werden nach Abnahme von Prüfung 2 definiert.*"
]
}
],
"userModified": false,
"replaceAll": false
}
}