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 <noreply@anthropic.com>
This commit is contained in:
Simon Kuehn 2026-05-18 07:56:00 +00:00
parent 3928d29420
commit ef29c3c47f
3 changed files with 18 additions and 2 deletions

View file

@ -17,6 +17,8 @@ interface AIPipelineJobRepositoryInterface
public function findByArticleId(Uuid $articleId): ?AIPipelineJob; public function findByArticleId(Uuid $articleId): ?AIPipelineJob;
public function hasActiveJobForArticle(Uuid $articleId): bool;
/** @return list<AIPipelineJob> */ /** @return list<AIPipelineJob> */
public function findUpdatedSince(\DateTimeImmutable $since): array; public function findUpdatedSince(\DateTimeImmutable $since): array;

View file

@ -77,11 +77,11 @@ final class ArticleCrudController extends AbstractCrudController
->linkToCrudAction('rerunAiPipeline') ->linkToCrudAction('rerunAiPipeline')
->setCssClass('btn btn-sm btn-info') ->setCssClass('btn btn-sm btn-info')
->askConfirmation(new TranslatableMessage('action.rerun_ai_confirm', [], 'admin')) ->askConfirmation(new TranslatableMessage('action.rerun_ai_confirm', [], 'admin'))
->displayIf(static fn (Article $a) => \in_array( ->displayIf(fn (Article $a) => \in_array(
$a->getStatus(), $a->getStatus(),
[ArticleStatus::Draft, ArticleStatus::Ingesting, ArticleStatus::NeedsReview], [ArticleStatus::Draft, ArticleStatus::Ingesting, ArticleStatus::NeedsReview],
true, true,
)); ) && !$this->jobRepository->hasActiveJobForArticle($a->getId()));
return $actions return $actions
->add(Crud::PAGE_INDEX, $activate) ->add(Crud::PAGE_INDEX, $activate)

View file

@ -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<AIPipelineJob> */ /** @return list<AIPipelineJob> */
public function findUpdatedSince(\DateTimeImmutable $since): array public function findUpdatedSince(\DateTimeImmutable $since): array
{ {