{
"event": "PreToolUse",
"tool_name": "Edit",
"tool_input": {
"file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ProtokollController.php",
"old_string": " \/\/ Einträge mit Pagination\n $page = $this->getPage();\n $limit = 50;\n $offset = ($page - 1) * $limit;\n\n $search = $this->getString('search');\n $status = $this->getString('status');\n $model = $this->getString('model');",
"new_string": " \/\/ Einträge mit Pagination\n $pagination = Pagination::fromRequest(50);\n\n $search = $this->getString('search');\n $status = $this->getString('status');\n $model = $this->getString('model');"
}
}
{
"tool_response": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ProtokollController.php",
"oldString": " \/\/ Einträge mit Pagination\n $page = $this->getPage();\n $limit = 50;\n $offset = ($page - 1) * $limit;\n\n $search = $this->getString('search');\n $status = $this->getString('status');\n $model = $this->getString('model');",
"newString": " \/\/ Einträge mit Pagination\n $pagination = Pagination::fromRequest(50);\n\n $search = $this->getString('search');\n $status = $this->getString('status');\n $model = $this->getString('model');",
"originalFile": "<?php\n\nnamespace Controller;\n\nuse Domain\\ValueObject\\Pagination;\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 }\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 = $this->getPage();\n $limit = 50;\n $offset = ($page - 1) * $limit;\n\n $search = $this->getString('search');\n $status = $this->getString('status');\n $model = $this->getString('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 foreach ($params as $key => $value) {\n $stmt->bindValue(':' . $key, $value);\n }\n $stmt->bindValue(':limit', $limit, \\PDO::PARAM_INT);\n $stmt->bindValue(':offset', $offset, \\PDO::PARAM_INT);\n $stmt->execute();\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 $this->notFound('Protokoll-Eintrag nicht gefunden');\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": 39,
"oldLines": 9,
"newStart": 39,
"newLines": 7,
"lines": [
" )->fetch();",
" ",
" \/\/ Einträge mit Pagination",
"- $page = $this->getPage();",
"- $limit = 50;",
"- $offset = ($page - 1) * $limit;",
"+ $pagination = Pagination::fromRequest(50);",
" ",
" $search = $this->getString('search');",
" $status = $this->getString('status');"
]
}
],
"userModified": false,
"replaceAll": false
}
}