feat(heures) : export PDF jour accessible aux chefs de site (périmètre par site)
Auto Tag Develop / tag (push) Successful in 10s

L'export des heures de la vue Jour était réservé aux admins. Il est désormais
ouvert aux chefs de site, restreint à leurs sites :
- sécurité endpoint ROLE_ADMIN -> ROLE_USER
- périmètre résolu côté backend via EmployeeRepository::findScoped() (un siteIds
  hors périmètre est ignoré, aucune fuite inter-sites)
- bouton Exporter visible pour admin + chef de site (masqué pour ROLE_SELF)
- doc, doc in-app et CLAUDE.md mis à jour

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 08:31:30 +02:00
parent 2802f9524c
commit 143278a368
6 changed files with 32 additions and 13 deletions
+12 -2
View File
@@ -6,13 +6,16 @@ namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Entity\User;
use App\Repository\EmployeeRepository;
use App\Service\WorkHours\YearlyHoursExportBuilder;
use DateTimeImmutable;
use Dompdf\Dompdf;
use Dompdf\Options;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Twig\Environment;
@@ -23,10 +26,16 @@ class WorkHourDayExportProvider implements ProviderInterface
private readonly RequestStack $requestStack,
private EmployeeRepository $employeeRepository,
private YearlyHoursExportBuilder $exportBuilder,
private readonly Security $security,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
{
$user = $this->security->getUser();
if (!$user instanceof User) {
throw new AccessDeniedHttpException('Authentication required.');
}
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return new Response('Missing request.', Response::HTTP_BAD_REQUEST);
@@ -47,8 +56,9 @@ class WorkHourDayExportProvider implements ProviderInterface
throw new UnprocessableEntityHttpException('siteIds is required.');
}
// Feature réservée admin : on charge tous les employés puis on filtre.
$employees = $this->employeeRepository->findAll();
// Périmètre selon le profil : admin → tous, chef de site → ses sites uniquement.
// Les siteIds demandés ne peuvent donc pas déborder du scope de l'utilisateur.
$employees = $this->employeeRepository->findScoped($user);
// Regroupement par site (ordre displayOrder), non-conducteurs uniquement.
$bySite = [];