Protokoll #5287

ID5287
Zeitstempel2025-12-22 21:19:05.405063
Clientroot
IP145.224.96.190
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens11,590 (Input: 2,470, Output: 9,120)
Dauer94 ms
Request-Zeit2025-12-22 21:19:05.405063
Response-Zeit2025-12-22 21:19:05.498798

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ContentController.php",
        "content": "<?php\n\nnamespace Controller;\n\nuse Application\\ContentCollectionService;\nuse Framework\\Controller;\nuse Infrastructure\\AI\\ModelConfig;\nuse Infrastructure\\Persistence\\CollectionRepository;\nuse Infrastructure\\Persistence\\ContentRepository;\nuse Infrastructure\\Validation\\CollectionValidator;\nuse UseCases\\Command\\CreateContentOrderCommand;\nuse UseCases\\Command\\GenerateContentCommand;\nuse UseCases\\Content\\GenerateContentUseCase;\n\nclass ContentController extends Controller\n{\n    private ContentRepository $repository;\n    private ContentCollectionService $collectionService;\n    private GenerateContentUseCase $generateUseCase;\n\n    public function __construct()\n    {\n        $this->repository = new ContentRepository();\n        $collectionRepo = new CollectionRepository();\n        $this->collectionService = new ContentCollectionService(\n            $collectionRepo,\n            new CollectionValidator($collectionRepo)\n        );\n        $this->generateUseCase = new GenerateContentUseCase();\n    }\n\n    \/**\n     * GET \/content - List all content orders\n     *\/\n    public function index(): void\n    {\n        $status = $this->getString('status');\n\n        $this->view('content.index', [\n            'title' => 'Content Studio',\n            'orders' => $this->repository->findAllOrders($status !== '' ? ['status' => $status] : []),\n            'stats' => $this->repository->getStatistics(),\n            'currentStatus' => $status,\n        ]);\n    }\n\n    \/**\n     * GET \/content\/new - Show create form\n     *\/\n    public function contentNew(): void\n    {\n        $lastSettings = $this->repository->getLastOrderSettings();\n\n        $this->view('content.new', [\n            'title' => 'Neuer Content-Auftrag',\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n            'models' => ModelConfig::getAll(),\n            'collections' => $this->collectionService->getAvailable(),\n            'defaultModel' => $lastSettings['model'],\n            'defaultCollections' => $lastSettings['collections'],\n            'defaultContextLimit' => $lastSettings['context_limit'],\n            'defaultProfileId' => $lastSettings['author_profile_id'],\n            'defaultContractId' => $lastSettings['contract_id'],\n            'defaultStructureId' => $lastSettings['structure_id'],\n        ]);\n    }\n\n    \/**\n     * POST \/content - Store new order\n     *\/\n    public function store(): void\n    {\n        $this->requireCsrf();\n\n        $command = CreateContentOrderCommand::fromRequest($_POST);\n        $errors = $command->validate();\n\n        if ($errors !== []) {\n            $_SESSION['error'] = implode(' ', $errors);\n            $this->redirect('\/content\/new');\n        }\n\n        \/\/ Validate collections\n        $result = $this->collectionService->validateWithCompatibility($command->collections);\n        if (!$result['valid']) {\n            $_SESSION['error'] = 'Collection-Fehler: ' . $result['error'];\n            $this->redirect('\/content\/new');\n        }\n\n        $orderId = $this->repository->createOrder([\n            'title' => $command->title,\n            'briefing' => $command->briefing,\n            'author_profile_id' => $command->authorProfileId,\n            'contract_id' => $command->contractId ?? $this->getFirstContractId(),\n            'structure_id' => $command->structureId,\n            'model' => ModelConfig::validate($command->model),\n            'collections' => json_encode($result['collections']),\n            'context_limit' => $command->contextLimit,\n        ]);\n\n        if ($command->shouldGenerate()) {\n            $genResult = $this->generateUseCase->generate(\n                $orderId,\n                ModelConfig::validate($command->model),\n                $result['collections'][0] ?? 'documents',\n                $command->contextLimit\n            );\n            $_SESSION[$genResult->hasError() ? 'error' : 'success'] =\n                $genResult->hasError() ? 'Generierung fehlgeschlagen: ' . $genResult->getError() : 'Content wurde generiert.';\n        }\n\n        $this->redirect('\/content\/' . $orderId);\n    }\n\n    \/**\n     * GET \/content\/{id} - Show order details\n     *\/\n    public function show(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $versions = $this->repository->findVersionsByOrder($id);\n        $latestVersion = $versions[0] ?? null;\n\n        $this->view('content.show', [\n            'title' => $order['title'],\n            'order' => $order,\n            'versions' => $versions,\n            'latestVersion' => $latestVersion,\n            'critiques' => $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [],\n            'sources' => $this->repository->findSourcesByOrder($id),\n            'models' => ModelConfig::getAll(),\n            'availableCollections' => $this->collectionService->getAvailable(),\n        ]);\n    }\n\n    \/**\n     * GET \/content\/{id}\/edit - Show edit form\n     *\/\n    public function edit(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $this->view('content.edit', [\n            'title' => 'Auftrag bearbeiten',\n            'order' => $order,\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n        ]);\n    }\n\n    \/**\n     * POST \/content\/{id}\/generate - Generate content (HTMX)\n     *\/\n    public function generate(int $id): void\n    {\n        $this->requireCsrf();\n\n        $command = GenerateContentCommand::fromRequest($id, $_POST);\n        if (($errors = $command->validate()) !== []) {\n            $this->htmxError(implode(' ', $errors));\n            return;\n        }\n\n        $result = $this->collectionService->validateWithCompatibility([$command->collection]);\n        if (!$result['valid']) {\n            $this->htmxError($result['error'] ?? 'Collection-Fehler');\n            return;\n        }\n\n        $genResult = $this->generateUseCase->generate($id, $command->model, $result['collections'][0], $command->contextLimit);\n        if ($genResult->hasError()) {\n            $this->htmxError('Fehler: ' . $genResult->getError());\n            return;\n        }\n\n        $this->renderVersionPartial($genResult->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/critique - Run critique round (HTMX)\n     *\/\n    public function critique(int $id): void\n    {\n        $this->requireCsrf();\n\n        $version = $this->repository->findLatestVersion($id);\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n            return;\n        }\n\n        $result = $this->generateUseCase->critique($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n            return;\n        }\n\n        $this->renderCritiquePartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/revise - Create revision (HTMX)\n     *\/\n    public function revise(int $id): void\n    {\n        $this->requireCsrf();\n\n        $version = $this->repository->findLatestVersion($id);\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n            return;\n        }\n\n        $result = $this->generateUseCase->revise($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n            return;\n        }\n\n        $this->renderVersionPartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/approve - Approve content\n     *\/\n    public function approve(int $id): void\n    {\n        $this->requireCsrf();\n        $this->repository->updateOrderStatus($id, 'approve');\n        $this->htmxSuccess('Content genehmigt!');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    \/**\n     * POST \/content\/{id}\/decline - Decline content\n     *\/\n    public function decline(int $id): void\n    {\n        $this->requireCsrf();\n        $this->repository->updateOrderStatus($id, 'draft');\n        $this->htmxAlert('warning', 'Content abgelehnt. Zurück zu Entwurf.');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    private function getFirstContractId(): ?int\n    {\n        $contracts = $this->repository->findAllContracts();\n        return $contracts !== [] ? (int) $contracts[0]['id'] : null;\n    }\n\n    private function renderVersionPartial(array $result): void\n    {\n        $this->view('content.partials.version', [\n            'content' => $result['content'] ?? '',\n            'sources' => $result['sources'] ?? [],\n            'versionNumber' => $result['version_number'] ?? '?',\n        ]);\n    }\n\n    private function renderCritiquePartial(array $result): void\n    {\n        $this->view('content.partials.critique', [\n            'critiques' => $result['critiques'] ?? [],\n            'allPassed' => $result['all_passed'] ?? false,\n            'round' => $result['round'] ?? '?',\n        ]);\n    }\n}\n"
    }
}

