Hello could you translate this php symfony code into spring boot + kotlin code (using springdoc/swagger for the annotations)? Also don't take into account the command bus during the translation and use the commandhandler directly.  

<?php

declare(strict_types=1);

namespace App\Presentation\Rest\Action\TrackingMethod;

use App\Domain\Application\Command\CommandBus;
use App\Domain\Application\Command\TrackingConfiguration\CreateTrackingConfigurationCommand;
use App\Domain\Application\Query\TrackingConfiguration\GetTrackingConfigurationQuery;
use App\Domain\Application\Query\TrackingConfiguration\GetTrackingConfigurationQueryHandler;
use App\Domain\Model\Exception\DomainExceptionInterface;
use App\Domain\Model\Exception\InfraExceptionInterface;
use App\Domain\Model\TrackingMethod\Exception\TrackingConfigurationAlreadyExistsException;
use App\Presentation\Rest\Action\TrackingMethod\DTO\TrackingConfigurationDTO;
use App\Presentation\Rest\Exception\RestException;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\SerializerInterface;

class CreateTrackingConfigurationAction
{
    public function __construct(
        private readonly CommandBus $commandBus,
        private readonly GetTrackingConfigurationQueryHandler $queryHandler,
        private readonly SerializerInterface $serializer
    ) {
    }

    #[OA\Post(
        path: '/api/tracking-configurations',
        operationId: 'CreateTrackingConfiguration',
        description: 'JWT Allowed:
BO Product Delivery: ROLE_BO_PRODUCT_DELIVERY_SUPER_ADMIN',
        summary: 'Create a new tracking configuration',
        security: [
            ['ManomanoBearer' => []],
        ],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(ref: '#/components/schemas/CreateTrackingConfigurationCommand')
        ),
        tags: ['Tracking Configurations'],
    )]
    #[OA\Response(
        response: 201,
        description: 'A TrackingConfiguration instance has been created',
        content: new OA\JsonContent(
            properties: [
                new OA\Property(property: 'content', ref: '#/components/schemas/TrackingConfigurationDTO', type: 'object'),
            ],
        )
    )]
    #[OA\Response(response: 400, description: 'Bad request, adjust before retrying')]
    #[OA\Response(ref: '#/components/responses/401', response: 401)]
    #[OA\Response(ref: '#/components/responses/403', response: 403)]
    #[OA\Response(
        response: 409,
        description: 'Conflict',
        content: new OA\JsonContent(
            examples: [
                'TRACKING_CONFIGURATION_ALREADY_EXISTS' => new OA\Examples(example: 'TRACKING_CONFIGURATION_ALREADY_EXISTS', summary: 'The tracking configuration already exists'),
            ]
        )
    )]
    #[OA\Response(response: 500, description: 'Internal server error')]
    #[IsGranted('ROLE_BO_PRODUCT_DELIVERY_SUPER_ADMIN')]
    /**
     * @throws RestException
     */
    public function __invoke(Request $request): JsonResponse
    {
        try {
            /** @var CreateTrackingConfigurationCommand $command */
            $command = $this->serializer->deserialize(
                $request->getContent(),
                CreateTrackingConfigurationCommand::class,
                JsonEncoder::FORMAT
            );
        } catch (ExceptionInterface $exception) {
            throw RestException::fromThrowable($exception, Response::HTTP_BAD_REQUEST);
        }

        try {
            $this->commandBus->dispatch($command);

            $createdTrackingConfiguration = $this->queryHandler->__invoke(
                new GetTrackingConfigurationQuery($command->getCreatedTrackingConfigurationId())
            );
        } catch (TrackingConfigurationAlreadyExistsException $e) {
            throw RestException::fromDomainException($e, Response::HTTP_CONFLICT);
        } catch (DomainExceptionInterface $e) {
            throw RestException::fromDomainException($e, Response::HTTP_BAD_REQUEST);
        } catch (InfraExceptionInterface $e) {
            throw RestException::fromInfraException($e);
        }

        return JsonResponse::fromJsonString(
            $this->serializer->serialize(
                TrackingConfigurationDTO::fromTrackingConfiguration($createdTrackingConfiguration),
                JsonEncoder::FORMAT
            ),
            Response::HTTP_CREATED
        );
    }
}
<?php

declare(strict_types=1);

namespace App\Domain\Application\Command\TrackingConfiguration;

