Add audit trail dump generation and status retrieval endpoints

- Added `generateDump` method to handle audit trail dump creation and queue a processing request.
- Introduced `waitForDump` endpoint to retrieve the status of a pending dump.
- Updated controller dependencies to include `MessageBusInterface`, `EntityManagerInterface`, `ClockInterface`, and `UrlGeneratorInterface`.
- Marked `AuditTrailSearchController` as `readonly` for improved immutability.
This commit is contained in:
2026-02-23 11:44:17 +01:00
parent 7324d8dfc7
commit 07417387bb

View File

@@ -11,19 +11,27 @@ declare(strict_types=1);
namespace Chill\MainBundle\Controller;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\MainBundle\Audit\Messenger\AuditDumpRequestMessage;
use Chill\MainBundle\Audit\Subject;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
use Chill\MainBundle\Repository\AuditTrailRepository;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatableMessage;
use Twig\Environment;
final class AuditTrailSearchController
final readonly class AuditTrailSearchController
{
public function __construct(
private Security $security,
@@ -31,10 +39,14 @@ final class AuditTrailSearchController
private FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
private Environment $twig,
private PaginatorFactoryInterface $paginatorFactory,
private MessageBusInterface $messenger,
private EntityManagerInterface $entityManager,
private ClockInterface $clock,
private UrlGeneratorInterface $urlGenerator,
) {}
#[Route('/{_locale}/main/audit-trail/list', name: 'chill_main_audit_trail_list')]
public function list(Request $request): Response
public function list(): Response
{
$filter = $this->buildFilter();
$criteria = $this->buildFilterCriteria($filter);
@@ -51,6 +63,41 @@ final class AuditTrailSearchController
]));
}
#[Route('/{_locale}/main/audit-trail/generate', name: 'chill_main_audit_trail_generate')]
public function generateDump(Request $request): Response
{
$filter = $this->buildFilter();
$criteria = $this->buildFilterCriteria($filter);
$storedObject = new StoredObject(StoredObject::STATUS_PENDING);
$storedObject->setDeleteAt($this->clock->now()->add(new \DateInterval('PT24H')));
$this->entityManager->persist($storedObject);
$message = new AuditDumpRequestMessage(
$request->getLocale(),
$storedObject->getId(),
$criteria['from_date'] ?? null,
$criteria['to_date'] ?? null,
array_map(fn (Subject $subject) => $subject->asArray(), $criteria['subjects'] ?? []),
array_map(fn (User $user): int => $user->getId(), $criteria['by_users'] ?? []),
);
$this->entityManager->flush();
$this->messenger->dispatch($message);
return new RedirectResponse(
$this->urlGenerator->generate('chill_main_audit_trail_wait', ['uuid' => $storedObject->getUuid()])
);
}
#[Route('/{_locale°/main/audit-trail/wait/{uuid}', name: 'chill_main_audit_trail_wait')]
public function waitForDump(StoredObject $storedObject): Response
{
return new Response($storedObject->getStatus());
}
private function buildFilter(): FilterOrderHelper
{
$filter = $this->filterOrderHelperFactory->create(self::class);