Backup #974
| ID | 974 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Controller/ContentController.php |
| Version | 57 |
| Typ |
modified |
| Größe | 9.2 KB |
| Hash | 896f08b73a46cd333e46916dba870ca67df37a43a0706fa1a02b91c47df68999 |
| Datum | 2025-12-24 00:12:13 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
declare(strict_types=1);
namespace Controller;
// @responsibility: HTTP-Endpunkte für Content Studio (Aufträge, Generierung, Kritik)
use Application\ContentCollectionService;
use Framework\Controller;
use Infrastructure\AI\ModelConfig;
use Infrastructure\Persistence\ContentRepository;
use UseCases\Command\CreateContentOrderCommand;
use UseCases\Command\GenerateContentCommand;
use UseCases\Content\GenerateContentUseCase;
class ContentController extends Controller
{
private ContentRepository $repository;
private ContentCollectionService $collectionService;
private GenerateContentUseCase $generateUseCase;
public function __construct(
ContentRepository $repository,
ContentCollectionService $collectionService,
GenerateContentUseCase $generateUseCase
) {
$this->repository = $repository;
$this->collectionService = $collectionService;
$this->generateUseCase = $generateUseCase;
}
/**
* GET /content - List all content orders
*/
public function index(): void
{
$status = $this->getString('status');
$this->view('content.index', [
'title' => 'Content Studio',
'orders' => $this->repository->findAllOrders($status !== '' ? ['status' => $status] : []),
'stats' => $this->repository->getStatistics(),
'currentStatus' => $status,
]);
}
/**
* GET /content/new - Show create form
*/
public function contentNew(): void
{
$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' => $this->collectionService->getAvailable(),
'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);
$this->redirect('/content/new');
}
// Validate collections
$result = $this->collectionService->validateWithCompatibility($command->collections);
if (!$result['valid']) {
$_SESSION['error'] = 'Collection-Fehler: ' . $result['error'];
$this->redirect('/content/new');
}
$orderId = $this->repository->createOrder([
'title' => $command->title,
'briefing' => $command->briefing,
'author_profile_id' => $command->authorProfileId,
'contract_id' => $command->contractId ?? $this->getFirstContractId(),
'structure_id' => $command->structureId,
'model' => ModelConfig::validate($command->model),
'collections' => json_encode($result['collections']),
'context_limit' => $command->contextLimit,
]);
if ($command->shouldGenerate()) {
$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
*/
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;
$this->view('content.show', [
'title' => $order['title'],
'order' => $order,
'versions' => $versions,
'latestVersion' => $latestVersion,
'critiques' => $latestVersion ? $this->repository->findCritiquesByVersion($latestVersion['id']) : [],
'sources' => $this->repository->findSourcesByOrder($id),
'models' => ModelConfig::getAll(),
'availableCollections' => $this->collectionService->getAvailable(),
]);
}
/**
* 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);
if (($errors = $command->validate()) !== []) {
$this->htmxError(implode(' ', $errors));
return;
}
$result = $this->collectionService->validateWithCompatibility([$command->collection]);
if (!$result['valid']) {
$this->htmxError($result['error'] ?? 'Collection-Fehler');
return;
}
$genResult = $this->generateUseCase->generate($id, $command->model, $result['collections'][0], $command->contextLimit);
if ($genResult->hasError()) {
$this->htmxError('Fehler: ' . $genResult->getError());
return;
}
$this->renderVersionPartial($genResult->toArray());
}
/**
* POST /content/{id}/critique - Run critique round (HTMX)
*/
public function critique(int $id): void
{
$this->requireCsrf();
$version = $this->repository->findLatestVersion($id);
if ($version === null) {
$this->htmxError('Keine Version vorhanden.');
return;
}
$result = $this->generateUseCase->critique($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');
if ($result->hasError()) {
$this->htmxError('Fehler: ' . $result->getError());
return;
}
$this->renderCritiquePartial($result->toArray());
}
/**
* 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;
}
$result = $this->generateUseCase->revise($version['id'], $_POST['model'] ?? 'claude-opus-4-5-20251101');
if ($result->hasError()) {
$this->htmxError('Fehler: ' . $result->getError());
return;
}
$this->renderVersionPartial($result->toArray());
}
/**
* POST /content/{id}/approve - Approve content
*/
public function approve(int $id): void
{
$this->requireCsrf();
$this->repository->updateOrderStatus($id, 'approve');
$this->htmxSuccess('Content genehmigt!');
$this->html('<script>setTimeout(() => window.location.reload(), 1000);</script>');
}
/**
* 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.');
$this->html('<script>setTimeout(() => window.location.reload(), 1000);</script>');
}
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', [
'content' => $result['content'] ?? '',
'sources' => $result['sources'] ?? [],
'versionNumber' => $result['version_number'] ?? '?',
]);
}
private function renderCritiquePartial(array $result): void
{
$this->view('content.partials.critique', [
'critiques' => $result['critiques'] ?? [],
'allPassed' => $result['all_passed'] ?? false,
'round' => $result['round'] ?? '?',
]);
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 2162 |
71 |
modified |
14.5 KB |
2025-12-30 22:24 |
| 2161 |
70 |
modified |
14.3 KB |
2025-12-30 22:24 |
| 2160 |
69 |
modified |
14.1 KB |
2025-12-30 22:24 |
| 2159 |
68 |
modified |
13.6 KB |
2025-12-30 22:23 |
| 1768 |
67 |
modified |
13.2 KB |
2025-12-27 12:55 |
| 1297 |
66 |
modified |
13.1 KB |
2025-12-25 13:27 |
| 1296 |
65 |
modified |
13.0 KB |
2025-12-25 13:27 |
| 1295 |
64 |
modified |
13.0 KB |
2025-12-25 13:27 |
| 1294 |
63 |
modified |
13.2 KB |
2025-12-25 13:27 |
| 1276 |
62 |
modified |
13.2 KB |
2025-12-25 12:52 |
| 1015 |
61 |
modified |
10.9 KB |
2025-12-24 01:29 |
| 986 |
60 |
modified |
10.7 KB |
2025-12-24 00:41 |
| 985 |
59 |
modified |
10.8 KB |
2025-12-24 00:31 |
| 984 |
58 |
modified |
10.4 KB |
2025-12-24 00:18 |
| 974 |
57 |
modified |
9.2 KB |
2025-12-24 00:12 |
| 686 |
56 |
modified |
9.1 KB |
2025-12-23 07:51 |
| 633 |
55 |
modified |
9.2 KB |
2025-12-23 04:45 |
| 618 |
54 |
modified |
9.5 KB |
2025-12-23 04:42 |
| 590 |
53 |
modified |
9.2 KB |
2025-12-23 04:24 |
| 530 |
52 |
modified |
11.8 KB |
2025-12-22 21:19 |
| 509 |
51 |
modified |
11.9 KB |
2025-12-22 15:42 |
| 508 |
50 |
modified |
11.9 KB |
2025-12-22 15:42 |
| 501 |
49 |
modified |
11.9 KB |
2025-12-22 15:40 |
| 500 |
48 |
modified |
11.9 KB |
2025-12-22 15:40 |
| 499 |
47 |
modified |
12.0 KB |
2025-12-22 15:40 |
| 498 |
46 |
modified |
12.0 KB |
2025-12-22 15:40 |
| 497 |
45 |
modified |
12.2 KB |
2025-12-22 15:38 |
| 489 |
44 |
modified |
12.1 KB |
2025-12-22 15:27 |
| 488 |
43 |
modified |
12.4 KB |
2025-12-22 15:27 |
| 487 |
42 |
modified |
12.3 KB |
2025-12-22 15:27 |
| 320 |
41 |
modified |
12.3 KB |
2025-12-22 08:06 |
| 280 |
40 |
modified |
14.1 KB |
2025-12-22 02:18 |
| 279 |
39 |
modified |
14.1 KB |
2025-12-22 02:17 |
| 278 |
38 |
modified |
14.1 KB |
2025-12-22 02:17 |
| 277 |
37 |
modified |
14.1 KB |
2025-12-22 02:17 |
| 276 |
36 |
modified |
14.1 KB |
2025-12-22 02:17 |
| 275 |
35 |
modified |
14.1 KB |
2025-12-22 02:17 |
| 267 |
34 |
modified |
15.4 KB |
2025-12-22 02:10 |
| 266 |
33 |
modified |
16.0 KB |
2025-12-22 02:10 |
| 234 |
32 |
modified |
16.0 KB |
2025-12-22 01:46 |
| 233 |
31 |
modified |
16.1 KB |
2025-12-22 01:46 |
| 207 |
30 |
modified |
15.6 KB |
2025-12-21 17:01 |
| 198 |
29 |
modified |
15.9 KB |
2025-12-21 14:39 |
| 190 |
28 |
modified |
14.4 KB |
2025-12-21 14:36 |
| 189 |
27 |
modified |
13.8 KB |
2025-12-21 14:35 |
| 188 |
26 |
modified |
13.4 KB |
2025-12-21 14:35 |
| 187 |
25 |
modified |
13.5 KB |
2025-12-21 14:35 |
| 186 |
24 |
modified |
13.6 KB |
2025-12-21 14:35 |
| 185 |
23 |
modified |
13.2 KB |
2025-12-21 14:35 |
| 178 |
22 |
modified |
13.4 KB |
2025-12-21 09:14 |
| 177 |
21 |
modified |
13.0 KB |
2025-12-21 09:14 |
| 173 |
20 |
modified |
12.8 KB |
2025-12-21 04:13 |
| 172 |
19 |
modified |
12.6 KB |
2025-12-21 04:13 |
| 166 |
18 |
modified |
12.6 KB |
2025-12-21 04:11 |
| 165 |
17 |
modified |
12.6 KB |
2025-12-21 04:11 |
| 164 |
16 |
modified |
12.6 KB |
2025-12-21 04:11 |
| 163 |
15 |
modified |
12.8 KB |
2025-12-21 04:11 |
| 160 |
14 |
modified |
12.5 KB |
2025-12-21 03:00 |
| 157 |
13 |
modified |
12.1 KB |
2025-12-21 02:59 |
| 156 |
12 |
modified |
11.8 KB |
2025-12-21 02:59 |
| 155 |
11 |
modified |
11.4 KB |
2025-12-21 02:59 |
| 139 |
10 |
modified |
11.4 KB |
2025-12-20 19:58 |
| 138 |
9 |
modified |
11.3 KB |
2025-12-20 19:57 |
| 137 |
8 |
modified |
10.8 KB |
2025-12-20 19:57 |
| 134 |
7 |
modified |
10.4 KB |
2025-12-20 19:55 |
| 113 |
6 |
modified |
10.4 KB |
2025-12-20 19:20 |
| 112 |
5 |
modified |
10.3 KB |
2025-12-20 19:20 |
| 111 |
4 |
modified |
10.3 KB |
2025-12-20 19:20 |
| 110 |
3 |
modified |
10.3 KB |
2025-12-20 19:20 |
| 109 |
2 |
modified |
10.2 KB |
2025-12-20 19:19 |
| 108 |
1 |
modified |
10.2 KB |
2025-12-20 19:19 |
← Zurück zur Übersicht