Skip to content

feat(sync-magento): add Magento 2 integration package - #27

Open
adrianliw wants to merge 6 commits into
open-mercato:developfrom
adrianliw:feat/issue-606-integration-with-magento2
Open

feat(sync-magento): add Magento 2 integration package#27
adrianliw wants to merge 6 commits into
open-mercato:developfrom
adrianliw:feat/issue-606-integration-with-magento2

Conversation

@adrianliw

Copy link
Copy Markdown

Summary

  • Adds @open-mercato/sync-magento, a DataSyncAdapter package integrating Magento 2 (REST API v1) with data_sync — categories, products (simple + configurable), attributes, inventory, orders, prices.
  • Retries category/product create-or-update on Magento url_key uniqueness conflicts (up to 5 attempts with a numeric suffix).
  • Wires the new package into the sandbox app and workspace.

See .ai/specs/SPEC-005-2026-06-12-magento2-data-sync-adapters.md for the full spec.

Test plan

  • yarn workspace @open-mercato/sync-magento test — 112 tests passing
  • yarn workspace @open-mercato/sync-magento tsc --noEmit — clean

Adds the @open-mercato/sync-magento module (entities, API routes, DI,
ACL, events, settings widget, CLI, migrations, tests) plus the
0.6.4 dependency bumps for carrier-inpost, test-package and the
sandbox app required by sync-magento's peer dependencies.
Registers all four DataSyncAdapter implementations (magento_products,
magento_prices, magento_inventory, magento_orders) in di.ts, fixing the
"not registered as a data sync provider" error on the Sync Schedule tab.

magento_products is fully implemented: EAV attribute + attribute-set +
category provisioning via ExternalIdMappingService, simple product
upsert via PUT /rest/V1/products/{sku}, optional image sync, per-item
error isolation. Phases 3–5 are registered as shells (mapping + validate
only) pending addendum specs.

Adds unit tests for products/attributes/categories adapters and shared
settings loader. Includes SPEC-005 spec doc.
Magento rejects category/product creation when the auto-derived
url_key collides with an existing one. Retry the create/update up to
5 times with a numeric suffix appended to the url_key on conflict.

Also stop logging full request/response payloads for product exports
and drop dead code left over from error-message handling.
Needed to validate the sync-magento Phase 3 (magento_prices) adapter
against a live Magento sandbox against current core behavior. Also
drops sync-magento's own core/shared/ui devDependencies (unused) and
adds the yarn patch generated for the bumped @open-mercato/core.
Implements streamExport for the magento_prices adapter: bulk base/
special/tier price push to Magento (/products/base-prices,
/products/special-price, /products/tier-prices), channel-aware via
channelStoreMappings resolved to Magento store_id/website_id through
new lib/store-views.ts, falling back to Magento's global scope when
no channels are configured. Covers both standalone simple products
and configurable products' variants.

Live-validated against a real Magento 2.4 sandbox. Fixes a bug found
during that validation: Magento rejects any non-zero store_id/
website_id for price endpoints when its Catalog Price Scope is set to
Global ("Could not change non global Price when price scope is
global") — added isGlobalPriceScope() to detect this via the price
attribute's scope field and collapse channel targets to 0 accordingly,
while still using the real per-channel id under Website/Store scope.

Also fixes the Magento env-preset preconfiguration log, which was
writing under the bundle id ("sync_magento") instead of a registered
integration id, so it never surfaced on any integration's log tab.

Adds per-product integration log entries (visible in the Magento
Products integration's log tab) for skipped/failed product exports,
and fixes the Turbopack dev-server crash caused by globals.css's
Tailwind @source glob sweeping package __tests__ directories.
Implements streamImport for the magento_orders adapter: pages Magento
orders via searchCriteria (updated_at cursor + optional status filter),
resolves each order's channel via channelStoreMappings/defaultOrderChannelId,
resolves/creates the OM customer per customerStrategy (skip/create_or_link/
create_only), best-effort matches line-item SKUs to local products, and
dispatches sales.orders.create / customers.people.create via commandBus
(now exposed on AdapterContext). Tracks external-id mappings for
idempotent re-runs and emits sync_magento.order.imported.

Two contract corrections found against current @open-mercato/core (differ
from the original sketch): order totals are recomputed server-side from
line items rather than accepted verbatim, and customerSnapshot nests
under a `customer` key rather than being a flat record.

Live-validated against the Magento sandbox's sample orders: import,
customer dedup by email, and idempotent skip-on-rerun all confirmed.

Phase 4 (magento_inventory) is deliberately deferred — stock sync is
superseded by the new `wms` core module (open-mercato/open-mercato#1701)
and would need reworking against it shortly after; magentoInventoryAdapter
stays a registered shell.

Also fixes the Magento env-preset preconfiguration log, which was
writing under the bundle id instead of a registered integration id
and so never surfaced on any integration's log tab.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant