['id' => ..., 'displayName' => ..., 'orphaned' => bool]] */ public function resolveGroupIds(array $groupIds, string $tenantId, array $options = []): array { if (empty($groupIds)) { return []; } // Create cache key $cacheKey = $this->getCacheKey($groupIds, $tenantId); return Cache::remember($cacheKey, 300, function () use ($groupIds, $tenantId, $options) { return $this->fetchAndResolveGroups($groupIds, $tenantId, $options); }); } /** * Fetch groups from Graph API and resolve orphaned IDs. */ private function fetchAndResolveGroups(array $groupIds, string $tenantId, array $options = []): array { try { $response = $this->graphClient->request( 'POST', '/directoryObjects/getByIds', array_merge($options, [ 'tenant' => $tenantId, 'json' => [ 'ids' => array_values($groupIds), 'types' => ['group'], ], ]) ); $resolvedGroups = $response->data['value'] ?? []; // Create result map $result = []; $resolvedIds = []; // Add resolved groups foreach ($resolvedGroups as $group) { $groupId = $group['id']; $resolvedIds[] = $groupId; $result[$groupId] = [ 'id' => $groupId, 'displayName' => $group['displayName'] ?? null, 'orphaned' => false, ]; } // Add orphaned groups (not in response) foreach ($groupIds as $groupId) { if (! in_array($groupId, $resolvedIds)) { $result[$groupId] = [ 'id' => $groupId, 'displayName' => null, 'orphaned' => true, ]; } } Log::debug('Resolved group IDs', [ 'tenant_id' => $tenantId, 'requested' => count($groupIds), 'resolved' => count($resolvedIds), 'orphaned' => count($groupIds) - count($resolvedIds), ]); return $result; } catch (GraphException $e) { Log::warning('Failed to resolve group IDs', [ 'tenant_id' => $tenantId, 'group_ids' => $groupIds, 'error' => $e->getMessage(), 'context' => $e->context, ]); // Return all as orphaned on failure $result = []; foreach ($groupIds as $groupId) { $result[$groupId] = [ 'id' => $groupId, 'displayName' => null, 'orphaned' => true, ]; } return $result; } } /** * Generate cache key for group resolution. */ private function getCacheKey(array $groupIds, string $tenantId): string { sort($groupIds); return "groups:{$tenantId}:".md5(implode(',', $groupIds)); } }