From ef29c3c47f3a177bf1380b6293611a3633aea5a1 Mon Sep 17 00:00:00 2001 From: Simon Kuehn Date: Mon, 18 May 2026 07:56:00 +0000 Subject: [PATCH] feat: disable Re-run AI when pipeline job is already active Add hasActiveJobForArticle() to check for queued/processing jobs. The displayIf closure hides the action while a job is running. Co-Authored-By: Claude Sonnet 4.6 --- .../AIPipelineJobRepositoryInterface.php | 2 ++ .../Controller/Admin/ArticleCrudController.php | 4 ++-- .../Repository/DoctrineAIPipelineJobRepository.php | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php b/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php index 4071354..f94bf69 100644 --- a/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php +++ b/src/Domain/Pipeline/Repository/AIPipelineJobRepositoryInterface.php @@ -17,6 +17,8 @@ interface AIPipelineJobRepositoryInterface public function findByArticleId(Uuid $articleId): ?AIPipelineJob; + public function hasActiveJobForArticle(Uuid $articleId): bool; + /** @return list */ public function findUpdatedSince(\DateTimeImmutable $since): array; diff --git a/src/Infrastructure/Http/Controller/Admin/ArticleCrudController.php b/src/Infrastructure/Http/Controller/Admin/ArticleCrudController.php index 252a5a3..d7855d7 100644 --- a/src/Infrastructure/Http/Controller/Admin/ArticleCrudController.php +++ b/src/Infrastructure/Http/Controller/Admin/ArticleCrudController.php @@ -77,11 +77,11 @@ final class ArticleCrudController extends AbstractCrudController ->linkToCrudAction('rerunAiPipeline') ->setCssClass('btn btn-sm btn-info') ->askConfirmation(new TranslatableMessage('action.rerun_ai_confirm', [], 'admin')) - ->displayIf(static fn (Article $a) => \in_array( + ->displayIf(fn (Article $a) => \in_array( $a->getStatus(), [ArticleStatus::Draft, ArticleStatus::Ingesting, ArticleStatus::NeedsReview], true, - )); + ) && !$this->jobRepository->hasActiveJobForArticle($a->getId())); return $actions ->add(Crud::PAGE_INDEX, $activate) diff --git a/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php b/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php index 50b4e93..5807a95 100644 --- a/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php +++ b/src/Infrastructure/Persistence/Repository/DoctrineAIPipelineJobRepository.php @@ -37,6 +37,20 @@ final class DoctrineAIPipelineJobRepository implements AIPipelineJobRepositoryIn ); } + public function hasActiveJobForArticle(Uuid $articleId): bool + { + $count = (int) $this->em->createQuery( + 'SELECT COUNT(j.id) FROM App\Domain\Pipeline\AIPipelineJob j + WHERE j.articleId = :articleId + AND j.status IN (:statuses)' + ) + ->setParameter('articleId', $articleId) + ->setParameter('statuses', [AIPipelineJobStatus::Queued, AIPipelineJobStatus::Processing]) + ->getSingleScalarResult(); + + return $count > 0; + } + /** @return list */ public function findUpdatedSince(\DateTimeImmutable $since): array {