- Shipped
- November 8, 2026 at 8:56 AM UTC
- Author
- Kamo
- Commit
- 05bd1ad
Until now a sync read the store, counted the records and threw them away, and every run said it worked. - StoreReader per platform (Shopify, WooCommerce, BigCommerce, Magento, Wix, Squarespace, Ecwid, Shift4Shop, PrestaShop, OpenCart): read-only, paged, carrying the store's own ids; statuses mapped to Kamo order statuses. Tested against recorded answers in each platform's documented shape (no live store is connected). - StoreSyncWriter: one Kamo product per sellable item (variants included), matched by market + platform + store id **************** unique) so a re-sync updates and never duplicates; an existing SKU in the market is adopted; products gone from the store are turned off, never deleted. Stock is set through StockService at a place named for the connection ('Synced from …' in the history). Customers match accounts by email within the org (never merged; blanks never overwrite). Orders become Retail orders in the market with the store's number and status, the customer's account or a walk-in, and take no stock. - StoreSyncEngine: background runs, one per connection at a time; each record in its own transaction; at most 40 pages / 20 minutes per kind; 429 Retry-After waited out; a store error keeps what was saved and marks the run partial; created / updated / skipped / failed and the first problems per kind, grouped by run id; the 'changed since' mark only moves after a clean run. - BaseProviderHttpClient: timeouts, URIs (no double encoding), logs host and path only. - Connections: one per platform per market, PULL only (no push path ever existed), blank secrets keep the stored ones, deleting removes its history but keeps what it brought in; the DTO never carries a secret. DDL applied by hand 2026-11-08 (commerce_retail_external_links + sync log / config columns).
