Skip to content

Canonical Product Field Mapping Matrix

ZWE-484

Defines a leading source per field for the canonical product/variant model (Product Sync Layer 2, ZWE-482), so conflicts between NAV and Ergonode are resolved by a written rule rather than by whichever sync job ran last. Feeds directly into ZWE-485 (canonical schema) and ZWE-487 (the merge sync command).

This builds on ZWE-391 (NAV → backend mapping, single source) and adds Ergonode as a second source with real conflict-resolution rules, per-field freshness and orphan handling — the wider scope ZWE-391 was deliberately not asked to cover.


Merge key

Article number + variant code, matching the identifier already confirmed on the Ergonode PIM page: "The variant code, combined with the article number, is used as the unique identifier for a variant."

  • Article number: NAV.ItemNo = Ergonode artikelnummer attribute (confirmed identical values, ZWE-496 real CSV export)
  • Variant code: NAV.LSItemVariant.Code, same value Ergonode uses for its own variant SKU

Verified for 2 of 4 in-scope brands

Uniqueness confirmed against the real bulk Ergonode CSV export (ZWE-496, 2026-08-18, 541 real Black Diamond/Petzl products) — no duplicate article number + variant code combinations found.

Meinl and Fjällräven not yet verifiable

ZWE-492 (Ergonode data completeness for all 4 in-scope brands) is still input required — Meinl and Fjällräven aren't fully imported into Ergonode yet. This matrix and merge key are correct in design, but uniqueness for those 2 brands can't be verified against real data until ZWE-492 closes. Flagging rather than guessing — do not treat this as blocking the rest of the matrix.


Field mapping

Canonical field Source(s) Leading source Freshness Nullable
Article number (merge key) NAV ItemNo, Ergonode artikelnummer NAV On sync (scheduled) No
Variant code (merge key) NAV LSItemVariant.Code NAV On sync No
Title Ergonode naam Ergonode On sync No
Description Ergonode Ergonode On sync Yes
Category Ergonode categoryList Ergonode On sync Yes — pending ZWE-501 (three-axis category mapping, still in progress)
Brand NAV Brand/BrandDescription, Ergonode merk Unresolved — see below On sync No
Images Ergonode product_media Ergonode On sync Yes
Colour / Size / Material / Gender / Waterproof / Collection Ergonode (kleur/maat/materiaal/sekse/waterdicht/collectie) Ergonode On sync Yes
Price (incl. VAT) NAV GetSalesPrice/PriceIncludingVAT NAV Scheduled sync (interval TBD by ZWE-487) No
Periodic discount NAV GetPeriodicDiscount NAV Scheduled sync Yes
Stock quantity NAV GetRealStock/StockQuantity NAV Scheduled sync, plus a live check at checkout (ADR-0004) No
Status / orderability NAV LSItemStatusLink/Blocked/NoStockPosting NAV Scheduled sync No — already implemented, ZWE-486
Barcode NAV LSItemBarcodes[] NAV Scheduled sync Yes

Brand: unresolved, not guessed

Already flagged as an open question on ZWE-391/ZWE-503 — unclear whether NAV's Brand code taxonomy matches Ergonode's merk attribute values 1:1. Until confirmed, treat Ergonode merk as leading (it's customer-facing/editorial, consistent with the rest of the content fields), but this needs Jasper/Florian sign-off before it's final.


Webshop-owned fields (third source, not NAV or Ergonode)

Per ZWE-483 — three fields that drive orderability come from neither NAV nor Ergonode. They're legacy webshop-owned data with no confirmed home in the new architecture yet:

Field What it does Source Leading source
bestelbaar Product option type 200, Ja/Nee, checked when adding to cart Legacy webshop, not NAV/Ergonode Unresolved — pending ZWE-483
Publication status offline/online/discontinued, maintained independently of the NAV status Legacy webshop Unresolved — pending ZWE-483
binnenkort_leverbaar Date field driving the "medio [month]" display when stock is zero Legacy webshop Unresolved — pending ZWE-483

Blocked on ZWE-483, not guessed

ZWE-483 is input required (Florian + Jasper) and its own Definition of Done requires the decision to be reflected here before ZWE-485 builds the schema. These 3 fields are intentionally left without a leading source in this matrix — do not assume they land in Ergonode, the backend, or stay legacy-only. ZWE-485 reserves space for them but does not commit to a shape until ZWE-483 resolves.


Orphan handling

Exists in Ergonode, not in NAV (editorial content with no sellable data): treat as draft/unpublished — no price, stock or orderability can be derived, so it must not appear as purchasable in the canonical model regardless of how complete its Ergonode content is.

Exists in NAV, not in Ergonode (sellable data with no marketing content): treat as excluded from the customer-facing catalogue — no title, images or category to display. This is a real, currently-occurring case, not hypothetical: the Ergonode page documents a known, unresolved reliability issue where "variants are not always correctly pulled from NAV, which can result in products appearing in Ergonode without their variants" — the inverse (NAV variant present, Ergonode missing it) is the same underlying sync gap and needs the same handling.

Both cases should be logged/countable (e.g. a sync_gaps view or count), not silently dropped — per ZWE-484's own Definition of Done ("remaining gaps are documented and accepted rather than left silently open").


Behaviour when a source is unreachable

Source down Behaviour
NAV unreachable Retain the last-synced price/stock/status values; mark the record's NAV freshness timestamp as stale. Do not block browsing on a failed sync. A live GetRealStock check still runs at checkout (ADR-0004) as the final authoritative gate regardless of how stale the cached value is.
Ergonode unreachable Retain last-synced content (title/description/images/attributes); mark the Ergonode freshness timestamp as stale. Content changes far less frequently than price/stock, so this is lower urgency — no live check needed at any point in the customer journey.

This requires per-source freshness timestamps on the canonical model, per ZWE-485's own Definition of Done ("record per record when each source was last seen").


Ergonode PIM Stock Statuses & Orderability NAV Field Mapping (ZWE-391) NAV Field Inventory