{
"event": "PreToolUse",
"tool_name": "mcp__mcp-tasks__tasks_create",
"tool_input": {
"title": "RAG Online: Scoring-Algorithmus erweitern (recency + authority)",
"description": "# Auftrag\n\nErweitere den Scoring-Algorithmus in ChatService.php um recency und authority Faktoren.\n\n## Voraussetzungen\n\n**ERSTE AKTION:** `docs_get(path=\"\/\")` → Lese CLAUDE.md vollständig\n\n**Relevante Contracts:**\n- `contracts_get(name=\"architecture-gate-contract\")` - Architektur-Prüfung\n- `contracts_get(name=\"code-quality-standards\")` - PHP-Standards\n- `contracts_get(name=\"layered-architecture-pruefung_v1.0\")` - MVC-Konformität\n\n**Paradigmen (ZWINGEND):**\n- OOP: ScoringService als eigene Klasse\n- SRP: Scoring-Logik getrennt von ChatService\n- DIP: Interface für Scoring-Strategie\n- KISS: Einfache Gewichtungsformel\n\n## Kontext\n\n**Referenz-Dokumentation:** `docs_get(id=100)` (RAG-Prozess, §7.1)\n\n**IST-Zustand:** `src\/Infrastructure\/AI\/ChatService.php` nutzt nur Qdrant Cosine-Score\n\n**SOLL (aus Doku):**\n```yaml\nscoring:\n vector_similarity: 0.7\n recency: 0.1\n source_authority: 0.2\n```\n\n## Aufgabe\n\n### 1. ScoringService erstellen\n\n**Datei:** `src\/Infrastructure\/AI\/ScoringService.php`\n\n```php\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\AI;\n\nfinal readonly class ScoringService\n{\n private const WEIGHT_SIMILARITY = 0.7;\n private const WEIGHT_RECENCY = 0.1;\n private const WEIGHT_AUTHORITY = 0.2;\n \n public function calculateScore(\n float $vectorScore,\n \\DateTimeInterface $documentDate,\n float $authorityScore = 0.5\n ): float {\n $recencyScore = $this->calculateRecency($documentDate);\n \n return (self::WEIGHT_SIMILARITY * $vectorScore)\n + (self::WEIGHT_RECENCY * $recencyScore)\n + (self::WEIGHT_AUTHORITY * $authorityScore);\n }\n \n private function calculateRecency(\\DateTimeInterface $date): float\n {\n $daysOld = (new \\DateTime())->diff($date)->days;\n return max(0.0, 1.0 - ($daysOld \/ 365));\n }\n}\n```\n\n### 2. ChatService integrieren\n\nIn `ChatService::chat()` nach Vector-Search:\n```php\n$scoringService = new ScoringService();\nforeach ($searchResults as &$result) {\n $result['weighted_score'] = $scoringService->calculateScore(\n $result['score'],\n new \\DateTime($result['processed_at'] ?? 'now'),\n $result['authority_score'] ?? 0.5\n );\n}\nusort($searchResults, fn($a, $b) => $b['weighted_score'] <=> $a['weighted_score']);\n```\n\n### 3. Authority-Score (Optional)\n\nFalls `documents.authority_score` nicht existiert:\n```sql\ndb_execute(statement=\"ALTER TABLE documents ADD COLUMN authority_score FLOAT DEFAULT 0.5\", database=\"ki_content\")\n```\n\n## Validierung\n\n```bash\n# PHP Quality Check\n\/opt\/scripts\/php-check.sh\n\n# Architecture Guard\n\/var\/www\/tools\/ki-protokoll\/claude-hook\/architecture_guard.py src\/Infrastructure\/AI\/ScoringService.php\n\n# Contract-Validierung\ncontracts_validate(name=\"code-quality-standards\")\n\n# Funktionstest\nREQUEST_URI=\"\/chat\" REQUEST_METHOD=\"GET\" php \/var\/www\/dev.campus.systemische-tools.de\/public\/index.php\n```\n\n## Qualitätskriterien\n\n- [ ] ScoringService.php erstellt mit strict_types\n- [ ] Dependency Injection (kein `new` in ChatService)\n- [ ] PHPDoc für alle public Methoden\n- [ ] PHPStan Level 7 ohne Fehler\n- [ ] Chat funktioniert mit neuem Scoring",
"type": "ai_task"
}
}
{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"task\": {\n \"id\": 303,\n \"uuid\": \"6a00b544-11e0-44ef-b7fd-ddb49ed8631f\",\n \"title\": \"RAG Online: Scoring-Algorithmus erweitern (recency + authority)\",\n \"description\": \"# Auftrag\\n\\nErweitere den Scoring-Algorithmus in ChatService.php um recency und authority Faktoren.\\n\\n## Voraussetzungen\\n\\n**ERSTE AKTION:** `docs_get(path=\\\"\/\\\")` → Lese CLAUDE.md vollständig\\n\\n**Relevante Contracts:**\\n- `contracts_get(name=\\\"architecture-gate-contract\\\")` - Architektur-Prüfung\\n- `contracts_get(name=\\\"code-quality-standards\\\")` - PHP-Standards\\n- `contracts_get(name=\\\"layered-architecture-pruefung_v1.0\\\")` - MVC-Konformität\\n\\n**Paradigmen (ZWINGEND):**\\n- OOP: ScoringService als eigene Klasse\\n- SRP: Scoring-Logik getrennt von ChatService\\n- DIP: Interface für Scoring-Strategie\\n- KISS: Einfache Gewichtungsformel\\n\\n## Kontext\\n\\n**Referenz-Dokumentation:** `docs_get(id=100)` (RAG-Prozess, §7.1)\\n\\n**IST-Zustand:** `src\/Infrastructure\/AI\/ChatService.php` nutzt nur Qdrant Cosine-Score\\n\\n**SOLL (aus Doku):**\\n```yaml\\nscoring:\\n vector_similarity: 0.7\\n recency: 0.1\\n source_authority: 0.2\\n```\\n\\n## Aufgabe\\n\\n### 1. ScoringService erstellen\\n\\n**Datei:** `src\/Infrastructure\/AI\/ScoringService.php`\\n\\n```php\\ndeclare(strict_types=1);\\n\\nnamespace Infrastructure\\\\AI;\\n\\nfinal readonly class ScoringService\\n{\\n private const WEIGHT_SIMILARITY = 0.7;\\n private const WEIGHT_RECENCY = 0.1;\\n private const WEIGHT_AUTHORITY = 0.2;\\n \\n public function calculateScore(\\n float $vectorScore,\\n \\\\DateTimeInterface $documentDate,\\n float $authorityScore = 0.5\\n ): float {\\n $recencyScore = $this->calculateRecency($documentDate);\\n \\n return (self::WEIGHT_SIMILARITY * $vectorScore)\\n + (self::WEIGHT_RECENCY * $recencyScore)\\n + (self::WEIGHT_AUTHORITY * $authorityScore);\\n }\\n \\n private function calculateRecency(\\\\DateTimeInterface $date): float\\n {\\n $daysOld = (new \\\\DateTime())->diff($date)->days;\\n return max(0.0, 1.0 - ($daysOld \/ 365));\\n }\\n}\\n```\\n\\n### 2. ChatService integrieren\\n\\nIn `ChatService::chat()` nach Vector-Search:\\n```php\\n$scoringService = new ScoringService();\\nforeach ($searchResults as &$result) {\\n $result['weighted_score'] = $scoringService->calculateScore(\\n $result['score'],\\n new \\\\DateTime($result['processed_at'] ?? 'now'),\\n $result['authority_score'] ?? 0.5\\n );\\n}\\nusort($searchResults, fn($a, $b) => $b['weighted_score'] <=> $a['weighted_score']);\\n```\\n\\n### 3. Authority-Score (Optional)\\n\\nFalls `documents.authority_score` nicht existiert:\\n```sql\\ndb_execute(statement=\\\"ALTER TABLE documents ADD COLUMN authority_score FLOAT DEFAULT 0.5\\\", database=\\\"ki_content\\\")\\n```\\n\\n## Validierung\\n\\n```bash\\n# PHP Quality Check\\n\/opt\/scripts\/php-check.sh\\n\\n# Architecture Guard\\n\/var\/www\/tools\/ki-protokoll\/claude-hook\/architecture_guard.py src\/Infrastructure\/AI\/ScoringService.php\\n\\n# Contract-Validierung\\ncontracts_validate(name=\\\"code-quality-standards\\\")\\n\\n# Funktionstest\\nREQUEST_URI=\\\"\/chat\\\" REQUEST_METHOD=\\\"GET\\\" php \/var\/www\/dev.campus.systemische-tools.de\/public\/index.php\\n```\\n\\n## Qualitätskriterien\\n\\n- [ ] ScoringService.php erstellt mit strict_types\\n- [ ] Dependency Injection (kein `new` in ChatService)\\n- [ ] PHPDoc für alle public Methoden\\n- [ ] PHPStan Level 7 ohne Fehler\\n- [ ] Chat funktioniert mit neuem Scoring\",\n \"type\": \"ai_task\",\n \"status\": \"pending\",\n \"created_by\": \"mcp-tasks\",\n \"created_by_type\": \"ai\",\n \"parent_task_id\": null,\n \"due_date\": null,\n \"created_at\": \"2025-12-24T15:01:23.534019\",\n \"updated_at\": \"2025-12-24T15:01:23.534022\",\n \"completed_at\": null,\n \"metadata\": {}\n },\n \"message\": \"Task #303 created\"\n}"
}
]
}