* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXM\PeopleManager\Controllers; use InvalidArgumentException; use KTXC\Http\Response\JsonResponse; use KTXC\SessionIdentity; use KTXC\SessionTenant; use KTXF\Controller\ControllerAbstract; use KTXF\People\Collection\ICollectionBase; use KTXF\Resource\Selector\SourceSelector; use KTXF\Routing\Attributes\AuthenticatedRoute; use KTXM\PeopleManager\Manager; class DefaultController extends ControllerAbstract { public function __construct( private readonly SessionTenant $tenantIdentity, private readonly SessionIdentity $userIdentity, private Manager $peopleManager, ) {} /** * Retrieve list of available providers * * @return JsonResponse */ #[AuthenticatedRoute('/v1', name: 'peoplemanager.v1', methods: ['POST'])] public function index(int $version, string $transaction, string $operation, array $data = [], string|null $user = null): JsonResponse { // authorize request $tenantId = $this->tenantIdentity->identifier(); $userId = $this->userIdentity->identifier(); try { $data = $this->process($tenantId, $userId, $operation, $data); return new JsonResponse([ 'version' => $version, 'transaction' => $transaction, 'operation' => $operation, 'status' => 'success', 'data' => $data, ], JsonResponse::HTTP_OK); } catch (\Throwable $t) { return new JsonResponse([ 'version' => $version, 'transaction' => $transaction, 'operation' => $operation, 'status' => 'error', 'data' => [ 'code' => $t->getCode(), 'message' => $t->getMessage(), ] ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR); } } private function process(string $tenantId, string $userId, string $operation, array $data): mixed { return match ($operation) { 'provider.list' => $this->providerList($tenantId, $userId, $data), 'provider.extant' => $this->providerExtant($tenantId, $userId, $data), 'service.list' => $this->serviceList($tenantId, $userId, $data), 'service.extant' => $this->serviceExtant($tenantId, $userId, $data), 'service.fetch' => $this->serviceFetch($tenantId, $userId, $data), 'collection.list' => $this->collectionList($tenantId, $userId, $data), 'collection.extant' => $this->collectionExtant($tenantId, $userId, $data), 'collection.fetch' => $this->collectionFetch($tenantId, $userId, $data), 'collection.create' => $this->collectionCreate($tenantId, $userId, $data), 'collection.modify' => $this->collectionModify($tenantId, $userId, $data), 'collection.destroy' => $this->collectionDestroy($tenantId, $userId, $data), 'entity.list' => $this->entityList($tenantId, $userId, $data), 'entity.delta' => $this->entityDelta($tenantId, $userId, $data), 'entity.extant' => $this->entityExtant($tenantId, $userId, $data), 'entity.fetch' => $this->entityFetch($tenantId, $userId, $data), 'entity.create' => $this->entityCreate($tenantId, $userId, $data), 'entity.modify' => $this->entityModify($tenantId, $userId, $data), 'entity.destroy' => $this->entityDestroy($tenantId, $userId, $data), default => throw new InvalidArgumentException("Invalid operation: $operation"), }; } // ==================== Provider Operations ==================== private function providerList(string $tenantId, string $userId, array $data): mixed { $sources = null; if (isset($data['sources']) && is_array($data['sources'])) { $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); } return $this->peopleManager->providerList($tenantId, $userId, $sources); } private function providerExtant(string $tenantId, string $userId, array $data): mixed { if (!isset($data['sources']) || !is_array($data['sources'])) { throw new InvalidArgumentException('Invalid sources selector provided'); } $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); return $this->peopleManager->providerExtant($tenantId, $userId, $sources); } // ==================== Service Operations ===================== private function serviceList(string $tenantId, string $userId, array $data): mixed { $sources = null; if (isset($data['sources']) && is_array($data['sources'])) { $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); } return $this->peopleManager->serviceList($tenantId, $userId, $sources); } private function serviceExtant(string $tenantId, string $userId, array $data): mixed { if (!isset($data['sources']) || !is_array($data['sources'])) { throw new InvalidArgumentException('Invalid sources selector provided'); } $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); return $this->peopleManager->serviceExtant($tenantId, $userId, $sources); } private function serviceFetch(string $tenantId, string $userId, array $data): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['identifier']) || !is_string($data['identifier'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } return $this->peopleManager->serviceFetch($tenantId, $userId, $data['provider'], $data['identifier']); } private function collectionList(string $tenantId, string $userId, array $data): mixed { $sources = null; if (isset($data['sources']) && is_array($data['sources'])) { $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); } $filter = $data['filter'] ?? null; $sort = $data['sort'] ?? null; // retrieve collections return $this->peopleManager->collectionList($tenantId, $userId, $sources, $filter, $sort); } private function collectionExtant(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['sources']) || !is_array($data['sources'])) { throw new InvalidArgumentException('Invalid sources selector provided'); } $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); // retrieve collection status return $this->peopleManager->collectionExtant($tenantId, $userId, $sources); } private function collectionFetch(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['identifier'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } // retrieve collection return $this->peopleManager->collectionFetch($tenantId, $userId, $data['provider'], $data['service'], $data['identifier']); } private function collectionCreate(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['data'])) { throw new InvalidArgumentException('Invalid collection data provided'); } $options = $data['options'] ?? []; // create collection return $this->peopleManager->collectionCreate($tenantId, $userId, $data['provider'], $data['service'], $data['data'], $options); } private function collectionModify(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['identifier'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } if (!isset($data['data'])) { throw new InvalidArgumentException('Invalid collection data provided'); } // modify collection return $this->peopleManager->collectionModify($tenantId, $userId, $data['provider'], $data['service'], $data['identifier'], $data['data']); } private function collectionDestroy(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['identifier'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } // destroy collection return ['success' => $this->peopleManager->collectionDestroy($tenantId, $userId, $data['provider'], $data['service'], $data['identifier'])]; } private function entityList(string $tenantId, string $userId, array $data = []): mixed { $sources = null; if (isset($data['sources']) && is_array($data['sources'])) { $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); } $filter = $data['filter'] ?? null; $sort = $data['sort'] ?? null; $range = $data['range'] ?? null; // retrieve entities return $this->peopleManager->entityList($tenantId, $userId, $sources, $filter, $sort, $range); } private function entityDelta(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['sources']) || !is_array($data['sources'])) { throw new InvalidArgumentException('Invalid sources selector provided'); } $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); // retrieve entity delta return $this->peopleManager->entityDelta($tenantId, $userId, $sources); } private function entityExtant(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['sources']) || !is_array($data['sources'])) { throw new InvalidArgumentException('Invalid sources selector provided'); } $sources = new SourceSelector(); $sources->jsonDeserialize($data['sources']); // retrieve entity status return $this->peopleManager->entityExtant($tenantId, $userId, $sources); } private function entityFetch(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['collection'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } if (!isset($data['identifiers']) || !is_array($data['identifiers'])) { throw new InvalidArgumentException('Invalid entity identifiers provided'); } // retrieve entities return $this->peopleManager->entityFetch($tenantId, $userId, $data['provider'], $data['service'], $data['collection'], $data['identifiers']); } private function entityCreate(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['collection'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } if (!isset($data['data']) || !is_array($data['data'])) { throw new InvalidArgumentException('Invalid entity data provided'); } $options = $data['options'] ?? []; // create entity return $this->peopleManager->entityCreate($tenantId, $userId, $data['provider'], $data['service'], $data['collection'], $data['data'], $options); } private function entityModify(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['collection'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } if (!isset($data['identifier'])) { throw new InvalidArgumentException('Invalid entity identifier provided'); } if (!isset($data['data']) || !is_array($data['data'])) { throw new InvalidArgumentException('Invalid entity data provided'); } // modify entity return $this->peopleManager->entityModify($tenantId, $userId, $data['provider'], $data['service'], $data['collection'], $data['identifier'], $data['data']); } private function entityDestroy(string $tenantId, string $userId, array $data = []): mixed { if (!isset($data['provider']) || !is_string($data['provider'])) { throw new InvalidArgumentException('Invalid provider identifier provided'); } if (!isset($data['service']) || !is_string($data['service'])) { throw new InvalidArgumentException('Invalid service identifier provided'); } if (!isset($data['collection'])) { throw new InvalidArgumentException('Invalid collection identifier provided'); } if (!isset($data['identifier'])) { throw new InvalidArgumentException('Invalid entity identifier provided'); } // destroy entity return ['success' => $this->peopleManager->entityDestroy($tenantId, $userId, $data['provider'], $data['service'], $data['collection'], $data['identifier'])]; } }