Backup #2052

ID2052
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Controller/Api/TaskController.php
Version29
Typ modified
Größe12.6 KB
Hash44a01f7df5c6d09a9c9e6659b42c339b5be569336a3c6b53ce070bdc9d9e1a50
Datum2025-12-28 23:27:55
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace Controller\Api;

// @responsibility: REST-API für Task-Management (CRUD, Assignments, AI-Execution)

use Domain\Repository\TaskRepositoryInterface;
use Domain\Repository\TaskResultRepositoryInterface;
use Framework\Controller;
use UseCases\Task\AssignTaskUseCase;
use UseCases\Task\CreateTaskUseCase;
use UseCases\Task\DeleteTaskUseCase;
use UseCases\Task\ExecuteAITaskUseCase;
use UseCases\Task\GetTasksUseCase;
use UseCases\Task\SaveTaskResultUseCase;
use UseCases\Task\UpdateTaskStatusUseCase;

class TaskController extends Controller
{
    private GetTasksUseCase $getTasksUseCase;
    private CreateTaskUseCase $createTaskUseCase;
    private DeleteTaskUseCase $deleteTaskUseCase;
    private AssignTaskUseCase $assignTaskUseCase;
    private UpdateTaskStatusUseCase $updateStatusUseCase;
    private SaveTaskResultUseCase $saveResultUseCase;
    private ExecuteAITaskUseCase $executeAIUseCase;
    private TaskRepositoryInterface $taskRepository;
    private TaskResultRepositoryInterface $resultRepository;

    public function __construct(
        GetTasksUseCase $getTasksUseCase,
        CreateTaskUseCase $createTaskUseCase,
        DeleteTaskUseCase $deleteTaskUseCase,
        AssignTaskUseCase $assignTaskUseCase,
        UpdateTaskStatusUseCase $updateStatusUseCase,
        SaveTaskResultUseCase $saveResultUseCase,
        ExecuteAITaskUseCase $executeAIUseCase,
        TaskRepositoryInterface $taskRepository,
        TaskResultRepositoryInterface $resultRepository
    ) {
        $this->getTasksUseCase = $getTasksUseCase;
        $this->createTaskUseCase = $createTaskUseCase;
        $this->deleteTaskUseCase = $deleteTaskUseCase;
        $this->assignTaskUseCase = $assignTaskUseCase;
        $this->updateStatusUseCase = $updateStatusUseCase;
        $this->saveResultUseCase = $saveResultUseCase;
        $this->executeAIUseCase = $executeAIUseCase;
        $this->taskRepository = $taskRepository;
        $this->resultRepository = $resultRepository;
    }

