find($this->tenantId); if (! $tenant instanceof Tenant) { throw new RuntimeException('Tenant not found.'); } $run = $this->resolveRun($tenant); if ($run->status !== EntraGroupSyncRun::STATUS_PENDING) { return; } $run->update([ 'status' => EntraGroupSyncRun::STATUS_RUNNING, 'started_at' => CarbonImmutable::now('UTC'), ]); $auditLogger->log( tenant: $tenant, action: 'directory_groups.sync.started', context: [ 'selection_key' => $run->selection_key, 'run_id' => $run->getKey(), 'slot_key' => $run->slot_key, ], actorId: $run->initiator_user_id, status: 'success', resourceType: 'entra_group_sync_run', resourceId: (string) $run->getKey(), ); $result = $syncService->sync($tenant, $run); $terminalStatus = EntraGroupSyncRun::STATUS_SUCCEEDED; if ($result['error_code'] !== null) { $terminalStatus = EntraGroupSyncRun::STATUS_FAILED; } elseif ($result['safety_stop_triggered'] === true) { $terminalStatus = EntraGroupSyncRun::STATUS_PARTIAL; } $run->update([ 'status' => $terminalStatus, 'pages_fetched' => $result['pages_fetched'], 'items_observed_count' => $result['items_observed_count'], 'items_upserted_count' => $result['items_upserted_count'], 'error_count' => $result['error_count'], 'safety_stop_triggered' => $result['safety_stop_triggered'], 'safety_stop_reason' => $result['safety_stop_reason'], 'error_code' => $result['error_code'], 'error_category' => $result['error_category'], 'error_summary' => $result['error_summary'], 'finished_at' => CarbonImmutable::now('UTC'), ]); $auditLogger->log( tenant: $tenant, action: $terminalStatus === EntraGroupSyncRun::STATUS_SUCCEEDED ? 'directory_groups.sync.succeeded' : ($terminalStatus === EntraGroupSyncRun::STATUS_PARTIAL ? 'directory_groups.sync.partial' : 'directory_groups.sync.failed'), context: [ 'selection_key' => $run->selection_key, 'run_id' => $run->getKey(), 'slot_key' => $run->slot_key, 'pages_fetched' => $run->pages_fetched, 'items_observed_count' => $run->items_observed_count, 'items_upserted_count' => $run->items_upserted_count, 'error_code' => $run->error_code, 'error_category' => $run->error_category, ], actorId: $run->initiator_user_id, status: $terminalStatus === EntraGroupSyncRun::STATUS_FAILED ? 'failed' : 'success', resourceType: 'entra_group_sync_run', resourceId: (string) $run->getKey(), ); } private function resolveRun(Tenant $tenant): EntraGroupSyncRun { if ($this->runId !== null) { $run = EntraGroupSyncRun::query() ->whereKey($this->runId) ->where('tenant_id', $tenant->getKey()) ->first(); if ($run instanceof EntraGroupSyncRun) { return $run; } throw new RuntimeException('EntraGroupSyncRun not found.'); } if ($this->slotKey !== null) { $run = EntraGroupSyncRun::query() ->where('tenant_id', $tenant->getKey()) ->where('selection_key', $this->selectionKey) ->where('slot_key', $this->slotKey) ->first(); if ($run instanceof EntraGroupSyncRun) { return $run; } throw new RuntimeException('EntraGroupSyncRun not found for slot.'); } throw new RuntimeException('Job missing runId/slotKey.'); } }