SaveTaskResultUseCase.php

Code Hygiene Score: 98

Keine Issues gefunden.

Dependencies 9

Klassen 1

Funktionen 3

Verwendet von 3

Versionen 4

Code

<?php

declare(strict_types=1);

namespace UseCases\Task;

// @responsibility: Speichert Task-Ergebnisse mit Token-Tracking

use Domain\Entity\TaskComment;
use Domain\Entity\TaskResult;
use Domain\Repository\TaskRepositoryInterface;
use Domain\ValueObject\AssigneeType;
use Infrastructure\Persistence\TaskCommentRepository;
use Infrastructure\Persistence\TaskResultRepository;

class SaveTaskResultUseCase
{
    public function __construct(
        private TaskRepositoryInterface $taskRepository,
        private TaskResultRepository $resultRepository,
        private TaskCommentRepository $commentRepository
    ) {
    }

    public function execute(int $taskId, array $data): TaskResult
    {
        $this->validate($data);

        $task = $this->taskRepository->find($taskId);
        if ($task === null) {
            throw new \InvalidArgumentException("Task {$taskId} not found");
        }

        $executorType = AssigneeType::from($data['executor_type']);
        $builder = TaskResult::builder($taskId, $data['executor'], $executorType);

        if (isset($data['assignment_id'])) {
            $builder->withAssignment((int) $data['assignment_id']);
        }

        if (isset($data['model_name'])) {
            $builder->withModel($data['model_name']);
        }

        if (isset($data['request'])) {
            $builder->withRequest($data['request']);
        }

        if (isset($data['response'])) {
            $builder->withResponse($data['response']);
        }

        if (isset($data['tokens_input'], $data['tokens_output'])) {
            $builder->withTokens((int) $data['tokens_input'], (int) $data['tokens_output']);
        } else {
            $builder->estimateTokens();
        }

        if (isset($data['cost_usd'])) {
            $builder->withCost((float) $data['cost_usd']);
        }

        if (isset($data['error_message'])) {
            $builder->withError($data['error_message']);
        } elseif (isset($data['status'])) {
            $builder->withStatus(\Domain\ValueObject\ResultStatus::from($data['status']));
        }

        $result = $builder->build();

        $id = $this->resultRepository->save($result);
        $result->setId($id);

        $status = $result->isSuccess() ? 'erfolgreich' : 'mit Fehler';
        $comment = new TaskComment();
        $comment->setTaskId($taskId);
        $comment->setAuthor($result->executor());
        $comment->setAuthorType($executorType->isAI() ? 'ai' : 'human');
        $comment->setCommentType('result');
        $comment->setContent("Ergebnis gespeichert ({$status})");
        $comment->setMetadata([
            'result_id' => $id,
            'model' => $result->modelName(),
            'tokens_total' => $result->metrics()->tokens()->total(),
        ]);
        $this->commentRepository->save($comment);

        return $result;
    }

    private function validate(array $data): void
    {
        if (!isset($data['executor']) || $data['executor'] === '') {
            throw new \InvalidArgumentException('Executor is required');
        }

        if (!isset($data['executor_type']) || $data['executor_type'] === '') {
            throw new \InvalidArgumentException('Executor type is required');
        }

        try {
            AssigneeType::from($data['executor_type']);
        } catch (\ValueError $e) {
            throw new \InvalidArgumentException('Invalid executor type');
        }
    }
}
← Übersicht Graph