$payload */ public function ingest(WooStore $store, array $payload): WooCategory { $externalId = (int) ($payload['id'] ?? 0); if ($externalId === 0) { throw new \InvalidArgumentException('WooCommerce category id missing.'); } $parent = (int) ($payload['parent'] ?? 0); return WooCategory::query()->updateOrCreate( [ 'woo_store_id' => $store->id, 'external_id' => $externalId, ], [ 'parent_external_id' => $parent > 0 ? $parent : null, 'name' => (string) ($payload['name'] ?? 'Category'), 'slug' => (string) ($payload['slug'] ?? 'category-'.$externalId), 'description' => WooHtml::sanitize($payload['description'] ?? null), 'product_count' => max(0, (int) ($payload['count'] ?? 0)), 'wc_updated_at' => $this->updatedAt($payload), 'metadata' => [ 'image' => $payload['image'] ?? null, ], ], ); } public function delete(WooStore $store, int $externalId): void { WooCategory::query() ->where('woo_store_id', $store->id) ->where('external_id', $externalId) ->delete(); } /** @param array $payload */ private function updatedAt(array $payload): ?Carbon { $raw = $payload['date_modified_gmt'] ?? $payload['date_modified'] ?? null; return is_string($raw) && $raw !== '' ? Carbon::parse($raw) : null; } private function nullableString(mixed $value): ?string { $text = trim((string) $value); return $text === '' ? null : $text; } }