diff --git a/migrations/Version20260517230000.php b/migrations/Version20260517230000.php new file mode 100644 index 0000000..c951a44 --- /dev/null +++ b/migrations/Version20260517230000.php @@ -0,0 +1,26 @@ +addSql('ALTER TABLE app.ai_pipeline_jobs ADD COLUMN current_step VARCHAR(50) NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE app.ai_pipeline_jobs DROP COLUMN current_step'); + } +} diff --git a/src/Domain/Pipeline/AIPipelineJob.php b/src/Domain/Pipeline/AIPipelineJob.php index c7f507c..929ed9e 100644 --- a/src/Domain/Pipeline/AIPipelineJob.php +++ b/src/Domain/Pipeline/AIPipelineJob.php @@ -42,6 +42,9 @@ class AIPipelineJob #[ORM\Column(type: 'text', nullable: true)] private ?string $errorMessage = null; + #[ORM\Column(type: 'string', length: 50, nullable: true)] + private ?string $currentStep = null; + #[ORM\Column(type: 'datetime_immutable')] private \DateTimeImmutable $createdAt; @@ -83,6 +86,16 @@ class AIPipelineJob return $this->status; } + public function getStatusLabel(): string + { + return $this->status->value; + } + + public function getAiResults(): string + { + return ''; + } + public function getAttemptCount(): int { return $this->attemptCount; @@ -111,6 +124,30 @@ class AIPipelineJob return $this->errorMessage; } + public function getCurrentStep(): ?string + { + return $this->currentStep; + } + + public function getInventoryNumber(): ?string + { + return $this->inputData['inventoryNumber'] ?? null; + } + + /** @param array $data */ + public function recordStep(string $step, array $data): void + { + $this->currentStep = $step; + $this->outputData[$step] = $data; + } + + public function resetForRetry(): void + { + $this->status = AIPipelineJobStatus::Queued; + $this->errorMessage = null; + $this->completedAt = null; + } + public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; @@ -130,7 +167,7 @@ class AIPipelineJob public function markCompleted(array $outputData = []): void { $this->status = AIPipelineJobStatus::Completed; - $this->outputData = $outputData; + $this->outputData = array_merge($this->outputData, $outputData); $this->completedAt = new \DateTimeImmutable(); } diff --git a/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php b/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php index 5784a0c..53523be 100644 --- a/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php +++ b/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php @@ -15,5 +15,7 @@ interface AIPipelineJobRepositoryInterface /** @return list */ public function findByStatus(AIPipelineJobStatus $status): array; + public function findByArticleId(Uuid $articleId): ?AIPipelineJob; + public function save(AIPipelineJob $job): void; } diff --git a/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php b/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php index 456b4d6..8e67333 100644 --- a/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php +++ b/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php @@ -28,6 +28,15 @@ final class DoctrineAIPipelineJobRepository implements AIPipelineJobRepositoryIn return $this->em->getRepository(AIPipelineJob::class)->findBy(['status' => $status]); } + public function findByArticleId(Uuid $articleId): ?AIPipelineJob + { + /** @var AIPipelineJob|null */ + return $this->em->getRepository(AIPipelineJob::class)->findOneBy( + ['articleId' => $articleId], + ['createdAt' => 'DESC'], + ); + } + public function save(AIPipelineJob $job): void { $this->em->persist($job);