    public function index(): void
    {
        try {
            $filters = [];
            $status = $this->getString('status');
            if ($status !== '') {
                $filters['status'] = $status;
            }
            $type = $this->getString('type');
            if ($type !== '') {
                $filters['type'] = $type;
            }
            $search = $this->getString('search');
            if ($search !== '') {
                $filters['search'] = $search;
            }

            $limit = $this->getInt('limit', 50);
            $offset = $this->getInt('offset');

            $tasks = $this->getTasksUseCase->execute($filters, $limit, $offset);
            $total = $this->getTasksUseCase->count($filters);

            $this->json([
                'success' => true,
                'data' => array_map(fn ($t) => $t->toArray(), $tasks),
                'meta' => [
                    'total' => $total,
                    'limit' => $limit,
                    'offset' => $offset,
                ],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.index] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    public function show(string $id): void
    {
        try {
            $details = $this->getTasksUseCase->getTaskWithDetails((int) $id);

            if ($details === null) {
                $this->json(['success' => false, 'error' => 'Task not found'], 404);

                return;
            }

            $this->json([
                'success' => true,
                'data' => $details,
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.show] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    public function store(): void
    {
        $this->requireCsrf();

        try {
            $input = $this->getJsonInput();
            if (empty($input)) {
                $input = $_POST;
            }

            $task = $this->createTaskUseCase->execute($input);

            // HTMX: Redirect to new task
            if ($this->isHtmxRequest()) {
                $this->htmxRedirect('/tasks/' . $task->getId());

                return;
            }

            $this->json([
                'success' => true,
                'data' => $task->toArray(),
            ], 201);
        } catch (\InvalidArgumentException $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.store] %s: %s', get_class($e), $e->getMessage()));
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->jsonError($e->getMessage());
        }
    }

    public function update(string $id): void
    {
        $this->requireCsrf();

        try {
            $input = $this->getJsonInput();
            if (empty($input)) {
                $input = $_POST;
            }

            $task = $this->getTasksUseCase->findById((int) $id);

            if ($task === null) {
                if ($this->isHtmxRequest()) {
                    $this->htmxError('Task nicht gefunden');

                    return;
                }
                $this->json(['success' => false, 'error' => 'Task not found'], 404);

                return;
            }

            if (isset($input['title']) || isset($input['description'])) {
                $task->updateDetails(
                    $input['title'] ?? $task->getTitle(),
                    $input['description'] ?? $task->getDescription()
                );
            }
            if (isset($input['type'])) {
                $task->changeType(\Domain\ValueObject\TaskType::from($input['type']));
            }
            if (isset($input['due_date'])) {
                $task->setDueDate(new \DateTimeImmutable($input['due_date']));
            }

            $this->taskRepository->update($task);

            // HTMX: Redirect to task page
            if ($this->isHtmxRequest()) {
                $this->htmxRedirect('/tasks/' . $id);

                return;
            }

            $this->json([
                'success' => true,
                'data' => $task->toArray(),
            ]);
        } catch (\InvalidArgumentException $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.update] %s: %s', get_class($e), $e->getMessage()));
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->jsonError($e->getMessage());
        }
    }

    public function destroy(string $id): void
    {
        try {
            $this->deleteTaskUseCase->execute((int) $id);

            $this->json([
                'success' => true,
                'message' => 'Task deleted',
            ]);
        } catch (\InvalidArgumentException $e) {
            $this->json(['success' => false, 'error' => $e->getMessage()], 404);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.destroy] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    public function assign(string $id): void
    {
        try {
            $input = $this->getJsonInput();

            $assignment = $this->assignTaskUseCase->execute((int) $id, $input);

            $this->json([
                'success' => true,
                'data' => $assignment->toArray(),
            ], 201);
        } catch (\InvalidArgumentException $e) {
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Task.assign] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    public function updateStatus(string $id): void
    {
        $this->requireCsrf();

        try {
            // Accept both JSON and form data
            $input = $this->getJsonInput();
            $status = $input['status'] ?? $_POST['status'] ?? null;

            if ($status === null || $status === '') {
                if ($this->isHtmxRequest()) {
                    $this->htmxError('Status ist erforderlich');

                    return;
                }
                $this->json(['success' => false, 'error' => 'Status is required'], 400);

                return;
            }

            $updatedBy = $input['updated_by'] ?? 'api';
            $updatedByType = $input['updated_by_type'] ?? 'human';

            $task = $this->updateStatusUseCase->execute((int) $id, $status, $updatedBy, $updatedByType);

            // HTMX: Return updated status select
            if ($this->isHtmxRequest()) {
                $this->partial('tasks.partials.status-select', [
                    'task' => $task->toArray(),
                ]);

                return;
            }

            $this->json([
                'success' => true,
                'data' => $task->toArray(),
            ]);
        } catch (\InvalidArgumentException $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\Exception $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->jsonError($e->getMessage());
        }
    }

    public function storeResult(string $id): void
    {
        try {
            $input = $this->getJsonInput();

            $result = $this->saveResultUseCase->execute((int) $id, $input);

            $this->json([
                'success' => true,
                'data' => $result->toArray(),
            ], 201);
        } catch (\InvalidArgumentException $e) {
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    public function getResults(string $id): void
    {
        try {
            $results = $this->resultRepository->findByTaskId((int) $id);

            $this->json([
                'success' => true,
                'data' => array_map(fn ($r) => $r->toArray(), $results),
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    public function executeAI(string $id): void
    {
        $this->requireCsrf();

        try {
            $input = $this->getJsonInput();

            $result = $this->executeAIUseCase->execute((int) $id, $input);

            // HTMX: Redirect to task page on success
            if ($this->isHtmxRequest()) {
                $this->htmxRedirect('/tasks/' . $id);

                return;
            }

            $this->json([
                'success' => true,
                'data' => $result->toArray(),
            ]);
        } catch (\InvalidArgumentException $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->json(['success' => false, 'error' => $e->getMessage()], 400);
        } catch (\RuntimeException $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->json(['success' => false, 'error' => $e->getMessage()], 503);
        } catch (\Exception $e) {
            if ($this->isHtmxRequest()) {
                $this->htmxError($e->getMessage());

                return;
            }
            $this->jsonError($e->getMessage());
        }
    }

    public function statistics(): void
    {
        try {
            $taskStats = $this->getTasksUseCase->getStatistics();

            $tokenStats = $this->resultRepository->getTokenStatistics();
            $modelUsage = $this->resultRepository->getModelUsage();

            $this->json([
                'success' => true,
                'data' => [
                    'tasks' => $taskStats,
                    'tokens' => $tokenStats,
                    'models' => $modelUsage,
                ],
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
2056 33 modified 13.0 KB 2025-12-28 23:28
2055 32 modified 12.9 KB 2025-12-28 23:28
2054 31 modified 12.8 KB 2025-12-28 23:28
2053 30 modified 12.7 KB 2025-12-28 23:28
2052 29 modified 12.6 KB 2025-12-28 23:27
2051 28 modified 12.5 KB 2025-12-28 23:27
2050 27 modified 12.4 KB 2025-12-28 23:27
2049 26 modified 12.4 KB 2025-12-28 23:27
2048 25 modified 12.3 KB 2025-12-28 23:27
2047 24 modified 12.2 KB 2025-12-28 23:27
2046 23 modified 12.1 KB 2025-12-28 23:27
2011 22 modified 12.1 KB 2025-12-28 14:20
1710 21 modified 11.4 KB 2025-12-27 12:25
1709 20 modified 10.8 KB 2025-12-27 12:25
1704 19 modified 10.3 KB 2025-12-27 12:22
1693 18 modified 9.5 KB 2025-12-27 12:12
1456 17 modified 9.4 KB 2025-12-25 17:01
1272 16 modified 9.4 KB 2025-12-25 12:52
703 15 modified 9.3 KB 2025-12-23 07:53
656 14 modified 9.4 KB 2025-12-23 04:48
655 13 modified 9.4 KB 2025-12-23 04:48
654 12 modified 9.5 KB 2025-12-23 04:48
653 11 modified 9.5 KB 2025-12-23 04:48
652 10 modified 9.5 KB 2025-12-23 04:48
651 9 modified 9.6 KB 2025-12-23 04:48
650 8 modified 9.6 KB 2025-12-23 04:48
649 7 modified 9.7 KB 2025-12-23 04:48
648 6 modified 9.7 KB 2025-12-23 04:48
647 5 modified 9.7 KB 2025-12-23 04:48
646 4 modified 8.3 KB 2025-12-23 04:48
309 3 modified 8.3 KB 2025-12-22 08:05
115 2 modified 8.2 KB 2025-12-20 19:20
114 1 modified 8.2 KB 2025-12-20 19:20

← Zurück zur Übersicht