Protokoll #27979

ID27979
Zeitstempel2025-12-28 12:38:48.959031
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens13,117 (Input: 2,657, Output: 10,460)
Dauer94 ms
Request-Zeit2025-12-28 12:38:48.959031
Response-Zeit2025-12-28 12:38:49.053257

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/mcp-servers\/mcp_docs\/infrastructure\/docs_repository.py",
        "content": "\"\"\"Repository für Dokumentation CRUD-Operationen.\"\"\"\n\nfrom datetime import datetime\nfrom typing import Any, Dict, List, Optional\n\nfrom config import Config\nfrom domain.dokumentation import DocStatus, Dokumentation\nfrom shared.infrastructure import SimpleDbConnection\n\n\nclass DocsRepository:\n    \"\"\"Repository für ki_system.dokumentation Tabelle.\"\"\"\n\n    def find_by_id(self, doc_id: int) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach ID.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE id = %s\", (doc_id,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_path(self, path: str) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Pfad.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE path = %s\", (path,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_slug(\n        self, slug: str, parent_id: Optional[int] = None\n    ) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Slug (optional mit Parent).\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                if parent_id is not None:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id = %s\",\n                        (slug, parent_id),\n                    )\n                else:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id IS NULL\",\n                        (slug,),\n                    )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_all(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n        limit: int = 20,\n        offset: int = 0,\n    ) -> List[Dokumentation]:\n        \"\"\"Findet alle Dokumente mit optionalen Filtern.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params: List[Any] = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\n                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"\n                    )\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                # Limit begrenzen\n                limit = min(limit, Config.MAX_RESULTS)\n\n                sql = f\"\"\"\n                    SELECT * FROM dokumentation\n                    WHERE {where_clause}\n                    ORDER BY depth, sort_order, title\n                    LIMIT %s OFFSET %s\n                \"\"\"\n                params.extend([limit, offset])\n\n                cursor.execute(sql, params)\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_children(self, parent_id: int) -> List[Dokumentation]:\n        \"\"\"Findet alle direkten Kinder eines Dokuments.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id = %s\n                    ORDER BY sort_order, title\"\"\",\n                    (parent_id,),\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_root_documents(self) -> List[Dokumentation]:\n        \"\"\"Findet alle Root-Dokumente (ohne Parent).\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id IS NULL\n                    ORDER BY sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def get_hierarchy(self) -> List[Dict[str, Any]]:\n        \"\"\"Gibt kompletten Dokumentationsbaum zurück.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT id, parent_id, slug, path, title, status, sort_order, depth\n                    FROM dokumentation\n                    ORDER BY depth, sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n\n        # Baum aufbauen\n        docs_by_id = {row[\"id\"]: {**row, \"children\": []} for row in rows}\n        roots = []\n\n        for row in rows:\n            doc = docs_by_id[row[\"id\"]]\n            if row[\"parent_id\"] is None:\n                roots.append(doc)\n            elif row[\"parent_id\"] in docs_by_id:\n                docs_by_id[row[\"parent_id\"]][\"children\"].append(doc)\n\n        return roots\n\n    def get_breadcrumb(self, doc_id: int) -> List[Dict[str, Any]]:\n        \"\"\"Gibt Breadcrumb-Pfad für ein Dokument zurück.\"\"\"\n        breadcrumb: List[Dict[str, Any]] = []\n        current_id: Optional[int] = doc_id\n\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                while current_id is not None:\n                    cursor.execute(\n                        \"SELECT id, parent_id, path, title FROM dokumentation WHERE id = %s\",\n                        (current_id,),\n                    )\n                    row = cursor.fetchone()\n                    if row:\n                        breadcrumb.insert(\n                            0,\n                            {\n                                \"id\": row[\"id\"],\n                                \"path\": row[\"path\"],\n                                \"title\": row[\"title\"],\n                            },\n                        )\n                        current_id = row[\"parent_id\"]\n                    else:\n                        break\n\n        return breadcrumb\n\n    def get_siblings(self, doc_id: int) -> List[Dokumentation]:\n        \"\"\"Findet Geschwister-Dokumente (gleicher Parent).\"\"\"\n        doc = self.find_by_id(doc_id)\n        if not doc:\n            return []\n\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                if doc.parent_id is not None:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id = %s AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc.parent_id, doc_id),\n                    )\n                else:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id IS NULL AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc_id,),\n                    )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def count(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n    ) -> int:\n        \"\"\"Zählt Dokumente mit optionalen Filtern.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params: List[Any] = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\n                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"\n                    )\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                cursor.execute(\n                    f\"SELECT COUNT(*) as count FROM dokumentation WHERE {where_clause}\",\n                    params,\n                )\n                result = cursor.fetchone()\n                return result[\"count\"] if result else 0\n\n    def create(self, doc: Dokumentation) -> int:\n        \"\"\"Erstellt neues Dokument, gibt ID zurück.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                now = datetime.now()\n                cursor.execute(\n                    \"\"\"INSERT INTO dokumentation\n                    (parent_id, slug, path, title, description, content, status,\n                     sort_order, depth, created_at, updated_at)\n                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\"\"\",\n                    (\n                        doc.parent_id,\n                        doc.slug,\n                        doc.path,\n                        doc.title,\n                        doc.description,\n                        doc.content,\n                        doc.status.value\n                        if isinstance(doc.status, DocStatus)\n                        else d... [TRUNCATED-e6e81cf9864f22cf]"
    }
}

