{
"tool_response": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ProtokollController.php",
"oldString": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\n\n\/**\n * ProtokollController - KI-Protokoll Ansicht\n *\n * Zeigt KI-Interaktionen aus ki_dev.protokoll.\n * Nur Lesen, kein Erstellen\/Bearbeiten.\n *\/\nclass ProtokollController extends Controller\n{\n private \\PDO $db;\n\n public function __construct()\n {\n $this->db = new \\PDO(\n 'mysql:host=localhost;dbname=ki_dev;charset=utf8mb4',\n 'root',\n $this->getPassword(),\n [\n \\PDO::ATTR_ERRMODE => \\PDO::ERRMODE_EXCEPTION,\n \\PDO::ATTR_DEFAULT_FETCH_MODE => \\PDO::FETCH_ASSOC,\n ]\n );\n }\n\n private function getPassword(): string\n {\n $file = '\/var\/www\/docs\/credentials\/credentials.md';\n $content = file_get_contents($file);\n foreach (explode(\"\\n\", $content) as $line) {\n if (str_contains($line, 'MariaDB') && str_contains($line, 'root')) {\n $parts = explode('|', $line);\n if (count($parts) >= 4) {\n return trim($parts[3]);\n }\n }\n }\n\n return '';\n }",
"newString": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse Infrastructure\\Config\\DatabaseFactory;\n\n\/**\n * ProtokollController - KI-Protokoll Ansicht\n *\n * Zeigt KI-Interaktionen aus ki_dev.protokoll.\n * Nur Lesen, kein Erstellen\/Bearbeiten.\n *\/\nclass ProtokollController extends Controller\n{\n private \\PDO $db;\n\n public function __construct()\n {\n $this->db = DatabaseFactory::dev();\n }",
"originalFile": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\n\n\/**\n * ProtokollController - KI-Protokoll Ansicht\n *\n * Zeigt KI-Interaktionen aus ki_dev.protokoll.\n * Nur Lesen, kein Erstellen\/Bearbeiten.\n *\/\nclass ProtokollController extends Controller\n{\n private \\PDO $db;\n\n public function __construct()\n {\n $this->db = new \\PDO(\n 'mysql:host=localhost;dbname=ki_dev;charset=utf8mb4',\n 'root',\n $this->getPassword(),\n [\n \\PDO::ATTR_ERRMODE => \\PDO::ERRMODE_EXCEPTION,\n \\PDO::ATTR_DEFAULT_FETCH_MODE => \\PDO::FETCH_ASSOC,\n ]\n );\n }\n\n private function getPassword(): string\n {\n $file = '\/var\/www\/docs\/credentials\/credentials.md';\n $content = file_get_contents($file);\n foreach (explode(\"\\n\", $content) as $line) {\n if (str_contains($line, 'MariaDB') && str_contains($line, 'root')) {\n $parts = explode('|', $line);\n if (count($parts) >= 4) {\n return trim($parts[3]);\n }\n }\n }\n\n return '';\n }\n\n \/**\n * GET \/protokoll\n * Liste aller Protokoll-Einträge\n *\/\n public function index(): void\n {\n \/\/ Statistiken\n $stats = $this->db->query(\n 'SELECT\n COUNT(*) as total,\n SUM(CASE WHEN status = \"completed\" THEN 1 ELSE 0 END) as completed,\n SUM(CASE WHEN status = \"error\" THEN 1 ELSE 0 END) as errors,\n COALESCE(SUM(tokens_total), 0) as tokens_total,\n COALESCE(SUM(duration_ms), 0) as duration_total\n FROM protokoll'\n )->fetch();\n\n \/\/ Einträge mit Pagination\n $page = max(1, (int) ($_GET['page'] ?? 1));\n $limit = 50;\n $offset = ($page - 1) * $limit;\n\n $search = $_GET['search'] ?? '';\n $status = $_GET['status'] ?? '';\n $model = $_GET['model'] ?? '';\n\n $sql = 'SELECT id, timestamp, client_name, model_name, status, tokens_total, duration_ms,\n LEFT(request, 200) as request_preview\n FROM protokoll WHERE 1=1';\n $countSql = 'SELECT COUNT(*) FROM protokoll WHERE 1=1';\n $params = [];\n\n if ($search !== '') {\n $sql .= ' AND (request LIKE :search OR response LIKE :search2 OR client_name LIKE :search3)';\n $countSql .= ' AND (request LIKE :search OR response LIKE :search2 OR client_name LIKE :search3)';\n $params['search'] = '%' . $search . '%';\n $params['search2'] = '%' . $search . '%';\n $params['search3'] = '%' . $search . '%';\n }\n\n if ($status !== '') {\n $sql .= ' AND status = :status';\n $countSql .= ' AND status = :status';\n $params['status'] = $status;\n }\n\n if ($model !== '') {\n $sql .= ' AND model_name = :model';\n $countSql .= ' AND model_name = :model';\n $params['model'] = $model;\n }\n\n \/\/ Total count\n $countStmt = $this->db->prepare($countSql);\n $countStmt->execute($params);\n $totalCount = (int) $countStmt->fetchColumn();\n\n \/\/ Fetch entries\n $sql .= ' ORDER BY timestamp DESC LIMIT ' . $limit . ' OFFSET ' . $offset;\n $stmt = $this->db->prepare($sql);\n $stmt->execute($params);\n $entries = $stmt->fetchAll();\n\n \/\/ Modelle für Filter\n $models = $this->db->query(\n 'SELECT DISTINCT model_name FROM protokoll WHERE model_name IS NOT NULL ORDER BY model_name'\n )->fetchAll(\\PDO::FETCH_COLUMN);\n\n $this->view('protokoll.index', [\n 'title' => 'KI-Protokoll',\n 'stats' => $stats,\n 'entries' => $entries,\n 'models' => $models,\n 'currentSearch' => $search,\n 'currentStatus' => $status,\n 'currentModel' => $model,\n 'currentPage' => $page,\n 'totalCount' => $totalCount,\n 'totalPages' => ceil($totalCount \/ $limit),\n ]);\n }\n\n \/**\n * GET \/protokoll\/{id}\n * Detail-Ansicht eines Eintrags\n *\/\n public function show(string $id): void\n {\n $stmt = $this->db->prepare('SELECT * FROM protokoll WHERE id = :id');\n $stmt->execute(['id' => (int) $id]);\n $entry = $stmt->fetch();\n\n if ($entry === false) {\n http_response_code(404);\n echo '404 - Protokoll-Eintrag nicht gefunden';\n\n return;\n }\n\n \/\/ Request\/Response als formatiertes JSON\n $entry['request_formatted'] = $this->formatJson($entry['request']);\n $entry['response_formatted'] = $this->formatJson($entry['response']);\n\n \/\/ Nachbar-Einträge für Navigation\n $stmt = $this->db->prepare('SELECT id FROM protokoll WHERE id < :id ORDER BY id DESC LIMIT 1');\n $stmt->execute(['id' => (int) $id]);\n $prevEntry = $stmt->fetch();\n\n $stmt = $this->db->prepare('SELECT id FROM protokoll WHERE id > :id ORDER BY id ASC LIMIT 1');\n $stmt->execute(['id' => (int) $id]);\n $nextEntry = $stmt->fetch();\n\n $this->view('protokoll.show', [\n 'title' => 'Protokoll #' . $id,\n 'entry' => $entry,\n 'prevEntry' => $prevEntry,\n 'nextEntry' => $nextEntry,\n ]);\n }\n\n \/**\n * JSON formatieren für Anzeige\n *\/\n private function formatJson(?string $json): string\n {\n if ($json === null || $json === '') {\n return '-';\n }\n\n $decoded = json_decode($json, true);\n if ($decoded === null) {\n return htmlspecialchars($json);\n }\n\n return json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n }\n}\n",
"structuredPatch": [
{
"oldStart": 3,
"oldLines": 6,
"newStart": 3,
"newLines": 7,
"lines": [
" namespace Controller;",
" ",
" use Framework\\Controller;",
"+use Infrastructure\\Config\\DatabaseFactory;",
" ",
" \/**",
" * ProtokollController - KI-Protokoll Ansicht"
]
},
{
"oldStart": 16,
"oldLines": 33,
"newStart": 17,
"newLines": 9,
"lines": [
" ",
" public function __construct()",
" {",
"- $this->db = new \\PDO(",
"- 'mysql:host=localhost;dbname=ki_dev;charset=utf8mb4',",
"- 'root',",
"- $this->getPassword(),",
"- [",
"- \\PDO::ATTR_ERRMODE => \\PDO::ERRMODE_EXCEPTION,",
"- \\PDO::ATTR_DEFAULT_FETCH_MODE => \\PDO::FETCH_ASSOC,",
"- ]",
"- );",
"+ $this->db = DatabaseFactory::dev();",
" }",
" ",
"- private function getPassword(): string",
"- {",
"- $file = '\/var\/www\/docs\/credentials\/credentials.md';",
"- $content = file_get_contents($file);",
"- foreach (explode(\"\\n\", $content) as $line) {",
"- if (str_contains($line, 'MariaDB') && str_contains($line, 'root')) {",
"- $parts = explode('|', $line);",
"- if (count($parts) >= 4) {",
"- return trim($parts[3]);",
"- }",
"- }",
"- }",
"-",
"- return '';",
"- }",
"-",
" \/**",
" * GET \/protokoll",
" * Liste aller Protokoll-Einträge"
]
}
],
"userModified": false,
"replaceAll": false
}
}