115 lines
4.1 KiB
PHP
115 lines
4.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace App\Infrastructure\Http\Controller\Admin;
|
||
|
|
|
||
|
|
use App\Domain\Pipeline\AIPipelineJob;
|
||
|
|
use App\Domain\Pipeline\AIPipelineJobStatus;
|
||
|
|
use Doctrine\ORM\QueryBuilder;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||
|
|
use EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository;
|
||
|
|
|
||
|
|
/** @extends AbstractCrudController<AIPipelineJob> */
|
||
|
|
final class PipelineArchiveCrudController extends AbstractCrudController
|
||
|
|
{
|
||
|
|
public static function getEntityFqcn(): string
|
||
|
|
{
|
||
|
|
return AIPipelineJob::class;
|
||
|
|
}
|
||
|
|
|
||
|
|
public function configureCrud(Crud $crud): Crud
|
||
|
|
{
|
||
|
|
return $crud
|
||
|
|
->setEntityLabelInSingular('Pipeline Job')
|
||
|
|
->setEntityLabelInPlural('AI Pipeline — Archive')
|
||
|
|
->setDefaultSort(['completedAt' => 'DESC'])
|
||
|
|
->showEntityActionsInlined();
|
||
|
|
}
|
||
|
|
|
||
|
|
public function configureActions(Actions $actions): Actions
|
||
|
|
{
|
||
|
|
return $actions
|
||
|
|
->add(Crud::PAGE_INDEX, Action::DETAIL)
|
||
|
|
->disable(Action::NEW, Action::EDIT, Action::DELETE);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function configureFields(string $pageName): iterable
|
||
|
|
{
|
||
|
|
yield IdField::new('id')->hideOnIndex();
|
||
|
|
yield TextField::new('inventoryNumber', 'Inventory #')
|
||
|
|
->hideOnForm()
|
||
|
|
->formatValue(static fn ($v, AIPipelineJob $job): string => (string) ($job->getInputData()['inventoryNumber'] ?? '—'));
|
||
|
|
yield TextField::new('statusLabel', 'Status')
|
||
|
|
->hideOnForm();
|
||
|
|
yield IntegerField::new('attemptCount', 'Attempts')->hideOnForm();
|
||
|
|
yield DateTimeField::new('createdAt', 'Started')->hideOnForm();
|
||
|
|
yield DateTimeField::new('completedAt', 'Completed')->hideOnForm();
|
||
|
|
yield TextField::new('articleId', 'Article')
|
||
|
|
->hideOnForm()
|
||
|
|
->formatValue(static fn ($v, AIPipelineJob $job): string => $job->getArticleId()?->toRfc4122() ?? '—');
|
||
|
|
yield TextareaField::new('aiResults', 'AI Results')
|
||
|
|
->onlyOnDetail()
|
||
|
|
->formatValue(static fn ($v, AIPipelineJob $job): string => self::formatStepResults($job));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function createIndexQueryBuilder(
|
||
|
|
SearchDto $searchDto,
|
||
|
|
EntityDto $entityDto,
|
||
|
|
FieldCollection $fields,
|
||
|
|
FilterCollection $filters,
|
||
|
|
): QueryBuilder {
|
||
|
|
$qb = $this->container->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
|
||
|
|
$qb->andWhere('entity.status = :completed')
|
||
|
|
->setParameter('completed', AIPipelineJobStatus::Completed);
|
||
|
|
|
||
|
|
return $qb;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static function formatStepResults(AIPipelineJob $job): string
|
||
|
|
{
|
||
|
|
$output = $job->getOutputData();
|
||
|
|
if ([] === $output) {
|
||
|
|
return '(none)';
|
||
|
|
}
|
||
|
|
|
||
|
|
$lines = [];
|
||
|
|
$labels = [
|
||
|
|
'vision' => 'Vision',
|
||
|
|
'specs_research' => 'Specs Research',
|
||
|
|
'json_coding' => 'JSON Coding',
|
||
|
|
'validation' => 'Validation',
|
||
|
|
];
|
||
|
|
|
||
|
|
foreach ($labels as $key => $label) {
|
||
|
|
if (!isset($output[$key])) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
$data = $output[$key];
|
||
|
|
$lines[] = "=== {$label} ===";
|
||
|
|
foreach ($data as $k => $v) {
|
||
|
|
if (\is_array($v)) {
|
||
|
|
$lines[] = "{$k}: ".json_encode($v, \JSON_UNESCAPED_UNICODE | \JSON_PRETTY_PRINT);
|
||
|
|
} else {
|
||
|
|
$lines[] = "{$k}: {$v}";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$lines[] = '';
|
||
|
|
}
|
||
|
|
|
||
|
|
return implode("\n", $lines);
|
||
|
|
}
|
||
|
|
}
|