repository = new ContentRepository(); $this->collectionRepository = new CollectionRepository(); $this->collectionValidator = new CollectionValidator($this->collectionRepository); $this->generateUseCase = new GenerateContentUseCase(); } /** * 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, 'currentStatus' => $status, ]); } /** * GET /content/new * Show create form */ public function contentNew(): void { $collections = $this->getAvailableCollections(); $lastSettings = $this->repository->getLastOrderSettings(); $this->view('content.new', [ 'title' => 'Neuer Content-Auftrag', 'profiles' => $this->repository->findAllProfiles(), 'contracts' => $this->repository->findAllContracts(), 'structures' => $this->repository->findAllStructures(), 'models' => ModelConfig::getAll(), 'collections' => $collections, // Defaults from last order 'defaultModel' => $lastSettings['model'], 'defaultCollections' => $lastSettings['collections'], 'defaultContextLimit' => $lastSettings['context_limit'], 'defaultProfileId' => $lastSettings['author_profile_id'], 'defaultContractId' => $lastSettings['contract_id'], 'defaultStructureId' => $lastSettings['structure_id'], ]); } /** * POST /content * Store new order */ public function store(): void { $this->requireCsrf(); $command = CreateContentOrderCommand::fromRequest($_POST); $errors = $command->validate(); if ($errors !== []) { $_SESSION['error'] = implode(' ', $errors); header('Location: /content/new'); exit; } // 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']; header('Location: /content/new'); exit; } $model = ModelConfig::validate($command->model); $orderId = $this->repository->createOrder([ 'title' => $command->title, 'briefing' => $command->briefing, 'author_profile_id' => $command->authorProfileId, 'contract_id' => $contractId, 'structure_id' => $command->structureId, 'model' => $model, 'collections' => json_encode($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.'; } } header('Location: /content/' . $orderId); exit; } /** * 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, 'models' => ModelConfig::getAll(), 'availableCollections' => $availableCollections, ]); } /** * 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'); } $this->view('content.edit', [ 'title' => 'Auftrag bearbeiten', 'order' => $order, 'profiles' => $this->repository->findAllProfiles(), 'contracts' => $this->repository->findAllContracts(), 'structures' => $this->repository->findAllStructures(), ]); } /** * 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 !== []) { echo '