feat: add admin provider setup UI with improved product sync
- Add /admin/providers LiveView for connecting and managing POD providers - Implement pagination for Printify API (handles all products, not just first page) - Add parallel processing (5 concurrent) for faster product sync - Add slug-based fallback matching when provider_product_id changes - Add error recovery with try/rescue to prevent stuck sync status - Add checksum-based change detection to skip unchanged products - Add upsert tests covering race conditions and slug matching - Add Printify provider tests - Document Printify integration research (product identity, order risks, open source vs managed hosting implications) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,11 +41,7 @@ defmodule SimpleshopTheme.Providers.Printify do
|
||||
else
|
||||
with api_key when is_binary(api_key) <- ProviderConnection.get_api_key(conn),
|
||||
:ok <- set_api_key(api_key),
|
||||
{:ok, response} <- Client.list_products(shop_id) do
|
||||
products =
|
||||
response["data"]
|
||||
|> Enum.map(&normalize_product/1)
|
||||
|
||||
{:ok, products} <- fetch_all_products(shop_id) do
|
||||
{:ok, products}
|
||||
else
|
||||
nil -> {:error, :no_api_key}
|
||||
@@ -54,6 +50,33 @@ defmodule SimpleshopTheme.Providers.Printify do
|
||||
end
|
||||
end
|
||||
|
||||
# Fetches all products by paginating through the API
|
||||
defp fetch_all_products(shop_id) do
|
||||
fetch_products_page(shop_id, 1, [])
|
||||
end
|
||||
|
||||
defp fetch_products_page(shop_id, page, acc) do
|
||||
case Client.list_products(shop_id, page: page) do
|
||||
{:ok, response} ->
|
||||
products = Enum.map(response["data"] || [], &normalize_product/1)
|
||||
all_products = acc ++ products
|
||||
|
||||
current_page = response["current_page"] || page
|
||||
last_page = response["last_page"] || 1
|
||||
|
||||
if current_page < last_page do
|
||||
# Small delay to be nice to rate limits (600/min = 10/sec)
|
||||
Process.sleep(100)
|
||||
fetch_products_page(shop_id, page + 1, all_products)
|
||||
else
|
||||
{:ok, all_products}
|
||||
end
|
||||
|
||||
{:error, _} = error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def submit_order(%ProviderConnection{config: config} = conn, order) do
|
||||
shop_id = config["shop_id"]
|
||||
|
||||
Reference in New Issue
Block a user