get(self::API_URL, [ 'outFields' => 'town_pid,town_name,state,population,town_class,date_retired', 'where' => '1=1', 'f' => 'json', 'resultOffset' => $offset, 'resultRecordCount' => self::PAGE_SIZE, 'orderByFields' => 'objectid ASC', ]); if ($response->failed()) { Log::error('SyncTowns: API request failed', ['offset' => $offset, 'status' => $response->status()]); break; } $features = $response->json('features', []); if (empty($features)) { break; } $records = collect($features)->map(fn (array $feature) => [ 'town_pid' => $feature['attributes']['town_pid'], 'town_name' => $feature['attributes']['town_name'], 'state' => $feature['attributes']['state'], 'population' => $feature['attributes']['population'], 'town_class' => $feature['attributes']['town_class'], 'date_retired' => isset($feature['attributes']['date_retired']) ? Carbon::createFromTimestampMs($feature['attributes']['date_retired']) : null, 'updated_at' => now(), 'created_at' => now(), ])->toArray(); Town::upsert($records, uniqueBy: ['town_pid'], update: [ 'town_name', 'state', 'population', 'town_class', 'date_retired', 'updated_at', ]); $synced += count($features); $offset += self::PAGE_SIZE; } while (count($features) === self::PAGE_SIZE); Log::info("SyncTowns: synced {$synced} towns."); } }