use App\Domain\Application\Command\Command;
use App\Domain\Model\Assert;
use OpenApi\Attributes as OA;

#[OA\Schema]
class CreateTrackingConfigurationCommand implements Command
{
    private ?int $createdTrackingConfigurationId = null;

    public function __construct(
        #[OA\Property(example: 1)]
        private readonly int $deliveryOfferId,
        #[OA\Property(example: 1)]
        private readonly int $defaultGenericTrackingMethodId,
        #[OA\Property(example: 'dpd', nullable: true)]
        private readonly ?string $urlGeneratorSlug = null,
    ) {
        Assert::positiveInteger($deliveryOfferId);
        Assert::positiveInteger($defaultGenericTrackingMethodId);
    }

    public function getDeliveryOfferId(): int
    {
        return $this->deliveryOfferId;
    }

    public function getDefaultGenericTrackingMethodId(): int
    {
        return $this->defaultGenericTrackingMethodId;
    }

    public function getUrlGeneratorSlug(): ?string
    {
        return $this->urlGeneratorSlug;
    }

    /**
     * @throws \LogicException when called before the handler set the value
     */
    public function getCreatedTrackingConfigurationId(): int
    {
        if (null === $this->createdTrackingConfigurationId) {
            throw new \LogicException(sprintf('%s::getCreatedTrackingConfigurationId() called before the handler set the value', self::class));
        }

        return $this->createdTrackingConfigurationId;
    }

    public function setCreatedTrackingConfigurationId(int $id): void
    {
        $this->createdTrackingConfigurationId = $id;
    }
}

<?php

declare(strict_types=1);

namespace App\Domain\Application\Command\TrackingConfiguration;

use App\Domain\Model\DeliveryOffer\DeliveryOfferProvider;
use App\Domain\Model\Exception\DeliveryOffer\DeliveryOfferNotFoundException;
use App\Domain\Model\Exception\InfraExceptionInterface;
use App\Domain\Model\Tracking\Exception\TrackingMethodNotFoundException;
use App\Domain\Model\TrackingMethod\Exception\TrackingConfigurationAlreadyExistsException;
use App\Domain\Model\TrackingMethod\GenericTrackingMethodRepository;
use App\Domain\Model\TrackingMethod\TrackingConfiguration;
use App\Domain\Model\TrackingMethod\TrackingConfigurationRepository;
use App\Domain\Model\TrackingUrl\InvalidUrlGeneratorSlugException;
use App\Domain\Model\TrackingUrl\UrlGeneratorStrategies;
use Webmozart\Assert\Assert;

class CreateTrackingConfigurationCommandHandler
{
    public function __construct(
        private readonly GenericTrackingMethodRepository $genericTrackingMethodRepository,
        private readonly TrackingConfigurationRepository $trackingConfigurationRepository,
        private readonly DeliveryOfferProvider $deliveryOfferProvider,
        private readonly UrlGeneratorStrategies $strategies,
    ) {
    }

    /**
     * @throws DeliveryOfferNotFoundException
     * @throws InvalidUrlGeneratorSlugException
     * @throws TrackingMethodNotFoundException
     * @throws TrackingConfigurationAlreadyExistsException
     * @throws InfraExceptionInterface
     */
    public function __invoke(CreateTrackingConfigurationCommand $command): void
    {
        if (null !== $this->trackingConfigurationRepository->getForDeliveryOffer($command->getDeliveryOfferId())) {
            throw TrackingConfigurationAlreadyExistsException::forDeliveryOfferId($command->getDeliveryOfferId());
        }

        $defaultTrackingMethod = $this->genericTrackingMethodRepository->findById(
            $command->getDefaultGenericTrackingMethodId()
        );

        $deliveryOffer = $this->deliveryOfferProvider->getById($command->getDeliveryOfferId());
        if (null !== $command->getUrlGeneratorSlug() && null === $this->strategies->getBySlug($command->getUrlGeneratorSlug())) {
            throw InvalidUrlGeneratorSlugException::forSlug($command->getUrlGeneratorSlug());
        }

        $trackingConfiguration = new TrackingConfiguration($deliveryOffer->id, $defaultTrackingMethod, $command->getUrlGeneratorSlug());
        $this->trackingConfigurationRepository->add($trackingConfiguration);

        Assert::notNull($trackingConfiguration->getId());
        $command->setCreatedTrackingConfigurationId($trackingConfiguration->getId());
    }
}