Response

{
    "tool_response": {
        "type": "update",
        "filePath": "\/var\/www\/mcp-servers\/mcp_docs\/infrastructure\/docs_repository.py",
        "content": "\"\"\"Repository für Dokumentation CRUD-Operationen.\"\"\"\n\nfrom datetime import datetime\nfrom typing import Any, Dict, List, Optional\n\nfrom config import Config\nfrom domain.dokumentation import DocStatus, Dokumentation\nfrom shared.infrastructure import SimpleDbConnection\n\n\nclass DocsRepository:\n    \"\"\"Repository für ki_system.dokumentation Tabelle.\"\"\"\n\n    def find_by_id(self, doc_id: int) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach ID.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE id = %s\", (doc_id,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_path(self, path: str) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Pfad.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE path = %s\", (path,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_slug(\n        self, slug: str, parent_id: Optional[int] = None\n    ) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Slug (optional mit Parent).\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                if parent_id is not None:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id = %s\",\n                        (slug, parent_id),\n                    )\n                else:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id IS NULL\",\n                        (slug,),\n                    )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_all(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n        limit: int = 20,\n        offset: int = 0,\n    ) -> List[Dokumentation]:\n        \"\"\"Findet alle Dokumente mit optionalen Filtern.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params: List[Any] = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\n                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"\n                    )\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                # Limit begrenzen\n                limit = min(limit, Config.MAX_RESULTS)\n\n                sql = f\"\"\"\n                    SELECT * FROM dokumentation\n                    WHERE {where_clause}\n                    ORDER BY depth, sort_order, title\n                    LIMIT %s OFFSET %s\n                \"\"\"\n                params.extend([limit, offset])\n\n                cursor.execute(sql, params)\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_children(self, parent_id: int) -> List[Dokumentation]:\n        \"\"\"Findet alle direkten Kinder eines Dokuments.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id = %s\n                    ORDER BY sort_order, title\"\"\",\n                    (parent_id,),\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_root_documents(self) -> List[Dokumentation]:\n        \"\"\"Findet alle Root-Dokumente (ohne Parent).\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id IS NULL\n                    ORDER BY sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def get_hierarchy(self) -> List[Dict[str, Any]]:\n        \"\"\"Gibt kompletten Dokumentationsbaum zurück.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT id, parent_id, slug, path, title, status, sort_order, depth\n                    FROM dokumentation\n                    ORDER BY depth, sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n\n        # Baum aufbauen\n        docs_by_id = {row[\"id\"]: {**row, \"children\": []} for row in rows}\n        roots = []\n\n        for row in rows:\n            doc = docs_by_id[row[\"id\"]]\n            if row[\"parent_id\"] is None:\n                roots.append(doc)\n            elif row[\"parent_id\"] in docs_by_id:\n                docs_by_id[row[\"parent_id\"]][\"children\"].append(doc)\n\n        return roots\n\n    def get_breadcrumb(self, doc_id: int) -> List[Dict[str, Any]]:\n        \"\"\"Gibt Breadcrumb-Pfad für ein Dokument zurück.\"\"\"\n        breadcrumb: List[Dict[str, Any]] = []\n        current_id: Optional[int] = doc_id\n\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                while current_id is not None:\n                    cursor.execute(\n                        \"SELECT id, parent_id, path, title FROM dokumentation WHERE id = %s\",\n                        (current_id,),\n                    )\n                    row = cursor.fetchone()\n                    if row:\n                        breadcrumb.insert(\n                            0,\n                            {\n                                \"id\": row[\"id\"],\n                                \"path\": row[\"path\"],\n                                \"title\": row[\"title\"],\n                            },\n                        )\n                        current_id = row[\"parent_id\"]\n                    else:\n                        break\n\n        return breadcrumb\n\n    def get_siblings(self, doc_id: int) -> List[Dokumentation]:\n        \"\"\"Findet Geschwister-Dokumente (gleicher Parent).\"\"\"\n        doc = self.find_by_id(doc_id)\n        if not doc:\n            return []\n\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                if doc.parent_id is not None:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id = %s AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc.parent_id, doc_id),\n                    )\n                else:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id IS NULL AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc_id,),\n                    )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def count(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n    ) -> int:\n        \"\"\"Zählt Dokumente mit optionalen Filtern.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params: List[Any] = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\n                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"\n                    )\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                cursor.execute(\n                    f\"SELECT COUNT(*) as count FROM dokumentation WHERE {where_clause}\",\n                    params,\n                )\n                result = cursor.fetchone()\n                return result[\"count\"] if result else 0\n\n    def create(self, doc: Dokumentation) -> int:\n        \"\"\"Erstellt neues Dokument, gibt ID zurück.\"\"\"\n        with SimpleDbConnection.get_connection(Config) as conn:\n            with conn.cursor() as cursor:\n                now = datetime.now()\n                cursor.execute(\n                    \"\"\"INSERT INTO dokumentation\n                    (parent_id, slug, path, title, description, content, status,\n                     sort_order, depth, created_at, updated_at)\n                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\"\"\",\n                    (\n                        doc.parent_id,\n                        doc.slug,\n                        doc.path,\n                        doc.title,\n                        doc.description,\n                        doc.content,\n                        doc.status.value\n                        if isinstance(doc.status, DocStatus)\n                        else d... [TRUNCATED-e6e81cf9864f22cf]",
        "structuredPatch": [
            {
                "oldStart": 1,
                "oldLines": 52,
                "newStart": 1,
                "newLines": 51,
                "lines": [
                    "-\"\"\"Repository für Dokumentation CRUD-Operationen\"\"\"",
                    "-import sys",
                    "+\"\"\"Repository für Dokumentation CRUD-Operationen.\"\"\"",
                    "+",
                    " from datetime import datetime",
                    "-from typing import Optional, List, Dict, Any",
                    "+from typing import Any, Dict, List, Optional",
                    " ",
                    "-sys.path.insert(0, \"\/var\/www\/mcp-servers\/mcp_docs\")",
                    " from config import Config",
                    "-from domain.dokumentation import Dokumentation, DocStatus",
                    "-from infrastructure.db_connection import DatabaseConnection",
                    "+from domain.dokumentation import DocStatus, Dokumentation",
                    "+from shared.infrastructure import SimpleDbConnection",
                    " ",
                    " ",
                    " class DocsRepository:",
                    "-    \"\"\"Repository für ki_system.dokumentation Tabelle\"\"\"",
                    "+    \"\"\"Repository für ki_system.dokumentation Tabelle.\"\"\"",
                    " ",
                    "     def find_by_id(self, doc_id: int) -> Optional[Dokumentation]:",
                    "-        \"\"\"Findet Dokument nach ID\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Findet Dokument nach ID.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 cursor.execute(",
                    "-                    \"SELECT * FROM dokumentation WHERE id = %s\",",
                    "-                    (doc_id,)",
                    "+                    \"SELECT * FROM dokumentation WHERE id = %s\", (doc_id,)",
                    "                 )",
                    "                 row = cursor.fetchone()",
                    "                 return self._row_to_doc(row) if row else None",
                    " ",
                    "     def find_by_path(self, path: str) -> Optional[Dokumentation]:",
                    "-        \"\"\"Findet Dokument nach Pfad\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Findet Dokument nach Pfad.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 cursor.execute(",
                    "-                    \"SELECT * FROM dokumentation WHERE path = %s\",",
                    "-                    (path,)",
                    "+                    \"SELECT * FROM dokumentation WHERE path = %s\", (path,)",
                    "                 )",
                    "                 row = cursor.fetchone()",
                    "                 return self._row_to_doc(row) if row else None",
                    " ",
                    "-    def find_by_slug(self, slug: str, parent_id: Optional[int] = None) -> Optional[Dokumentation]:",
                    "-        \"\"\"Findet Dokument nach Slug (optional mit Parent)\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+    def find_by_slug(",
                    "+        self, slug: str, parent_id: Optional[int] = None",
                    "+    ) -> Optional[Dokumentation]:",
                    "+        \"\"\"Findet Dokument nach Slug (optional mit Parent).\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 if parent_id is not None:",
                    "                     cursor.execute(",
                    "                         \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id = %s\",",
                    "-                        (slug, parent_id)",
                    "+                        (slug, parent_id),",
                    "                     )",
                    "                 else:",
                    "                     cursor.execute(",
                    "                         \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id IS NULL\",",
                    "-                        (slug,)",
                    "+                        (slug,),",
                    "                     )",
                    "                 row = cursor.fetchone()",
                    "                 return self._row_to_doc(row) if row else None"
                ]
            },
            {
                "oldStart": 57,
                "oldLines": 13,
                "newStart": 56,
                "newLines": 13,
                "lines": [
                    "         parent_id: Optional[int] = None,",
                    "         search: Optional[str] = None,",
                    "         limit: int = 20,",
                    "-        offset: int = 0",
                    "+        offset: int = 0,",
                    "     ) -> List[Dokumentation]:",
                    "-        \"\"\"Findet alle Dokumente mit optionalen Filtern\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Findet alle Dokumente mit optionalen Filtern.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 conditions = []",
                    "-                params = []",
                    "+                params: List[Any] = []",
                    " ",
                    "                 if status:",
                    "                     conditions.append(\"status = %s\")"
                ]
            },
            {
                "oldStart": 74,
                "oldLines": 7,
                "newStart": 73,
                "newLines": 9,
                "lines": [
                    "                     params.append(parent_id)",
                    " ",
                    "                 if search:",
                    "-                    conditions.append(\"(title LIKE %s OR description LIKE %s OR content LIKE %s)\")",
                    "+                    conditions.append(",
                    "+                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"",
                    "+                    )",
                    "                     search_term = f\"%{search}%\"",
                    "                     params.extend([search_term, search_term, search_term])",
                    " "
                ]
            },
            {
                "oldStart": 96,
                "oldLines": 21,
                "newStart": 97,
                "newLines": 21,
                "lines": [
                    "                 return [self._row_to_doc(row) for row in rows]",
                    " ",
                    "     def find_children(self, parent_id: int) -> List[Dokumentation]:",
                    "-        \"\"\"Findet alle direkten Kinder eines Dokuments\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Findet alle direkten Kinder eines Dokuments.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 cursor.execute(",
                    "                     \"\"\"SELECT * FROM dokumentation",
                    "                     WHERE parent_id = %s",
                    "                     ORDER BY sort_order, title\"\"\",",
                    "-                    (parent_id,)",
                    "+                    (parent_id,),",
                    "                 )",
                    "                 rows = cursor.fetchall()",
                    "                 return [self._row_to_doc(row) for row in rows]",
                    " ",
                    "     def find_root_documents(self) -> List[Dokumentation]:",
                    "-        \"\"\"Findet alle Root-Dokumente (ohne Parent)\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Findet alle Root-Dokumente (ohne Parent).\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 cursor.execute(",
                    "                     \"\"\"SELECT * FROM dokumentation"
                ]
            },
            {
                "oldStart": 121,
                "oldLines": 8,
                "newStart": 122,
                "newLines": 8,
                "lines": [
                    "                 return [self._row_to_doc(row) for row in rows]",
                    " ",
                    "     def get_hierarchy(self) -> List[Dict[str, Any]]:",
                    "-        \"\"\"Gibt kompletten Dokumentationsbaum zurück\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Gibt kompletten Dokumentationsbaum zurück.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 cursor.execute(",
                    "                     \"\"\"SELECT id, parent_id, slug, path, title, status, sort_order, depth"
                ]
            },
            {
                "oldStart": 145,
                "oldLines": 24,
                "newStart": 146,
                "newLines": 27,
                "lines": [
                    "         return roots",
                    " ",
                    "     def get_breadcrumb(self, doc_id: int) -> List[Dict[str, Any]]:",
                    "-        \"\"\"Gibt Breadcrumb-Pfad für ein Dokument zurück\"\"\"",
                    "-        breadcrumb = []",
                    "-        current_id = doc_id",
                    "+        \"\"\"Gibt Breadcrumb-Pfad für ein Dokument zurück.\"\"\"",
                    "+        breadcrumb: List[Dict[str, Any]] = []",
                    "+        current_id: Optional[int] = doc_id",
                    " ",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 while current_id is not None:",
                    "                     cursor.execute(",
                    "                         \"SELECT id, parent_id, path, title FROM dokumentation WHERE id = %s\",",
                    "-                        (current_id,)",
                    "+                        (current_id,),",
                    "                     )",
                    "                     row = cursor.fetchone()",
                    "                     if row:",
                    "-                        breadcrumb.insert(0, {",
                    "-                            \"id\": row[\"id\"],",
                    "-                            \"path\": row[\"path\"],",
                    "-                            \"title\": row[\"title\"]",
                    "-                        })",
                    "+                        breadcrumb.insert(",
                    "+                            0,",
                    "+                            {",
                    "+                                \"id\": row[\"id\"],",
                    "+                                \"path\": row[\"path\"],",
                    "+                                \"title\": row[\"title\"],",
                    "+                            },",
                    "+                        )",
                    "                         current_id = row[\"parent_id\"]",
                    "                     else:",
                    "                         break"
                ]
            },
            {
                "oldStart": 170,
                "oldLines": 26,
                "newStart": 174,
                "newLines": 26,
                "lines": [
                    "         return breadcrumb",
                    " ",
                    "     def get_siblings(self, doc_id: int) -> List[Dokumentation]:",
                    "-        \"\"\"Findet Geschwister-Dokumente (gleicher Parent)\"\"\"",
                    "+        \"\"\"Findet Geschwister-Dokumente (gleicher Parent).\"\"\"",
                    "         doc = self.find_by_id(doc_id)",
                    "         if not doc:",
                    "             return []",
                    " ",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 if doc.parent_id is not None:",
                    "                     cursor.execute(",
                    "                         \"\"\"SELECT * FROM dokumentation",
                    "                         WHERE parent_id = %s AND id != %s",
                    "                         ORDER BY sort_order, title\"\"\",",
                    "-                        (doc.parent_id, doc_id)",
                    "+                        (doc.parent_id, doc_id),",
                    "                     )",
                    "                 else:",
                    "                     cursor.execute(",
                    "                         \"\"\"SELECT * FROM dokumentation",
                    "                         WHERE parent_id IS NULL AND id != %s",
                    "                         ORDER BY sort_order, title\"\"\",",
                    "-                        (doc_id,)",
                    "+                        (doc_id,),",
                    "                     )",
                    "                 rows = cursor.fetchall()",
                    "                 return [self._row_to_doc(row) for row in rows]"
                ]
            },
            {
                "oldStart": 198,
                "oldLines": 13,
                "newStart": 202,
                "newLines": 13,
                "lines": [
                    "         self,",
                    "         status: Optional[str] = None,",
                    "         parent_id: Optional[int] = None,",
                    "-        search: Optional[str] = None",
                    "+        search: Optional[str] = None,",
                    "     ) -> int:",
                    "-        \"\"\"Zählt Dokumente mit optionalen Filtern\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Zählt Dokumente mit optionalen Filtern.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 conditions = []",
                    "-                params = []",
                    "+                params: List[Any] = []",
                    " ",
                    "                 if status:",
                    "                     conditions.append(\"status = %s\")"
                ]
            },
            {
                "oldStart": 215,
                "oldLines": 24,
                "newStart": 219,
                "newLines": 30,
                "lines": [
                    "                     params.append(parent_id)",
                    " ",
                    "                 if search:",
                    "-                    conditions.append(\"(title LIKE %s OR description LIKE %s OR content LIKE %s)\")",
                    "+                    conditions.append(",
                    "+                        \"(title LIKE %s OR description LIKE %s OR content LIKE %s)\"",
                    "+                    )",
                    "                     search_term = f\"%{search}%\"",
                    "                     params.extend([search_term, search_term, search_term])",
                    " ",
                    "                 where_clause = \" AND \".join(conditions) if conditions else \"1=1\"",
                    " ",
                    "-                cursor.execute(f\"SELECT COUNT(*) as count FROM dokumentation WHERE {where_clause}\", params)",
                    "+                cursor.execute(",
                    "+                    f\"SELECT COUNT(*) as count FROM dokumentation WHERE {where_clause}\",",
                    "+                    params,",
                    "+                )",
                    "                 result = cursor.fetchone()",
                    "                 return result[\"count\"] if result else 0",
                    " ",
                    "     def create(self, doc: Dokumentation) -> int:",
                    "-        \"\"\"Erstellt neues Dokument, gibt ID zurück\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Erstellt neues Dokument, gibt ID zurück.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 now = datetime.now()",
                    "                 cursor.execute(",
                    "                     \"\"\"INSERT INTO dokumentation",
                    "-                    (parent_id, slug, path, title, description, content, status, sort_order, depth, created_at, updated_at)",
                    "+                    (parent_id, slug, path, title, description, content, status,",
                    "+                     sort_order, depth, created_at, updated_at)",
                    "                     VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\"\"\",",
                    "                     (",
                    "                         doc.parent_id,"
                ]
            },
            {
                "oldStart": 241,
                "oldLines": 21,
                "newStart": 251,
                "newLines": 33,
                "lines": [
                    "                         doc.title,",
                    "                         doc.description,",
                    "                         doc.content,",
                    "-                        doc.status.value if isinstance(doc.status, DocStatus) else doc.status,",
                    "+                        doc.status.value",
                    "+                        if isinstance(doc.status, DocStatus)",
                    "+                        else doc.status,",
                    "                         doc.sort_order,",
                    "                         doc.depth,",
                    "                         now,",
                    "-                        now",
                    "-                    )",
                    "+                        now,",
                    "+                    ),",
                    "                 )",
                    "-                return cursor.lastrowid",
                    "+                return cursor.lastrowid or 0",
                    " ",
                    "     def update(self, doc_id: int, updates: Dict[str, Any]) -> bool:",
                    "-        \"\"\"Aktualisiert Dokument-Felder\"\"\"",
                    "+        \"\"\"Aktualisiert Dokument-Felder.\"\"\"",
                    "         if not updates:",
                    "             return False",
                    " ",
                    "-        allowed_fields = {\"title\", \"description\", \"content\", \"status\", \"slug\", \"path\", \"sort_order\", \"parent_id\", \"depth\"}",
                    "+        allowed_fields = {",
                    "+            \"title\",",
                    "+            \"description\",",
                    "+            \"content\",",
                    "+            \"status\",",
                    "+            \"slug\",",
                    "+            \"path\",",
                    "+            \"sort_order\",",
                    "+            \"parent_id\",",
                    "+            \"depth\",",
                    "+        }",
                    "         filtered_updates = {k: v for k, v in updates.items() if k in allowed_fields}",
                    " ",
                    "         if not filtered_updates:"
                ]
            },
            {
                "oldStart": 264,
                "oldLines": 7,
                "newStart": 286,
                "newLines": 7,
                "lines": [
                    "         # updated_at automatisch setzen",
                    "         filtered_updates[\"updated_at\"] = datetime.now()",
                    " ",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 set_clause = \", \".join([f\"{k} = %s\" for k in filtered_updates.keys()])",
                    "                 values = list(filtered_updates.values())"
                ]
            },
            {
                "oldStart": 272,
                "oldLines": 33,
                "newStart": 294,
                "newLines": 38,
                "lines": [
                    " ",
                    "                 cursor.execute(",
                    "                     f\"UPDATE dokumentation SET {set_clause} WHERE id = %s\",",
                    "-                    values",
                    "+                    values,",
                    "                 )",
                    "                 return cursor.rowcount > 0",
                    " ",
                    "     def delete(self, doc_id: int) -> bool:",
                    "-        \"\"\"Löscht ein Dokument (keine Kaskade!)\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Löscht ein Dokument (keine Kaskade!).\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 # Prüfen ob Kinder existieren",
                    "                 cursor.execute(",
                    "                     \"SELECT COUNT(*) as count FROM dokumentation WHERE parent_id = %s\",",
                    "-                    (doc_id,)",
                    "+                    (doc_id,),",
                    "                 )",
                    "                 result = cursor.fetchone()",
                    "                 if result and result[\"count\"] > 0:",
                    "-                    raise ValueError(f\"Dokument hat {result['count']} Kind-Dokumente. Bitte zuerst diese löschen.\")",
                    "+                    raise ValueError(",
                    "+                        f\"Dokument hat {result['count']} Kind-Dokumente. \"",
                    "+                        \"Bitte zuerst diese löschen.\"",
                    "+                    )",
                    " ",
                    "                 cursor.execute(\"DELETE FROM dokumentation WHERE id = %s\", (doc_id,))",
                    "                 return cursor.rowcount > 0",
                    " ",
                    "-    def move(self, doc_id: int, new_parent_id: Optional[int], new_sort_order: Optional[int] = None) -> bool:",
                    "-        \"\"\"Verschiebt Dokument zu neuem Parent\"\"\"",
                    "+    def move(",
                    "+        self, doc_id: int, new_parent_id: Optional[int], new_sort_order: Optional[int] = None",
                    "+    ) -> bool:",
                    "+        \"\"\"Verschiebt Dokument zu neuem Parent.\"\"\"",
                    "         doc = self.find_by_id(doc_id)",
                    "         if not doc:",
                    "             return False",
                    " ",
                    "-        updates = {\"parent_id\": new_parent_id}",
                    "+        updates: Dict[str, Any] = {\"parent_id\": new_parent_id}",
                    " ",
                    "         # Neue Tiefe berechnen",
                    "         if new_parent_id is not None:"
                ]
            },
            {
                "oldStart": 317,
                "oldLines": 11,
                "newStart": 344,
                "newLines": 12,
                "lines": [
                    "         return self.update(doc_id, updates)",
                    " ",
                    "     def get_statistics(self) -> Dict[str, Any]:",
                    "-        \"\"\"Gibt Statistiken über alle Dokumente zurück\"\"\"",
                    "-        with DatabaseConnection.get_connection() as conn:",
                    "+        \"\"\"Gibt Statistiken über alle Dokumente zurück.\"\"\"",
                    "+        with SimpleDbConnection.get_connection(Config) as conn:",
                    "             with conn.cursor() as cursor:",
                    "                 # Gesamt und nach Status",
                    "-                cursor.execute(\"\"\"",
                    "+                cursor.execute(",
                    "+                    \"\"\"",
                    "                     SELECT",
                    "                         COUNT(*) as total,",
                    "                         SUM(CASE WHEN status = 'draft' THEN 1 ELSE 0 END) as draft,"
                ]
            },
            {
                "oldStart": 329,
                "oldLines": 11,
                "newStart": 357,
                "newLines": 14,
                "lines": [
                    "                         SUM(CASE WHEN status = 'archived' THEN 1 ELSE 0 END) as archived,",
                    "                         MAX(depth) as max_depth",
                    "                     FROM dokumentation",
                    "-                \"\"\")",
                    "+                \"\"\"",
                    "+                )",
                    "                 stats = cursor.fetchone()",
                    " ",
                    "                 # Root-Dokumente zählen",
                    "-                cursor.execute(\"SELECT COUNT(*) as count FROM dokumentation WHERE parent_id IS NULL\")",
                    "+                cursor.execute(",
                    "+                    \"SELECT COUNT(*) as count FROM dokumentation WHERE parent_id IS NULL\"",
                    "+                )",
                    "                 root_count = cursor.fetchone()",
                    " ",
                    "                 return {"
                ]
            },
            {
                "oldStart": 341,
                "oldLines": 14,
                "newStart": 372,
                "newLines": 14,
                "lines": [
                    "                     \"by_status\": {",
                    "                         \"draft\": stats[\"draft\"] or 0,",
                    "                         \"published\": stats[\"published\"] or 0,",
                    "-                        \"archived\": stats[\"archived\"] or 0",
                    "+                        \"archived\": stats[\"archived\"] or 0,",
                    "                     },",
                    "                     \"root_documents\": root_count[\"count\"] if root_count else 0,",
                    "-                    \"max_depth\": stats[\"max_depth\"] or 0",
                    "+                    \"max_depth\": stats[\"max_depth\"] or 0,",
                    "                 }",
                    " ",
                    "     def _row_to_doc(self, row: Dict[str, Any]) -> Dokumentation:",
                    "-        \"\"\"Konvertiert DB-Row zu Dokumentation-Entity\"\"\"",
                    "+        \"\"\"Konvertiert DB-Row zu Dokumentation-Entity.\"\"\"",
                    "         status = row.get(\"status\", \"draft\")",
                    "         if isinstance(status, str):",
                    "             try:"
                ]
            },
            {
                "oldStart": 368,
                "oldLines": 16,
                "newStart": 399,
                "newLines": 16,
                "lines": [
                    "             sort_order=row.get(\"sort_order\", 0),",
                    "             depth=row.get(\"depth\", 0),",
                    "             created_at=row.get(\"created_at\", datetime.now()),",
                    "-            updated_at=row.get(\"updated_at\", datetime.now())",
                    "+            updated_at=row.get(\"updated_at\", datetime.now()),",
                    "         )",
                    " ",
                    " ",
                    " # Singleton-Instanz",
                    "-_repository_instance = None",
                    "+_repository_instance: Optional[DocsRepository] = None",
                    " ",
                    " ",
                    " def get_repository() -> DocsRepository:",
                    "-    \"\"\"Gibt Singleton-Repository zurück\"\"\"",
                    "+    \"\"\"Gibt Singleton-Repository zurück.\"\"\"",
                    "     global _repository_instance",
                    "     if _repository_instance is None:",
                    "         _repository_instance = DocsRepository()"
                ]
            }
        ],
        "originalFile": "\"\"\"Repository für Dokumentation CRUD-Operationen\"\"\"\nimport sys\nfrom datetime import datetime\nfrom typing import Optional, List, Dict, Any\n\nsys.path.insert(0, \"\/var\/www\/mcp-servers\/mcp_docs\")\nfrom config import Config\nfrom domain.dokumentation import Dokumentation, DocStatus\nfrom infrastructure.db_connection import DatabaseConnection\n\n\nclass DocsRepository:\n    \"\"\"Repository für ki_system.dokumentation Tabelle\"\"\"\n\n    def find_by_id(self, doc_id: int) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach ID\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE id = %s\",\n                    (doc_id,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_path(self, path: str) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Pfad\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"SELECT * FROM dokumentation WHERE path = %s\",\n                    (path,)\n                )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_by_slug(self, slug: str, parent_id: Optional[int] = None) -> Optional[Dokumentation]:\n        \"\"\"Findet Dokument nach Slug (optional mit Parent)\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                if parent_id is not None:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id = %s\",\n                        (slug, parent_id)\n                    )\n                else:\n                    cursor.execute(\n                        \"SELECT * FROM dokumentation WHERE slug = %s AND parent_id IS NULL\",\n                        (slug,)\n                    )\n                row = cursor.fetchone()\n                return self._row_to_doc(row) if row else None\n\n    def find_all(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None,\n        limit: int = 20,\n        offset: int = 0\n    ) -> List[Dokumentation]:\n        \"\"\"Findet alle Dokumente mit optionalen Filtern\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\"(title LIKE %s OR description LIKE %s OR content LIKE %s)\")\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                # Limit begrenzen\n                limit = min(limit, Config.MAX_RESULTS)\n\n                sql = f\"\"\"\n                    SELECT * FROM dokumentation\n                    WHERE {where_clause}\n                    ORDER BY depth, sort_order, title\n                    LIMIT %s OFFSET %s\n                \"\"\"\n                params.extend([limit, offset])\n\n                cursor.execute(sql, params)\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_children(self, parent_id: int) -> List[Dokumentation]:\n        \"\"\"Findet alle direkten Kinder eines Dokuments\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id = %s\n                    ORDER BY sort_order, title\"\"\",\n                    (parent_id,)\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def find_root_documents(self) -> List[Dokumentation]:\n        \"\"\"Findet alle Root-Dokumente (ohne Parent)\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT * FROM dokumentation\n                    WHERE parent_id IS NULL\n                    ORDER BY sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def get_hierarchy(self) -> List[Dict[str, Any]]:\n        \"\"\"Gibt kompletten Dokumentationsbaum zurück\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                cursor.execute(\n                    \"\"\"SELECT id, parent_id, slug, path, title, status, sort_order, depth\n                    FROM dokumentation\n                    ORDER BY depth, sort_order, title\"\"\"\n                )\n                rows = cursor.fetchall()\n\n        # Baum aufbauen\n        docs_by_id = {row[\"id\"]: {**row, \"children\": []} for row in rows}\n        roots = []\n\n        for row in rows:\n            doc = docs_by_id[row[\"id\"]]\n            if row[\"parent_id\"] is None:\n                roots.append(doc)\n            elif row[\"parent_id\"] in docs_by_id:\n                docs_by_id[row[\"parent_id\"]][\"children\"].append(doc)\n\n        return roots\n\n    def get_breadcrumb(self, doc_id: int) -> List[Dict[str, Any]]:\n        \"\"\"Gibt Breadcrumb-Pfad für ein Dokument zurück\"\"\"\n        breadcrumb = []\n        current_id = doc_id\n\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                while current_id is not None:\n                    cursor.execute(\n                        \"SELECT id, parent_id, path, title FROM dokumentation WHERE id = %s\",\n                        (current_id,)\n                    )\n                    row = cursor.fetchone()\n                    if row:\n                        breadcrumb.insert(0, {\n                            \"id\": row[\"id\"],\n                            \"path\": row[\"path\"],\n                            \"title\": row[\"title\"]\n                        })\n                        current_id = row[\"parent_id\"]\n                    else:\n                        break\n\n        return breadcrumb\n\n    def get_siblings(self, doc_id: int) -> List[Dokumentation]:\n        \"\"\"Findet Geschwister-Dokumente (gleicher Parent)\"\"\"\n        doc = self.find_by_id(doc_id)\n        if not doc:\n            return []\n\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                if doc.parent_id is not None:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id = %s AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc.parent_id, doc_id)\n                    )\n                else:\n                    cursor.execute(\n                        \"\"\"SELECT * FROM dokumentation\n                        WHERE parent_id IS NULL AND id != %s\n                        ORDER BY sort_order, title\"\"\",\n                        (doc_id,)\n                    )\n                rows = cursor.fetchall()\n                return [self._row_to_doc(row) for row in rows]\n\n    def count(\n        self,\n        status: Optional[str] = None,\n        parent_id: Optional[int] = None,\n        search: Optional[str] = None\n    ) -> int:\n        \"\"\"Zählt Dokumente mit optionalen Filtern\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                conditions = []\n                params = []\n\n                if status:\n                    conditions.append(\"status = %s\")\n                    params.append(status)\n\n                if parent_id is not None:\n                    conditions.append(\"parent_id = %s\")\n                    params.append(parent_id)\n\n                if search:\n                    conditions.append(\"(title LIKE %s OR description LIKE %s OR content LIKE %s)\")\n                    search_term = f\"%{search}%\"\n                    params.extend([search_term, search_term, search_term])\n\n                where_clause = \" AND \".join(conditions) if conditions else \"1=1\"\n\n                cursor.execute(f\"SELECT COUNT(*) as count FROM dokumentation WHERE {where_clause}\", params)\n                result = cursor.fetchone()\n                return result[\"count\"] if result else 0\n\n    def create(self, doc: Dokumentation) -> int:\n        \"\"\"Erstellt neues Dokument, gibt ID zurück\"\"\"\n        with DatabaseConnection.get_connection() as conn:\n            with conn.cursor() as cursor:\n                now = datetime.now()\n                cursor.execute(\n                    \"\"\"INSERT INTO dokumentation\n                    (parent_id, slug, path, title, description, content, status, sort_order, depth, created_at, updated_at)\n                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\"\"\",\n                    (\n                        doc.parent_id,\n                        doc.slug,\n                        doc.path,\n                        doc.title,\n                        doc.description,\n                        doc.content,\n                        doc.status.value if isinstance(doc.status, DocStatus) else doc.status,\n                        doc.sort_order,\n                        doc.depth,\n                        now,\n                        now\n                    )\n                )\n                return cursor.lastrowid\n\n    def update(self, doc_id: int, updates: Dict[str, Any]) -> bool:\n        \"\"\"Aktualisiert Dokument-Felder\"\"\"\n        if not updates:\n            ... [TRUNCATED-a7ad1062d286074e]"
    }
}
← Vorheriger Zur Liste Nächster →