Protokoll #4545

ID4545
Zeitstempel2025-12-22 10:13:37.457764
Clientroot
IP145.224.96.190
Modellclaude-sonnet-4-20250514
Statuspending
Tokens2,313 (Input: 2,313, Output: 0)
Dauer-
Request-Zeit2025-12-22 10:13:37.457764
Response-Zeit-

Request

{
    "event": "PostToolUse",
    "raw_data": {
        "session_id": "18ef5bf3-e872-4052-897e-53d6dc45b0b9",
        "transcript_path": "\/root\/.claude\/projects\/-var-www\/18ef5bf3-e872-4052-897e-53d6dc45b0b9.jsonl",
        "cwd": "\/var\/www",
        "permission_mode": "acceptEdits",
        "hook_event_name": "PostToolUse",
        "tool_name": "Read",
        "tool_input": {
            "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/CriticsController.php"
        },
        "tool_response": {
            "type": "text",
            "file": {
                "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/CriticsController.php",
                "content": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse Infrastructure\\Config\\DatabaseFactory;\n\nclass CriticsController extends Controller\n{\n    private \\PDO $db;\n\n    public function __construct()\n    {\n        $this->db = DatabaseFactory::content();\n    }\n\n    \/**\n     * GET \/critics\n     *\/\n    public function index(): void\n    {\n        $stmt = $this->db->query('\n            SELECT c.*, p.name as prompt_name\n            FROM critics c\n            LEFT JOIN prompts p ON c.prompt_id = p.id\n            ORDER BY c.sort_order, c.name\n        ');\n        $critics = $stmt->fetchAll(\\PDO::FETCH_ASSOC);\n\n        $stats = $this->getStatistics();\n\n        $this->view('critics.index', [\n            'title' => 'Critics verwalten',\n            'critics' => $critics,\n            'stats' => $stats,\n        ]);\n    }\n\n    \/**\n     * GET \/critics\/new\n     *\/\n    public function criticsNew(): void\n    {\n        $prompts = $this->getAvailablePrompts();\n\n        $this->view('critics.form', [\n            'title' => 'Neuer Critic',\n            'critic' => null,\n            'prompts' => $prompts,\n            'isEdit' => false,\n        ]);\n    }\n\n    \/**\n     * POST \/critics\n     *\/\n    public function store(): void\n    {\n        $this->requireCsrf();\n\n        $name = trim($_POST['name'] ?? '');\n        $fokus = $_POST['fokus'] ?? '';\n        $promptId = !empty($_POST['prompt_id']) ? (int) $_POST['prompt_id'] : null;\n        $sortOrder = (int) ($_POST['sort_order'] ?? 0);\n        $isActive = isset($_POST['is_active']) ? 1 : 0;\n\n        if ($name === '') {\n            $_SESSION['error'] = 'Name ist erforderlich.';\n            header('Location: \/critics\/new');\n            exit;\n        }\n\n        \/\/ Fokus als JSON Array speichern\n        $fokusArray = array_filter(array_map('trim', explode(\"\\n\", $fokus)));\n        $fokusJson = json_encode(array_values($fokusArray), JSON_UNESCAPED_UNICODE);\n\n        $stmt = $this->db->prepare('\n            INSERT INTO critics (name, fokus, prompt_id, sort_order, is_active)\n            VALUES (?, ?, ?, ?, ?)\n        ');\n        $stmt->execute([$name, $fokusJson, $promptId, $sortOrder, $isActive]);\n        $id = $this->db->lastInsertId();\n\n        $_SESSION['success'] = 'Critic erfolgreich erstellt.';\n        header('Location: \/critics\/' . $id);\n        exit;\n    }\n\n    \/**\n     * GET \/critics\/{id}\n     *\/\n    public function show(string $id): void\n    {\n        $critic = $this->findById((int) $id);\n\n        if ($critic === null) {\n            $this->notFound('Critic nicht gefunden');\n        }\n\n        \/\/ Prompt-Details laden\n        $prompt = null;\n        if ($critic['prompt_id']) {\n            $stmt = $this->db->prepare('SELECT * FROM prompts WHERE id = ?');\n            $stmt->execute([$critic['prompt_id']]);\n            $prompt = $stmt->fetch(\\PDO::FETCH_ASSOC);\n        }\n\n        \/\/ Letzte Critiques anzeigen\n        $stmt = $this->db->prepare('\n            SELECT cc.*, cv.version_number, co.title as order_title\n            FROM content_critiques cc\n            JOIN content_versions cv ON cc.version_id = cv.id\n            JOIN content_orders co ON cv.order_id = co.id\n            WHERE cc.critic_id = ?\n            ORDER BY cc.created_at DESC\n            LIMIT 10\n        ');\n        $stmt->execute([$id]);\n        $recentCritiques = $stmt->fetchAll(\\PDO::FETCH_ASSOC);\n\n        $this->view('critics.show', [\n            'title' => $critic['name'],\n            'critic' => $critic,\n            'prompt' => $prompt,\n            'recentCritiques' => $recentCritiques,\n        ]);\n    }\n\n    \/**\n     * GET \/critics\/{id}\/edit\n     *\/\n    public function edit(string $id): void\n    {\n        $critic = $this->findById((int) $id);\n\n        if ($critic === null) {\n            $this->notFound('Critic nicht gefunden');\n        }\n\n        $prompts = $this->getAvailablePrompts();\n\n        $this->view('critics.form', [\n            'title' => 'Bearbeiten: ' . $critic['name'],\n            'critic' => $critic,\n            'prompts' => $prompts,\n            'isEdit' => true,\n        ]);\n    }\n\n    \/**\n     * POST \/critics\/{id}\n     *\/\n    public function update(string $id): void\n    {\n        $this->requireCsrf();\n\n        $critic = $this->findById((int) $id);\n\n        if ($critic === null) {\n            $this->notFound('Critic nicht gefunden');\n        }\n\n        $name = trim($_POST['name'] ?? '');\n        $fokus = $_POST['fokus'] ?? '';\n        $promptId = !empty($_POST['prompt_id']) ? (int) $_POST['prompt_id'] : null;\n        $sortOrder = (int) ($_POST['sort_order'] ?? 0);\n        $isActive = isset($_POST['is_active']) ? 1 : 0;\n\n        if ($name === '') {\n            $_SESSION['error'] = 'Name ist erforderlich.';\n            header('Location: \/critics\/' . $id . '\/edit');\n            exit;\n        }\n\n        \/\/ Fokus als JSON Array speichern\n        $fokusArray = array_filter(array_map('trim', explode(\"\\n\", $fokus)));\n        $fokusJson = json_encode(array_values($fokusArray), JSON_UNESCAPED_UNICODE);\n\n        $stmt = $this->db->prepare('\n            UPDATE critics\n            SET name = ?, fokus = ?, prompt_id = ?, sort_order = ?, is_active = ?\n            WHERE id = ?\n        ');\n        $stmt->execute([$name, $fokusJson, $promptId, $sortOrder, $isActive, $id]);\n\n        $_SESSION['success'] = 'Critic aktualisiert.';\n        header('Location: \/critics\/' . $id);\n        exit;\n    }\n\n    \/**\n     * POST \/critics\/{id}\/delete\n     *\/\n    public function delete(string $id): void\n    {\n        $this->requireCsrf();\n\n        $critic = $this->findById((int) $id);\n\n        if ($critic === null) {\n            $this->notFound('Critic nicht gefunden');\n        }\n\n        \/\/ Prüfen ob Critiques existieren\n        $stmt = $this->db->prepare('SELECT COUNT(*) FROM content_critiques WHERE critic_id = ?');\n        $stmt->execute([$id]);\n        $critiqueCount = (int) $stmt->fetchColumn();\n\n        if ($critiqueCount > 0) {\n            $_SESSION['error'] = \"Kann nicht gelöscht werden: {$critiqueCount} Critiques verknüpft.\";\n            header('Location: \/critics\/' . $id);\n            exit;\n        }\n\n        $stmt = $this->db->prepare('DELETE FROM critics WHERE id = ?');\n        $stmt->execute([$id]);\n\n        $_SESSION['success'] = 'Critic gelöscht.';\n        header('Location: \/critics');\n        exit;\n    }\n\n    \/**\n     * POST \/critics\/{id}\/toggle\n     *\/\n    public function toggle(string $id): void\n    {\n        $this->requireCsrf();\n\n        $critic = $this->findById((int) $id);\n\n        if ($critic === null) {\n            $this->notFound('Critic nicht gefunden');\n        }\n\n        $newStatus = $critic['is_active'] ? 0 : 1;\n        $stmt = $this->db->prepare('UPDATE critics SET is_active = ? WHERE id = ?');\n        $stmt->execute([$newStatus, $id]);\n\n        $statusText = $newStatus ? 'aktiviert' : 'deaktiviert';\n        $_SESSION['success'] = \"Critic {$statusText}.\";\n        header('Location: \/critics');\n        exit;\n    }\n\n    \/\/ ========== Private Helpers ==========\n\n    private function findById(int $id): ?array\n    {\n        $stmt = $this->db->prepare('\n            SELECT c.*, p.name as prompt_name\n            FROM critics c\n            LEFT JOIN prompts p ON c.prompt_id = p.id\n            WHERE c.id = ?\n        ');\n        $stmt->execute([$id]);\n        $result = $stmt->fetch(\\PDO::FETCH_ASSOC);\n\n        return $result !== false ? $result : null;\n    }\n\n    private function getAvailablePrompts(): array\n    {\n        $stmt = $this->db->query('\n            SELECT id, name, version\n            FROM prompts\n            WHERE is_active = 1\n            ORDER BY name\n        ');\n\n        return $stmt->fetchAll(\\PDO::FETCH_ASSOC);\n    }\n\n    private function getStatistics(): array\n    {\n        $stats = ['total' => 0, 'active' => 0, 'inactive' => 0, 'total_critiques' => 0];\n\n        $stmt = $this->db->query('SELECT COUNT(*) as cnt, SUM(is_active) as active FROM critics');\n        $row = $stmt->fetch(\\PDO::FETCH_ASSOC);\n        $stats['total'] = (int) $row['cnt'];\n        $stats['active'] = (int) $row['active'];\n        $stats['inactive'] = $stats['total'] - $stats['active'];\n\n        $stmt = $this->db->query('SELECT COUNT(*) FROM content_critiques');\n        $stats['total_critiques'] = (int) $stmt->fetchColumn();\n\n        return $stats;\n    }\n}\n",
                "numLines": 290,
                "startLine": 1,
                "totalLines": 290
            }
        },
        "tool_use_id": "toolu_01YMXx45DAddG5i15nXCNYyf"
    }
}

Response

-
← Vorheriger Zur Liste Nächster →