storage->getSyncCursor(); $response = $this->client->listEvents($cursor, $this->limit); $events = $response['events'] ?? []; $ackIds = []; $stored = 0; foreach ($events as $event) { $remoteId = (string) ($event['id'] ?? ''); $eventType = (string) ($event['eventType'] ?? 'unknown'); $payload = is_array($event['payload'] ?? null) ? $event['payload'] : []; if ($remoteId === '') { continue; } $this->storage->storeRemoteEvent($remoteId, $eventType, $payload); $stored++; if ($this->shouldAutoAck($eventType)) { $ackIds[] = $remoteId; } } if ($ackIds !== []) { $this->client->acknowledgeEvents($ackIds); } if (!empty($response['nextCursor'])) { $this->storage->updateSyncCursor((string) $response['nextCursor']); } elseif ($events !== []) { $last = $events[count($events) - 1]; if (!empty($last['id'])) { $this->storage->updateSyncCursor((string) $last['id']); } } return [ 'fetched' => count($events), 'stored' => $stored, 'acknowledged' => count($ackIds), 'nextCursor' => $response['nextCursor'] ?? null, ]; } private function shouldAutoAck(string $eventType): bool { return in_array($eventType, ['usage_period_ready', 'usage_period_closed'], true); } }