Response

{
    "tool_response": {
        "type": "update",
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ContentController.php",
        "content": "<?php\n\nnamespace Controller;\n\nuse Application\\ContentCollectionService;\nuse Framework\\Controller;\nuse Infrastructure\\AI\\ModelConfig;\nuse Infrastructure\\Persistence\\CollectionRepository;\nuse Infrastructure\\Persistence\\ContentRepository;\nuse Infrastructure\\Validation\\CollectionValidator;\nuse UseCases\\Command\\CreateContentOrderCommand;\nuse UseCases\\Command\\GenerateContentCommand;\nuse UseCases\\Content\\GenerateContentUseCase;\n\nclass ContentController extends Controller\n{\n    private ContentRepository $repository;\n    private ContentCollectionService $collectionService;\n    private GenerateContentUseCase $generateUseCase;\n\n    public function __construct()\n    {\n        $this->repository = new ContentRepository();\n        $collectionRepo = new CollectionRepository();\n        $this->collectionService = new ContentCollectionService(\n            $collectionRepo,\n            new CollectionValidator($collectionRepo)\n        );\n        $this->generateUseCase = new GenerateContentUseCase();\n    }\n\n    \/**\n     * GET \/content - List all content orders\n     *\/\n    public function index(): void\n    {\n        $status = $this->getString('status');\n\n        $this->view('content.index', [\n            'title' => 'Content Studio',\n            'orders' => $this->repository->findAllOrders($status !== '' ? ['status' => $status] : []),\n            'stats' => $this->repository->getStatistics(),\n            'currentStatus' => $status,\n        ]);\n    }\n\n    \/**\n     * GET \/content\/new - Show create form\n     *\/\n    public function contentNew(): void\n    {\n        $lastSettings = $this->repository->getLastOrderSettings();\n\n        $this->view('content.new', [\n            'title' => 'Neuer Content-Auftrag',\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n            'models' => ModelConfig::getAll(),\n            'collections' => $this->collectionService->getAvailable(),\n            'defaultModel' => $lastSettings['model'],\n            'defaultCollections' => $lastSettings['collections'],\n            'defaultContextLimit' => $lastSettings['context_limit'],\n            'defaultProfileId' => $lastSettings['author_profile_id'],\n            'defaultContractId' => $lastSettings['contract_id'],\n            'defaultStructureId' => $lastSettings['structure_id'],\n        ]);\n    }\n\n    \/**\n     * POST \/content - Store new order\n     *\/\n    public function store(): void\n    {\n        $this->requireCsrf();\n\n        $command = CreateContentOrderCommand::fromRequest($_POST);\n        $errors = $command->validate();\n\n        if ($errors !== []) {\n            $_SESSION['error'] = implode(' ', $errors);\n            $this->redirect('\/content\/new');\n        }\n\n        \/\/ Validate collections\n        $result = $this->collectionService->validateWithCompatibility($command->collections);\n        if (!$result['valid']) {\n            $_SESSION['error'] = 'Collection-Fehler: ' . $result['error'];\n            $this->redirect('\/content\/new');\n        }\n\n        $orderId = $this->repository->createOrder([\n            'title' => $command->title,\n            'briefing' => $command->briefing,\n            'author_profile_id' => $command->authorProfileId,\n            'contract_id' => $command->contractId ?? $this->getFirstContractId(),\n            'structure_id' => $command->structureId,\n            'model' => ModelConfig::validate($command->model),\n            'collections' => json_encode($result['collections']),\n            'context_limit' => $command->contextLimit,\n        ]);\n\n        if ($command->shouldGenerate()) {\n            $genResult = $this->generateUseCase->generate(\n                $orderId,\n                ModelConfig::validate($command->model),\n                $result['collections'][0] ?? 'documents',\n                $command->contextLimit\n            );\n            $_SESSION[$genResult->hasError() ? 'error' : 'success'] =\n                $genResult->hasError() ? 'Generierung fehlgeschlagen: ' . $genResult->getError() : 'Content wurde generiert.';\n        }\n\n        $this->redirect('\/content\/' . $orderId);\n    }\n\n    \/**\n     * GET \/content\/{id} - Show order details\n     *\/\n    public function show(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $versions = $this->repository->findVersionsByOrder($id);\n        $latestVersion = $versions[0] ?? null;\n\n        $this->view('content.show', [\n            'title' => $order['title'],\n            'order' => $order,\n            'versions' => $versions,\n            'latestVersion' => $latestVersion,\n            'critiques' => $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [],\n            'sources' => $this->repository->findSourcesByOrder($id),\n            'models' => ModelConfig::getAll(),\n            'availableCollections' => $this->collectionService->getAvailable(),\n        ]);\n    }\n\n    \/**\n     * GET \/content\/{id}\/edit - Show edit form\n     *\/\n    public function edit(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $this->view('content.edit', [\n            'title' => 'Auftrag bearbeiten',\n            'order' => $order,\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n        ]);\n    }\n\n    \/**\n     * POST \/content\/{id}\/generate - Generate content (HTMX)\n     *\/\n    public function generate(int $id): void\n    {\n        $this->requireCsrf();\n\n        $command = GenerateContentCommand::fromRequest($id, $_POST);\n        if (($errors = $command->validate()) !== []) {\n            $this->htmxError(implode(' ', $errors));\n            return;\n        }\n\n        $result = $this->collectionService->validateWithCompatibility([$command->collection]);\n        if (!$result['valid']) {\n            $this->htmxError($result['error'] ?? 'Collection-Fehler');\n            return;\n        }\n\n        $genResult = $this->generateUseCase->generate($id, $command->model, $result['collections'][0], $command->contextLimit);\n        if ($genResult->hasError()) {\n            $this->htmxError('Fehler: ' . $genResult->getError());\n            return;\n        }\n\n        $this->renderVersionPartial($genResult->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/critique - Run critique round (HTMX)\n     *\/\n    public function critique(int $id): void\n    {\n        $this->requireCsrf();\n\n        $version = $this->repository->findLatestVersion($id);\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n            return;\n        }\n\n        $result = $this->generateUseCase->critique($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n            return;\n        }\n\n        $this->renderCritiquePartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/revise - Create revision (HTMX)\n     *\/\n    public function revise(int $id): void\n    {\n        $this->requireCsrf();\n\n        $version = $this->repository->findLatestVersion($id);\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n            return;\n        }\n\n        $result = $this->generateUseCase->revise($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n            return;\n        }\n\n        $this->renderVersionPartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/approve - Approve content\n     *\/\n    public function approve(int $id): void\n    {\n        $this->requireCsrf();\n        $this->repository->updateOrderStatus($id, 'approve');\n        $this->htmxSuccess('Content genehmigt!');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    \/**\n     * POST \/content\/{id}\/decline - Decline content\n     *\/\n    public function decline(int $id): void\n    {\n        $this->requireCsrf();\n        $this->repository->updateOrderStatus($id, 'draft');\n        $this->htmxAlert('warning', 'Content abgelehnt. Zurück zu Entwurf.');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    private function getFirstContractId(): ?int\n    {\n        $contracts = $this->repository->findAllContracts();\n        return $contracts !== [] ? (int) $contracts[0]['id'] : null;\n    }\n\n    private function renderVersionPartial(array $result): void\n    {\n        $this->view('content.partials.version', [\n            'content' => $result['content'] ?? '',\n            'sources' => $result['sources'] ?? [],\n            'versionNumber' => $result['version_number'] ?? '?',\n        ]);\n    }\n\n    private function renderCritiquePartial(array $result): void\n    {\n        $this->view('content.partials.critique', [\n            'critiques' => $result['critiques'] ?? [],\n            'allPassed' => $result['all_passed'] ?? false,\n            'round' => $result['round'] ?? '?',\n        ]);\n    }\n}\n",
        "structuredPatch": [
            {
                "oldStart": 2,
                "oldLines": 6,
                "newStart": 2,
                "newLines": 7,
                "lines": [
                    " ",
                    " namespace Controller;",
                    " ",
                    "+use Application\\ContentCollectionService;",
                    " use Framework\\Controller;",
                    " use Infrastructure\\AI\\ModelConfig;",
                    " use Infrastructure\\Persistence\\CollectionRepository;"
                ]
            },
            {
                "oldStart": 14,
                "oldLines": 48,
                "newStart": 15,
                "newLines": 40,
                "lines": [
                    " class ContentController extends Controller",
                    " {",
                    "     private ContentRepository $repository;",
                    "-    private CollectionRepository $collectionRepository;",
                    "-    private CollectionValidator $collectionValidator;",
                    "+    private ContentCollectionService $collectionService;",
                    "     private GenerateContentUseCase $generateUseCase;",
                    " ",
                    "     public function __construct()",
                    "     {",
                    "         $this->repository = new ContentRepository();",
                    "-        $this->collectionRepository = new CollectionRepository();",
                    "-        $this->collectionValidator = new CollectionValidator($this->collectionRepository);",
                    "+        $collectionRepo = new CollectionRepository();",
                    "+        $this->collectionService = new ContentCollectionService(",
                    "+            $collectionRepo,",
                    "+            new CollectionValidator($collectionRepo)",
                    "+        );",
                    "         $this->generateUseCase = new GenerateContentUseCase();",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * GET \/content",
                    "-     * List all content orders",
                    "+     * GET \/content - List all content orders",
                    "      *\/",
                    "     public function index(): void",
                    "     {",
                    "-        $filters = [];",
                    "         $status = $this->getString('status');",
                    "-        if ($status !== '') {",
                    "-            $filters['status'] = $status;",
                    "-        }",
                    " ",
                    "-        $orders = $this->repository->findAllOrders($filters);",
                    "-        $stats = $this->repository->getStatistics();",
                    "-",
                    "         $this->view('content.index', [",
                    "             'title' => 'Content Studio',",
                    "-            'orders' => $orders,",
                    "-            'stats' => $stats,",
                    "+            'orders' => $this->repository->findAllOrders($status !== '' ? ['status' => $status] : []),",
                    "+            'stats' => $this->repository->getStatistics(),",
                    "             'currentStatus' => $status,",
                    "         ]);",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * GET \/content\/new",
                    "-     * Show create form",
                    "+     * GET \/content\/new - Show create form",
                    "      *\/",
                    "     public function contentNew(): void",
                    "     {",
                    "-        $collections = $this->getAvailableCollections();",
                    "         $lastSettings = $this->repository->getLastOrderSettings();",
                    " ",
                    "         $this->view('content.new', ["
                ]
            },
            {
                "oldStart": 64,
                "oldLines": 8,
                "newStart": 57,
                "newLines": 7,
                "lines": [
                    "             'contracts' => $this->repository->findAllContracts(),",
                    "             'structures' => $this->repository->findAllStructures(),",
                    "             'models' => ModelConfig::getAll(),",
                    "-            'collections' => $collections,",
                    "-            \/\/ Defaults from last order",
                    "+            'collections' => $this->collectionService->getAvailable(),",
                    "             'defaultModel' => $lastSettings['model'],",
                    "             'defaultCollections' => $lastSettings['collections'],",
                    "             'defaultContextLimit' => $lastSettings['context_limit'],"
                ]
            },
            {
                "oldStart": 76,
                "oldLines": 8,
                "newStart": 68,
                "newLines": 7,
                "lines": [
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content",
                    "-     * Store new order",
                    "+     * POST \/content - Store new order",
                    "      *\/",
                    "     public function store(): void",
                    "     {"
                ]
            },
            {
                "oldStart": 91,
                "oldLines": 91,
                "newStart": 82,
                "newLines": 69,
                "lines": [
                    "             $this->redirect('\/content\/new');",
                    "         }",
                    " ",
                    "-        \/\/ Auto-apply first active contract if none selected",
                    "-        $contractId = $command->contractId;",
                    "-        if ($contractId === null) {",
                    "-            $contracts = $this->repository->findAllContracts();",
                    "-            if ($contracts !== []) {",
                    "-                $contractId = (int) $contracts[0]['id'];",
                    "-            }",
                    "-        }",
                    "-",
                    "-        \/\/ Validate collection compatibility",
                    "-        $collections = $this->validateCollections($command->collections);",
                    "-        $compatibility = $this->validateCollectionCompatibility($collections);",
                    "-        if (!$compatibility['valid']) {",
                    "-            $_SESSION['error'] = 'Collection-Fehler: ' . $compatibility['error'];",
                    "+        \/\/ Validate collections",
                    "+        $result = $this->collectionService->validateWithCompatibility($command->collections);",
                    "+        if (!$result['valid']) {",
                    "+            $_SESSION['error'] = 'Collection-Fehler: ' . $result['error'];",
                    "             $this->redirect('\/content\/new');",
                    "         }",
                    " ",
                    "-        $model = ModelConfig::validate($command->model);",
                    "-",
                    "         $orderId = $this->repository->createOrder([",
                    "             'title' => $command->title,",
                    "             'briefing' => $command->briefing,",
                    "             'author_profile_id' => $command->authorProfileId,",
                    "-            'contract_id' => $contractId,",
                    "+            'contract_id' => $command->contractId ?? $this->getFirstContractId(),",
                    "             'structure_id' => $command->structureId,",
                    "-            'model' => $model,",
                    "-            'collections' => json_encode($collections),",
                    "+            'model' => ModelConfig::validate($command->model),",
                    "+            'collections' => json_encode($result['collections']),",
                    "             'context_limit' => $command->contextLimit,",
                    "         ]);",
                    " ",
                    "-        \/\/ If \"generate\" action: generate content immediately",
                    "         if ($command->shouldGenerate()) {",
                    "-            $collection = $collections[0] ?? 'documents';",
                    "-            $result = $this->generateUseCase->generate($orderId, $model, $collection, $command->contextLimit);",
                    "-",
                    "-            if ($result->hasError()) {",
                    "-                $_SESSION['error'] = 'Generierung fehlgeschlagen: ' . $result->getError();",
                    "-            } else {",
                    "-                $_SESSION['success'] = 'Content wurde generiert.';",
                    "-            }",
                    "+            $genResult = $this->generateUseCase->generate(",
                    "+                $orderId,",
                    "+                ModelConfig::validate($command->model),",
                    "+                $result['collections'][0] ?? 'documents',",
                    "+                $command->contextLimit",
                    "+            );",
                    "+            $_SESSION[$genResult->hasError() ? 'error' : 'success'] =",
                    "+                $genResult->hasError() ? 'Generierung fehlgeschlagen: ' . $genResult->getError() : 'Content wurde generiert.';",
                    "         }",
                    " ",
                    "         $this->redirect('\/content\/' . $orderId);",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * GET \/content\/{id}",
                    "-     * Show order details",
                    "+     * GET \/content\/{id} - Show order details",
                    "      *\/",
                    "     public function show(int $id): void",
                    "     {",
                    "         $order = $this->repository->findOrder($id);",
                    "-",
                    "         if ($order === null) {",
                    "             $this->notFound('Auftrag nicht gefunden');",
                    "         }",
                    " ",
                    "         $versions = $this->repository->findVersionsByOrder($id);",
                    "         $latestVersion = $versions[0] ?? null;",
                    "-        $critiques = $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [];",
                    "-        $sources = $this->repository->findSourcesByOrder($id);",
                    " ",
                    "-        \/\/ Get available collections for the dropdown",
                    "-        $availableCollections = $this->getAvailableCollections();",
                    "-",
                    "         $this->view('content.show', [",
                    "             'title' => $order['title'],",
                    "             'order' => $order,",
                    "             'versions' => $versions,",
                    "             'latestVersion' => $latestVersion,",
                    "-            'critiques' => $critiques,",
                    "-            'sources' => $sources,",
                    "+            'critiques' => $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [],",
                    "+            'sources' => $this->repository->findSourcesByOrder($id),",
                    "             'models' => ModelConfig::getAll(),",
                    "-            'availableCollections' => $availableCollections,",
                    "+            'availableCollections' => $this->collectionService->getAvailable(),",
                    "         ]);",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * GET \/content\/{id}\/edit",
                    "-     * Show edit form",
                    "+     * GET \/content\/{id}\/edit - Show edit form",
                    "      *\/",
                    "     public function edit(int $id): void",
                    "     {",
                    "         $order = $this->repository->findOrder($id);",
                    "-",
                    "         if ($order === null) {",
                    "             $this->notFound('Auftrag nicht gefunden');",
                    "         }"
                ]
            },
            {
                "oldStart": 190,
                "oldLines": 103,
                "newStart": 159,
                "newLines": 71,
                "lines": [
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content\/{id}\/generate",
                    "-     * Generate content (HTMX)",
                    "+     * POST \/content\/{id}\/generate - Generate content (HTMX)",
                    "      *\/",
                    "     public function generate(int $id): void",
                    "     {",
                    "         $this->requireCsrf();",
                    " ",
                    "         $command = GenerateContentCommand::fromRequest($id, $_POST);",
                    "-        $errors = $command->validate();",
                    "-",
                    "-        if ($errors !== []) {",
                    "+        if (($errors = $command->validate()) !== []) {",
                    "             $this->htmxError(implode(' ', $errors));",
                    "-",
                    "             return;",
                    "         }",
                    " ",
                    "-        \/\/ Validate collection",
                    "-        $collections = $this->validateCollections([$command->collection]);",
                    "-        if (empty($collections)) {",
                    "-            $this->htmxError('Ungültige Collection: ' . $command->collection);",
                    "-",
                    "+        $result = $this->collectionService->validateWithCompatibility([$command->collection]);",
                    "+        if (!$result['valid']) {",
                    "+            $this->htmxError($result['error'] ?? 'Collection-Fehler');",
                    "             return;",
                    "         }",
                    "-        $collection = $collections[0];",
                    " ",
                    "-        \/\/ Validate compatibility (single collection always valid, but check exists)",
                    "-        $compatibility = $this->validateCollectionCompatibility($collections);",
                    "-        if (!$compatibility['valid']) {",
                    "-            $this->htmxError($compatibility['error'] ?? 'Collection-Fehler');",
                    "-",
                    "+        $genResult = $this->generateUseCase->generate($id, $command->model, $result['collections'][0], $command->contextLimit);",
                    "+        if ($genResult->hasError()) {",
                    "+            $this->htmxError('Fehler: ' . $genResult->getError());",
                    "             return;",
                    "         }",
                    " ",
                    "-        $result = $this->generateUseCase->generate($id, $command->model, $collection, $command->contextLimit);",
                    "-",
                    "-        if ($result->hasError()) {",
                    "-            $this->htmxError('Fehler: ' . $result->getError());",
                    "-",
                    "-            return;",
                    "-        }",
                    "-",
                    "-        \/\/ Return updated content section",
                    "-        $this->renderVersionPartial($result->toArray());",
                    "+        $this->renderVersionPartial($genResult->toArray());",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content\/{id}\/critique",
                    "-     * Run critique round (HTMX)",
                    "+     * POST \/content\/{id}\/critique - Run critique round (HTMX)",
                    "      *\/",
                    "     public function critique(int $id): void",
                    "     {",
                    "         $this->requireCsrf();",
                    " ",
                    "-        \/\/ Get latest version",
                    "         $version = $this->repository->findLatestVersion($id);",
                    "-",
                    "         if ($version === null) {",
                    "             $this->htmxError('Keine Version vorhanden.');",
                    "-",
                    "             return;",
                    "         }",
                    " ",
                    "-        $model = $_POST['model'] ?? 'claude-opus-4-5-20251101';",
                    "-        $result = $this->generateUseCase->critique($version['id'], $model);",
                    "-",
                    "+        $result = $this->generateUseCase->critique($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');",
                    "         if ($result->hasError()) {",
                    "             $this->htmxError('Fehler: ' . $result->getError());",
                    "-",
                    "             return;",
                    "         }",
                    " ",
                    "-        \/\/ Return critique results",
                    "         $this->renderCritiquePartial($result->toArray());",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content\/{id}\/revise",
                    "-     * Create revision (HTMX)",
                    "+     * POST \/content\/{id}\/revise - Create revision (HTMX)",
                    "      *\/",
                    "     public function revise(int $id): void",
                    "     {",
                    "         $this->requireCsrf();",
                    " ",
                    "         $version = $this->repository->findLatestVersion($id);",
                    "-",
                    "         if ($version === null) {",
                    "             $this->htmxError('Keine Version vorhanden.');",
                    "-",
                    "             return;",
                    "         }",
                    " ",
                    "-        $model = $_POST['model'] ?? 'claude-opus-4-5-20251101';",
                    "-        $result = $this->generateUseCase->revise($version['id'], $model);",
                    "-",
                    "+        $result = $this->generateUseCase->revise($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');",
                    "         if ($result->hasError()) {",
                    "             $this->htmxError('Fehler: ' . $result->getError());",
                    "-",
                    "             return;",
                    "         }",
                    " "
                ]
            },
            {
                "oldStart": 294,
                "oldLines": 34,
                "newStart": 231,
                "newLines": 33,
                "lines": [
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content\/{id}\/approve",
                    "-     * Approve content",
                    "+     * POST \/content\/{id}\/approve - Approve content",
                    "      *\/",
                    "     public function approve(int $id): void",
                    "     {",
                    "         $this->requireCsrf();",
                    "-",
                    "         $this->repository->updateOrderStatus($id, 'approve');",
                    "         $this->htmxSuccess('Content genehmigt!');",
                    "         echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';",
                    "     }",
                    " ",
                    "     \/**",
                    "-     * POST \/content\/{id}\/decline",
                    "-     * Decline content",
                    "+     * POST \/content\/{id}\/decline - Decline content",
                    "      *\/",
                    "     public function decline(int $id): void",
                    "     {",
                    "         $this->requireCsrf();",
                    "-",
                    "         $this->repository->updateOrderStatus($id, 'draft');",
                    "         $this->htmxAlert('warning', 'Content abgelehnt. Zurück zu Entwurf.');",
                    "         echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';",
                    "     }",
                    " ",
                    "-    \/**",
                    "-     * Render version partial",
                    "-     *\/",
                    "+    private function getFirstContractId(): ?int",
                    "+    {",
                    "+        $contracts = $this->repository->findAllContracts();",
                    "+        return $contracts !== [] ? (int) $contracts[0]['id'] : null;",
                    "+    }",
                    "+",
                    "     private function renderVersionPartial(array $result): void",
                    "     {",
                    "         $this->view('content.partials.version', ["
                ]
            },
            {
                "oldStart": 331,
                "oldLines": 9,
                "newStart": 267,
                "newLines": 6,
                "lines": [
                    "         ]);",
                    "     }",
                    " ",
                    "-    \/**",
                    "-     * Render critique partial",
                    "-     *\/",
                    "     private function renderCritiquePartial(array $result): void",
                    "     {",
                    "         $this->view('content.partials.critique', ["
                ]
            },
            {
                "oldStart": 342,
                "oldLines": 56,
                "newStart": 275,
                "newLines": 4,
                "lines": [
                    "             'round' => $result['round'] ?? '?',",
                    "         ]);",
                    "     }",
                    "-",
                    "-    \/**",
                    "-     * Get available collections from database",
                    "-     *",
                    "-     * @return array<int, array<string,mixed>>",
                    "-     *\/",
                    "-    private function getAvailableCollections(): array",
                    "-    {",
                    "-        $collections = $this->collectionRepository->getSearchable();",
                    "-",
                    "-        if ($collections === []) {",
                    "-            return [",
                    "-                ['collection_id' => 'documents', 'display_name' => 'Dokumente', 'points_count' => 0, 'vector_size' => 1024],",
                    "-            ];",
                    "-        }",
                    "-",
                    "-        return $collections;",
                    "-    }",
                    "-",
                    "-    \/**",
                    "-     * Validate collections against available ones",
                    "-     *",
                    "-     * @param array<string> $collections",
                    "-     * @return array<string>",
                    "-     *\/",
                    "-    private function validateCollections(array $collections): array",
                    "-    {",
                    "-        $availableIds = array_column($this->getAvailableCollections(), 'collection_id');",
                    "-        $valid = array_filter($collections, fn ($c) => in_array($c, $availableIds, true));",
                    "-",
                    "-        return array_values($valid);",
                    "-    }",
                    "-",
                    "-    \/**",
                    "-     * Validate collection compatibility (vector dimensions)",
                    "-     *",
                    "-     * @param array<string> $collectionIds",
                    "-     * @return array{valid: bool, error: string|null}",
                    "-     *\/",
                    "-    private function validateCollectionCompatibility(array $collectionIds): array",
                    "-    {",
                    "-        if (empty($collectionIds)) {",
                    "-            return ['valid' => true, 'error' => null];",
                    "-        }",
                    "-",
                    "-        $result = $this->collectionValidator->validateSelection($collectionIds);",
                    "-",
                    "-        return [",
                    "-            'valid' => $result->isValid(),",
                    "-            'error' => $result->getError(),",
                    "-        ];",
                    "-    }",
                    " }"
                ]
            }
        ],
        "originalFile": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse Infrastructure\\AI\\ModelConfig;\nuse Infrastructure\\Persistence\\CollectionRepository;\nuse Infrastructure\\Persistence\\ContentRepository;\nuse Infrastructure\\Validation\\CollectionValidator;\nuse UseCases\\Command\\CreateContentOrderCommand;\nuse UseCases\\Command\\GenerateContentCommand;\nuse UseCases\\Content\\GenerateContentUseCase;\n\nclass ContentController extends Controller\n{\n    private ContentRepository $repository;\n    private CollectionRepository $collectionRepository;\n    private CollectionValidator $collectionValidator;\n    private GenerateContentUseCase $generateUseCase;\n\n    public function __construct()\n    {\n        $this->repository = new ContentRepository();\n        $this->collectionRepository = new CollectionRepository();\n        $this->collectionValidator = new CollectionValidator($this->collectionRepository);\n        $this->generateUseCase = new GenerateContentUseCase();\n    }\n\n    \/**\n     * GET \/content\n     * List all content orders\n     *\/\n    public function index(): void\n    {\n        $filters = [];\n        $status = $this->getString('status');\n        if ($status !== '') {\n            $filters['status'] = $status;\n        }\n\n        $orders = $this->repository->findAllOrders($filters);\n        $stats = $this->repository->getStatistics();\n\n        $this->view('content.index', [\n            'title' => 'Content Studio',\n            'orders' => $orders,\n            'stats' => $stats,\n            'currentStatus' => $status,\n        ]);\n    }\n\n    \/**\n     * GET \/content\/new\n     * Show create form\n     *\/\n    public function contentNew(): void\n    {\n        $collections = $this->getAvailableCollections();\n        $lastSettings = $this->repository->getLastOrderSettings();\n\n        $this->view('content.new', [\n            'title' => 'Neuer Content-Auftrag',\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n            'models' => ModelConfig::getAll(),\n            'collections' => $collections,\n            \/\/ Defaults from last order\n            'defaultModel' => $lastSettings['model'],\n            'defaultCollections' => $lastSettings['collections'],\n            'defaultContextLimit' => $lastSettings['context_limit'],\n            'defaultProfileId' => $lastSettings['author_profile_id'],\n            'defaultContractId' => $lastSettings['contract_id'],\n            'defaultStructureId' => $lastSettings['structure_id'],\n        ]);\n    }\n\n    \/**\n     * POST \/content\n     * Store new order\n     *\/\n    public function store(): void\n    {\n        $this->requireCsrf();\n\n        $command = CreateContentOrderCommand::fromRequest($_POST);\n        $errors = $command->validate();\n\n        if ($errors !== []) {\n            $_SESSION['error'] = implode(' ', $errors);\n            $this->redirect('\/content\/new');\n        }\n\n        \/\/ Auto-apply first active contract if none selected\n        $contractId = $command->contractId;\n        if ($contractId === null) {\n            $contracts = $this->repository->findAllContracts();\n            if ($contracts !== []) {\n                $contractId = (int) $contracts[0]['id'];\n            }\n        }\n\n        \/\/ Validate collection compatibility\n        $collections = $this->validateCollections($command->collections);\n        $compatibility = $this->validateCollectionCompatibility($collections);\n        if (!$compatibility['valid']) {\n            $_SESSION['error'] = 'Collection-Fehler: ' . $compatibility['error'];\n            $this->redirect('\/content\/new');\n        }\n\n        $model = ModelConfig::validate($command->model);\n\n        $orderId = $this->repository->createOrder([\n            'title' => $command->title,\n            'briefing' => $command->briefing,\n            'author_profile_id' => $command->authorProfileId,\n            'contract_id' => $contractId,\n            'structure_id' => $command->structureId,\n            'model' => $model,\n            'collections' => json_encode($collections),\n            'context_limit' => $command->contextLimit,\n        ]);\n\n        \/\/ If \"generate\" action: generate content immediately\n        if ($command->shouldGenerate()) {\n            $collection = $collections[0] ?? 'documents';\n            $result = $this->generateUseCase->generate($orderId, $model, $collection, $command->contextLimit);\n\n            if ($result->hasError()) {\n                $_SESSION['error'] = 'Generierung fehlgeschlagen: ' . $result->getError();\n            } else {\n                $_SESSION['success'] = 'Content wurde generiert.';\n            }\n        }\n\n        $this->redirect('\/content\/' . $orderId);\n    }\n\n    \/**\n     * GET \/content\/{id}\n     * Show order details\n     *\/\n    public function show(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $versions = $this->repository->findVersionsByOrder($id);\n        $latestVersion = $versions[0] ?? null;\n        $critiques = $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [];\n        $sources = $this->repository->findSourcesByOrder($id);\n\n        \/\/ Get available collections for the dropdown\n        $availableCollections = $this->getAvailableCollections();\n\n        $this->view('content.show', [\n            'title' => $order['title'],\n            'order' => $order,\n            'versions' => $versions,\n            'latestVersion' => $latestVersion,\n            'critiques' => $critiques,\n            'sources' => $sources,\n            'models' => ModelConfig::getAll(),\n            'availableCollections' => $availableCollections,\n        ]);\n    }\n\n    \/**\n     * GET \/content\/{id}\/edit\n     * Show edit form\n     *\/\n    public function edit(int $id): void\n    {\n        $order = $this->repository->findOrder($id);\n\n        if ($order === null) {\n            $this->notFound('Auftrag nicht gefunden');\n        }\n\n        $this->view('content.edit', [\n            'title' => 'Auftrag bearbeiten',\n            'order' => $order,\n            'profiles' => $this->repository->findAllProfiles(),\n            'contracts' => $this->repository->findAllContracts(),\n            'structures' => $this->repository->findAllStructures(),\n        ]);\n    }\n\n    \/**\n     * POST \/content\/{id}\/generate\n     * Generate content (HTMX)\n     *\/\n    public function generate(int $id): void\n    {\n        $this->requireCsrf();\n\n        $command = GenerateContentCommand::fromRequest($id, $_POST);\n        $errors = $command->validate();\n\n        if ($errors !== []) {\n            $this->htmxError(implode(' ', $errors));\n\n            return;\n        }\n\n        \/\/ Validate collection\n        $collections = $this->validateCollections([$command->collection]);\n        if (empty($collections)) {\n            $this->htmxError('Ungültige Collection: ' . $command->collection);\n\n            return;\n        }\n        $collection = $collections[0];\n\n        \/\/ Validate compatibility (single collection always valid, but check exists)\n        $compatibility = $this->validateCollectionCompatibility($collections);\n        if (!$compatibility['valid']) {\n            $this->htmxError($compatibility['error'] ?? 'Collection-Fehler');\n\n            return;\n        }\n\n        $result = $this->generateUseCase->generate($id, $command->model, $collection, $command->contextLimit);\n\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n\n            return;\n        }\n\n        \/\/ Return updated content section\n        $this->renderVersionPartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/critique\n     * Run critique round (HTMX)\n     *\/\n    public function critique(int $id): void\n    {\n        $this->requireCsrf();\n\n        \/\/ Get latest version\n        $version = $this->repository->findLatestVersion($id);\n\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n\n            return;\n        }\n\n        $model = $_POST['model'] ?? 'claude-opus-4-5-20251101';\n        $result = $this->generateUseCase->critique($version['id'], $model);\n\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n\n            return;\n        }\n\n        \/\/ Return critique results\n        $this->renderCritiquePartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/revise\n     * Create revision (HTMX)\n     *\/\n    public function revise(int $id): void\n    {\n        $this->requireCsrf();\n\n        $version = $this->repository->findLatestVersion($id);\n\n        if ($version === null) {\n            $this->htmxError('Keine Version vorhanden.');\n\n            return;\n        }\n\n        $model = $_POST['model'] ?? 'claude-opus-4-5-20251101';\n        $result = $this->generateUseCase->revise($version['id'], $model);\n\n        if ($result->hasError()) {\n            $this->htmxError('Fehler: ' . $result->getError());\n\n            return;\n        }\n\n        $this->renderVersionPartial($result->toArray());\n    }\n\n    \/**\n     * POST \/content\/{id}\/approve\n     * Approve content\n     *\/\n    public function approve(int $id): void\n    {\n        $this->requireCsrf();\n\n        $this->repository->updateOrderStatus($id, 'approve');\n        $this->htmxSuccess('Content genehmigt!');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    \/**\n     * POST \/content\/{id}\/decline\n     * Decline content\n     *\/\n    public function decline(int $id): void\n    {\n        $this->requireCsrf();\n\n        $this->repository->updateOrderStatus($id, 'draft');\n        $this->htmxAlert('warning', 'Content abgelehnt. Zurück zu Entwurf.');\n        echo '<script>setTimeout(() => window.location.reload(), 1000);<\/script>';\n    }\n\n    \/**\n     * Render version partial\n     *\/\n    private function renderVersionP... [TRUNCATED-5278a8668f7433bb]"
    }
}
← Vorheriger Zur Liste Nächster →