Protokoll #33313

ID33313
Zeitstempel2026-04-21 00:06:08.687586
Clientroot
IP62.246.34.195
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens5,281 (Input: 2,635, Output: 2,646)
Dauer69 ms
Request-Zeit2026-04-21 00:06:08.687586
Response-Zeit2026-04-21 00:06:08.756921

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/crawler\/planung\/01-code-standards.yaml",
        "content": "---\n# ============================================================================\n# Crawler – Code-Standards & Quality Gateways\n# ============================================================================\n# Verbindlich. Keine Umgehung. Alle Gateways müssen vor Merge\/Deploy passen.\n# Stand: 2026-04-21\n# ============================================================================\n\nmeta:\n  document: crawler-code-standards\n  version: 1.0.0\n  binding: true\n  last_updated: 2026-04-21\n  scope:\n    - python_core: \/var\/www\/dev.campus.systemische-tools.de\/crawler\/src\n    - php_presentation: \/var\/www\/dev.campus.systemische-tools.de\/src (Controller\/View unter Route \/crawler)\n\n# ----------------------------------------------------------------------------\n# Architektur\n# ----------------------------------------------------------------------------\narchitecture:\n  paradigm: Domain-Driven Design\n  style: Hexagonal (Ports and Adapters)\n  core_principles: [SRP, SoC, DRY, DIP, YAGNI]\n\n  layers:\n    domain:\n      responsibility: reine Geschäftslogik, Entities, Value Objects, Domain Services\n      imports_allowed: [stdlib, typing, dataclasses, datetime, hashlib, enum, re, abc]\n      imports_forbidden: [framework, db_driver, http_client, filesystem, third_party_business]\n    application:\n      responsibility: Use Cases, Orchestrierung, Ports (Interfaces zu Infrastructure)\n      imports_allowed: [domain, stdlib]\n      imports_forbidden: [infrastructure, interfaces, third_party_impl]\n    infrastructure:\n      responsibility: Adapter – DB, HTTP, Playwright, Filesystem, Logging\n      imports_allowed: [domain, application, stdlib, third_party]\n      imports_forbidden: [interfaces]\n    interfaces:\n      responsibility: CLI (Python), HTTP-Controller + Views (PHP), HTMX\n      imports_allowed: [application, domain, stdlib, third_party_ui]\n      imports_forbidden: [infrastructure_internals]\n\n  dependency_direction: |\n    interfaces → application → domain\n    infrastructure → application, domain\n    Verletzungen → Gate 4 Failure.\n\n# ----------------------------------------------------------------------------\n# Harte Code-Metriken (nicht verhandelbar, nicht umgehbar)\n# ----------------------------------------------------------------------------\ncode_metrics:\n  max_loc_per_method:\n    soft: 50\n    hard: 80\n    excludes_from_count: [comments, docstrings, blank_lines, pure_type_stubs]\n    applies_to: [python_functions, python_methods, php_methods, php_functions]\n    enforcement: gate_1_lint_block\n\n  max_loc_per_class:\n    soft: 50\n    hard: 80\n    excludes_from_count: [comments, docstrings, blank_lines, class_attribute_declarations]\n    applies_to: [python_classes, php_classes]\n    note: \"SRP ernst nehmen – große Adapter in fokussierte Sub-Adapter aufteilen.\"\n    enforcement: gate_1_lint_block\n\n  max_loc_per_file:\n    hard: 200\n    excludes_from_count: [comments, docstrings, blank_lines]\n    enforcement: gate_1_lint_block\n\n  max_cyclomatic_complexity:\n    soft: 5\n    hard: 8\n    enforcement: gate_1_lint_block\n\n  max_method_parameters:\n    hard: 4\n    note: \"Mehr Parameter → Value Object \/ DTO einführen.\"\n    enforcement: gate_1_lint_block\n\n  max_nesting_depth:\n    hard: 3\n    enforcement: gate_1_lint_block\n\n  max_return_points_per_method:\n    hard: 4\n    enforcement: gate_1_lint_warn\n\n# ----------------------------------------------------------------------------\n# Naming\n# ----------------------------------------------------------------------------\nnaming:\n  python:\n    modules: snake_case\n    classes: PascalCase\n    functions: snake_case\n    methods: snake_case\n    constants: UPPER_SNAKE_CASE\n    private_members: _leading_underscore\n    type_aliases: PascalCase\n    test_files: \"test_*.py\"\n  php:\n    namespaces: PascalCase\n    classes: PascalCase\n    interfaces: \"*Interface oder *Port\"\n    methods: camelCase\n    constants: UPPER_SNAKE_CASE\n    properties: camelCase\n\n# ----------------------------------------------------------------------------\n# Verboten (hard fail)\n# ----------------------------------------------------------------------------\nforbidden:\n  - id: F-001\n    rule: Magic Numbers\n    detail: \"Zahlenliterale außerhalb von 0, 1, -1 nur via Constants::* bzw. constants.*\"\n    enforcement: gate_1_lint_block\n  - id: F-002\n    rule: Direkter SQL-Zugriff außerhalb Infrastructure-Repositories\n    enforcement: gate_4_architecture_block\n  - id: F-003\n    rule: Framework-Imports in Domain\/Application\n    enforcement: gate_4_architecture_block\n  - id: F-004\n    rule: Globaler veränderlicher Zustand (modul-level mutable state)\n    enforcement: gate_1_lint_block\n  - id: F-005\n    rule: print() \/ var_dump() \/ echo-Debug\n    detail: \"Ausschließlich Logging-Adapter verwenden.\"\n    enforcement: gate_1_lint_block\n  - id: F-006\n    rule: Bare except \/ catch(\\Throwable) außerhalb Interfaces-Layer-Edge\n    enforcement: gate_1_lint_block\n  - id: F-007\n    rule: Zirkuläre Imports\n    enforcement: gate_1_lint_block\n  - id: F-008\n    rule: God-Classes (> max_loc_per_class.hard)\n    enforcement: gate_1_lint_block\n  - id: F-009\n    rule: fetch() \/ XMLHttpRequest \/ jQuery.ajax im Frontend\n    detail: \"Pflicht: HTMX gemäß CLAUDE.md HTMX-C1..C5.\"\n    enforcement: gate_7_htmx_block\n  - id: F-010\n    rule: Secrets \/ Passwörter in Code oder Commands\n    detail: \"Aus Environment via get_db_password() \/ getenv('DB_PASSWORD').\"\n    enforcement: pre_hook_block\n  - id: F-011\n    rule: Mutating-Requests ohne CSRF (POST\/PUT\/PATCH\/DELETE)\n    enforcement: gate_7_htmx_block\n  - id: F-012\n    rule: SELECT * in Repositories\n    enforcement: gate_1_lint_block\n  - id: F-013\n    rule: Business-Logik in Controllers oder Views\n    enforcement: gate_4_architecture_block\n  - id: F-014\n    rule: time.sleep() in Tests\n    enforcement: gate_2_unit_block\n  - id: F-015\n    rule: Netzwerk-Zugriffe in Unit-Tests\n    enforcement: gate_2_unit_block\n  - id: F-016\n    rule: Auskommentierter Code im Commit\n    enforcement: gate_1_lint_block\n\n# ----------------------------------------------------------------------------\n# Pflicht (hard require)\n# ----------------------------------------------------------------------------\nrequired:\n  python:\n    type_hints:\n      mode: strict\n      tool: mypy --strict\n      coverage_percent: 100\n    entities_as: dataclass(frozen=True) oder pydantic.BaseModel\n    errors: spezifische Exception-Klassen pro Domain-Fehler\n    logging: structlog oder stdlib logging mit JSON-Formatter\n    io_boundary_only: Dateisystem\/Netzwerk nur in Infrastructure-Adaptern\n    docstrings:\n      public_api: required\n      private: optional\n  php:\n    declare_strict_types: true\n    return_types: required\n    param_types: required\n    property_types: required\n    phpstan_level: 8\n    readonly_where_possible: true\n    csrf_all_mutating: true\n    htmx_headers_pattern: gemäß CLAUDE.md Standard-Pattern\n\n# ----------------------------------------------------------------------------\n# Testing\n# ----------------------------------------------------------------------------\ntesting:\n  coverage:\n    project_min_percent: 85\n    domain_layer_min_percent: 95\n    application_layer_min_percent: 90\n  naming_pattern: \"test_<method>_<scenario>_<expected_result>\"\n  structure:\n    - tests\/unit\/domain\n    - tests\/unit\/application\n    - tests\/integration\/infrastructure\n    - tests\/e2e\n  constraints:\n    no_sleep: true\n    no_network_in_unit: true\n    no_db_in_unit: true\n    fixtures: pytest fixtures \/ PHPUnit data providers\n  required_for_each:\n    - domain_entity: Konstruktions-, Invarianten- und Equality-Tests\n    - use_case: mindestens Happy-Path + ein Fehlerpfad\n    - adapter: Integrationstest gegen reale Ressource (DB\/HTTP-Fixture)\n\n# ----------------------------------------------------------------------------\n# DB \/ Persistenz\n# ----------------------------------------------------------------------------\npersistence:\n  db_access: ausschließlich via MCP-DB oder infrastructure\/Repository-Adapter\n  no_orm_in_domain: true\n  migrations: versioniert unter src\/db\/migrations\/*.sql\n  transactions: pro Use Case genau eine Transaktion\n  bulk_insert_threshold: 100\n\n# ----------------------------------------------------------------------------\n# Quality Gateways (verbindlich; alle grün vor Deploy)\n# ----------------------------------------------------------------------------\nquality_gateways:\n  policy: all_must_pass\n  execution: script \/var\/www\/dev.campus.systemische-tools.de\/crawler\/scripts\/check.sh\n\n  gates:\n    - id: G1\n      name: Static Analysis\n      blocking: true\n      python:\n        - \"ruff check --select=ALL --ignore=D100,D104 src tests\"\n        - \"ruff format --check src tests\"\n        - \"mypy --strict src\"\n        - \"radon cc -s -n B src\"\n        - \"radon mi -s -n B src\"\n        - \"python scripts\/max_loc_linter.py src\"   # eigenes Tool: Klassen- und Methoden-LOC ohne Kommentare\/Blanks\n      php:\n        - \"\/var\/www\/scripts\/php-check.sh\"\n        - \"phpstan analyse --level=8 src\/Controller\/Crawler src\/Domain\/Crawler src\/Infrastructure\/Crawler src\/View\/crawler\"\n        - \"php-cs-fixer fix --dry-run --diff\"\n        - \"php scripts\/max_loc_linter.php src\/Controller\/Crawler src\/Infrastructure\/Crawler\"\n\n    - id: G2\n      name: Unit Tests\n      blocking: true\n      python: \"pytest tests\/unit -q --cov=src --cov-fail-under=85\"\n      php: \"phpunit --testsuite=crawler-unit --coverage-text\"\n\n    - id: G3\n      name: Integration Tests\n      blocking: true\n      preconditions: [crawler DB erreichbar, Playwright Chromium installiert]\n      python: \"pytest tests\/integration -q\"\n\n    - id: G4\n      name: Architecture \/ Dependency Direction\n      blocking: true\n      python: \"import-linter --config .import-linter\"\n      php: \"deptrac analyse deptrac.yaml\"\n\n    - id: G5\n      name: Security\n      blocking: true\n      tools:\n        - \"semgrep --config=auto --error\"\n        - \"pip-audit --strict\"\n        - \"composer audit\"\n        - \"gitleaks detect --no-git --source src --redact\"\n\n    - id: G6\n      name: DB-Schema-Drift\n   ... [TRUNCATED-d1001eae1053eb7d]"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/crawler\/planung\/01-code-standards.yaml",
        "content": "---\n# ============================================================================\n# Crawler – Code-Standards & Quality Gateways\n# ============================================================================\n# Verbindlich. Keine Umgehung. Alle Gateways müssen vor Merge\/Deploy passen.\n# Stand: 2026-04-21\n# ============================================================================\n\nmeta:\n  document: crawler-code-standards\n  version: 1.0.0\n  binding: true\n  last_updated: 2026-04-21\n  scope:\n    - python_core: \/var\/www\/dev.campus.systemische-tools.de\/crawler\/src\n    - php_presentation: \/var\/www\/dev.campus.systemische-tools.de\/src (Controller\/View unter Route \/crawler)\n\n# ----------------------------------------------------------------------------\n# Architektur\n# ----------------------------------------------------------------------------\narchitecture:\n  paradigm: Domain-Driven Design\n  style: Hexagonal (Ports and Adapters)\n  core_principles: [SRP, SoC, DRY, DIP, YAGNI]\n\n  layers:\n    domain:\n      responsibility: reine Geschäftslogik, Entities, Value Objects, Domain Services\n      imports_allowed: [stdlib, typing, dataclasses, datetime, hashlib, enum, re, abc]\n      imports_forbidden: [framework, db_driver, http_client, filesystem, third_party_business]\n    application:\n      responsibility: Use Cases, Orchestrierung, Ports (Interfaces zu Infrastructure)\n      imports_allowed: [domain, stdlib]\n      imports_forbidden: [infrastructure, interfaces, third_party_impl]\n    infrastructure:\n      responsibility: Adapter – DB, HTTP, Playwright, Filesystem, Logging\n      imports_allowed: [domain, application, stdlib, third_party]\n      imports_forbidden: [interfaces]\n    interfaces:\n      responsibility: CLI (Python), HTTP-Controller + Views (PHP), HTMX\n      imports_allowed: [application, domain, stdlib, third_party_ui]\n      imports_forbidden: [infrastructure_internals]\n\n  dependency_direction: |\n    interfaces → application → domain\n    infrastructure → application, domain\n    Verletzungen → Gate 4 Failure.\n\n# ----------------------------------------------------------------------------\n# Harte Code-Metriken (nicht verhandelbar, nicht umgehbar)\n# ----------------------------------------------------------------------------\ncode_metrics:\n  max_loc_per_method:\n    soft: 50\n    hard: 80\n    excludes_from_count: [comments, docstrings, blank_lines, pure_type_stubs]\n    applies_to: [python_functions, python_methods, php_methods, php_functions]\n    enforcement: gate_1_lint_block\n\n  max_loc_per_class:\n    soft: 50\n    hard: 80\n    excludes_from_count: [comments, docstrings, blank_lines, class_attribute_declarations]\n    applies_to: [python_classes, php_classes]\n    note: \"SRP ernst nehmen – große Adapter in fokussierte Sub-Adapter aufteilen.\"\n    enforcement: gate_1_lint_block\n\n  max_loc_per_file:\n    hard: 200\n    excludes_from_count: [comments, docstrings, blank_lines]\n    enforcement: gate_1_lint_block\n\n  max_cyclomatic_complexity:\n    soft: 5\n    hard: 8\n    enforcement: gate_1_lint_block\n\n  max_method_parameters:\n    hard: 4\n    note: \"Mehr Parameter → Value Object \/ DTO einführen.\"\n    enforcement: gate_1_lint_block\n\n  max_nesting_depth:\n    hard: 3\n    enforcement: gate_1_lint_block\n\n  max_return_points_per_method:\n    hard: 4\n    enforcement: gate_1_lint_warn\n\n# ----------------------------------------------------------------------------\n# Naming\n# ----------------------------------------------------------------------------\nnaming:\n  python:\n    modules: snake_case\n    classes: PascalCase\n    functions: snake_case\n    methods: snake_case\n    constants: UPPER_SNAKE_CASE\n    private_members: _leading_underscore\n    type_aliases: PascalCase\n    test_files: \"test_*.py\"\n  php:\n    namespaces: PascalCase\n    classes: PascalCase\n    interfaces: \"*Interface oder *Port\"\n    methods: camelCase\n    constants: UPPER_SNAKE_CASE\n    properties: camelCase\n\n# ----------------------------------------------------------------------------\n# Verboten (hard fail)\n# ----------------------------------------------------------------------------\nforbidden:\n  - id: F-001\n    rule: Magic Numbers\n    detail: \"Zahlenliterale außerhalb von 0, 1, -1 nur via Constants::* bzw. constants.*\"\n    enforcement: gate_1_lint_block\n  - id: F-002\n    rule: Direkter SQL-Zugriff außerhalb Infrastructure-Repositories\n    enforcement: gate_4_architecture_block\n  - id: F-003\n    rule: Framework-Imports in Domain\/Application\n    enforcement: gate_4_architecture_block\n  - id: F-004\n    rule: Globaler veränderlicher Zustand (modul-level mutable state)\n    enforcement: gate_1_lint_block\n  - id: F-005\n    rule: print() \/ var_dump() \/ echo-Debug\n    detail: \"Ausschließlich Logging-Adapter verwenden.\"\n    enforcement: gate_1_lint_block\n  - id: F-006\n    rule: Bare except \/ catch(\\Throwable) außerhalb Interfaces-Layer-Edge\n    enforcement: gate_1_lint_block\n  - id: F-007\n    rule: Zirkuläre Imports\n    enforcement: gate_1_lint_block\n  - id: F-008\n    rule: God-Classes (> max_loc_per_class.hard)\n    enforcement: gate_1_lint_block\n  - id: F-009\n    rule: fetch() \/ XMLHttpRequest \/ jQuery.ajax im Frontend\n    detail: \"Pflicht: HTMX gemäß CLAUDE.md HTMX-C1..C5.\"\n    enforcement: gate_7_htmx_block\n  - id: F-010\n    rule: Secrets \/ Passwörter in Code oder Commands\n    detail: \"Aus Environment via get_db_password() \/ getenv('DB_PASSWORD').\"\n    enforcement: pre_hook_block\n  - id: F-011\n    rule: Mutating-Requests ohne CSRF (POST\/PUT\/PATCH\/DELETE)\n    enforcement: gate_7_htmx_block\n  - id: F-012\n    rule: SELECT * in Repositories\n    enforcement: gate_1_lint_block\n  - id: F-013\n    rule: Business-Logik in Controllers oder Views\n    enforcement: gate_4_architecture_block\n  - id: F-014\n    rule: time.sleep() in Tests\n    enforcement: gate_2_unit_block\n  - id: F-015\n    rule: Netzwerk-Zugriffe in Unit-Tests\n    enforcement: gate_2_unit_block\n  - id: F-016\n    rule: Auskommentierter Code im Commit\n    enforcement: gate_1_lint_block\n\n# ----------------------------------------------------------------------------\n# Pflicht (hard require)\n# ----------------------------------------------------------------------------\nrequired:\n  python:\n    type_hints:\n      mode: strict\n      tool: mypy --strict\n      coverage_percent: 100\n    entities_as: dataclass(frozen=True) oder pydantic.BaseModel\n    errors: spezifische Exception-Klassen pro Domain-Fehler\n    logging: structlog oder stdlib logging mit JSON-Formatter\n    io_boundary_only: Dateisystem\/Netzwerk nur in Infrastructure-Adaptern\n    docstrings:\n      public_api: required\n      private: optional\n  php:\n    declare_strict_types: true\n    return_types: required\n    param_types: required\n    property_types: required\n    phpstan_level: 8\n    readonly_where_possible: true\n    csrf_all_mutating: true\n    htmx_headers_pattern: gemäß CLAUDE.md Standard-Pattern\n\n# ----------------------------------------------------------------------------\n# Testing\n# ----------------------------------------------------------------------------\ntesting:\n  coverage:\n    project_min_percent: 85\n    domain_layer_min_percent: 95\n    application_layer_min_percent: 90\n  naming_pattern: \"test_<method>_<scenario>_<expected_result>\"\n  structure:\n    - tests\/unit\/domain\n    - tests\/unit\/application\n    - tests\/integration\/infrastructure\n    - tests\/e2e\n  constraints:\n    no_sleep: true\n    no_network_in_unit: true\n    no_db_in_unit: true\n    fixtures: pytest fixtures \/ PHPUnit data providers\n  required_for_each:\n    - domain_entity: Konstruktions-, Invarianten- und Equality-Tests\n    - use_case: mindestens Happy-Path + ein Fehlerpfad\n    - adapter: Integrationstest gegen reale Ressource (DB\/HTTP-Fixture)\n\n# ----------------------------------------------------------------------------\n# DB \/ Persistenz\n# ----------------------------------------------------------------------------\npersistence:\n  db_access: ausschließlich via MCP-DB oder infrastructure\/Repository-Adapter\n  no_orm_in_domain: true\n  migrations: versioniert unter src\/db\/migrations\/*.sql\n  transactions: pro Use Case genau eine Transaktion\n  bulk_insert_threshold: 100\n\n# ----------------------------------------------------------------------------\n# Quality Gateways (verbindlich; alle grün vor Deploy)\n# ----------------------------------------------------------------------------\nquality_gateways:\n  policy: all_must_pass\n  execution: script \/var\/www\/dev.campus.systemische-tools.de\/crawler\/scripts\/check.sh\n\n  gates:\n    - id: G1\n      name: Static Analysis\n      blocking: true\n      python:\n        - \"ruff check --select=ALL --ignore=D100,D104 src tests\"\n        - \"ruff format --check src tests\"\n        - \"mypy --strict src\"\n        - \"radon cc -s -n B src\"\n        - \"radon mi -s -n B src\"\n        - \"python scripts\/max_loc_linter.py src\"   # eigenes Tool: Klassen- und Methoden-LOC ohne Kommentare\/Blanks\n      php:\n        - \"\/var\/www\/scripts\/php-check.sh\"\n        - \"phpstan analyse --level=8 src\/Controller\/Crawler src\/Domain\/Crawler src\/Infrastructure\/Crawler src\/View\/crawler\"\n        - \"php-cs-fixer fix --dry-run --diff\"\n        - \"php scripts\/max_loc_linter.php src\/Controller\/Crawler src\/Infrastructure\/Crawler\"\n\n    - id: G2\n      name: Unit Tests\n      blocking: true\n      python: \"pytest tests\/unit -q --cov=src --cov-fail-under=85\"\n      php: \"phpunit --testsuite=crawler-unit --coverage-text\"\n\n    - id: G3\n      name: Integration Tests\n      blocking: true\n      preconditions: [crawler DB erreichbar, Playwright Chromium installiert]\n      python: \"pytest tests\/integration -q\"\n\n    - id: G4\n      name: Architecture \/ Dependency Direction\n      blocking: true\n      python: \"import-linter --config .import-linter\"\n      php: \"deptrac analyse deptrac.yaml\"\n\n    - id: G5\n      name: Security\n      blocking: true\n      tools:\n        - \"semgrep --config=auto --error\"\n        - \"pip-audit --strict\"\n        - \"composer audit\"\n        - \"gitleaks detect --no-git --source src --redact\"\n\n    - id: G6\n      name: DB-Schema-Drift\n   ... [TRUNCATED-d1001eae1053eb7d]",
        "structuredPatch": [],
        "originalFile": null,
        "userModified": false
    }
}
← Vorheriger Zur Liste Nächster →