306cfd34cd
LST-66 (2.3) backend. Behaviour-preserving move of the absences domain into
src/Module/Absence/. API operations, securities, routes and the 10 MCP tool
names are unchanged.
- 3 entities + 3 enums moved to Domain/{Entity,Enum}; user relations stay on
UserInterface. 3 repositories split into Domain/Repository interfaces +
Doctrine impls (bound in services.yaml); find() kept off interfaces
(findById instead).
- Pure services (AbsenceDayCalculator, PublicHolidayProvider) -> Domain/Service;
AbsenceBalanceService -> Application/Service; State (5), controllers (5),
10 MCP tools and AccrueLeaveCommand -> Infrastructure/.
- New LeaveProfileInterface contract (Shared) exposes the HR getters used by
AbsenceBalanceService/AccrueLeaveCommand; User implements it -> Absence no
longer imports the concrete Core User. MCP tools/command inject
UserRepositoryInterface (findById) instead of the concrete repository.
- Timestampable/Blamable added to AbsenceBalance and AbsencePolicy (additive
migration: created_at/updated_at + created_by/updated_by FK ON DELETE SET
NULL + COMMENT). AbsenceRequest untouched (already has createdAt/reviewedAt).
- AbsenceModule registered (id absence, 4 RBAC perms, not re-wired); doctrine
mapping added; team-absences sidebar item gated by the module.
161 tests green, mapping valid, no API route regression, cs-fixer clean.
38 lines
1.1 KiB
PHP
38 lines
1.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Module\Absence\Infrastructure\Mcp\Tool;
|
|
|
|
use App\Mcp\Tool\Serializer;
|
|
use App\Module\Absence\Domain\Repository\AbsenceRequestRepositoryInterface;
|
|
use InvalidArgumentException;
|
|
use Mcp\Capability\Attribute\McpTool;
|
|
use Symfony\Bundle\SecurityBundle\Security;
|
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
|
|
|
use function sprintf;
|
|
|
|
#[McpTool(name: 'get-absence-request', description: 'Get a single absence request by ID.')]
|
|
class GetAbsenceRequestTool
|
|
{
|
|
public function __construct(
|
|
private readonly AbsenceRequestRepositoryInterface $requestRepository,
|
|
private readonly Security $security,
|
|
) {}
|
|
|
|
public function __invoke(int $id): string
|
|
{
|
|
if (!$this->security->isGranted('ROLE_USER')) {
|
|
throw new AccessDeniedException('Access denied: ROLE_USER required.');
|
|
}
|
|
|
|
$request = $this->requestRepository->findById($id);
|
|
if (null === $request) {
|
|
throw new InvalidArgumentException(sprintf('AbsenceRequest with ID %d not found.', $id));
|
|
}
|
|
|
|
return json_encode(Serializer::absenceRequest($request));
|
|
}
|
|
}
|