Back to Journal
netorigoen

The shared product surface of ERP + storefront — catalog as single source of truth

One product, 10 attributes, same SKU across 8 storefronts, opt-in override table for presentation, Draft→Active rolling release of 80 SKUs in a day.

A classic problem pattern: in the company ERP the product runs under code SKU-12345 with 18 attributes. On the webshop the same product has 24 attributes (different SEO title, longer description, image collection). In the Marketing CMS it exists a third time, because that needs hand-curated content. Three places, 60 attributes total, and the integration sync runs 4 hours per week — and still has source-data conflicts. In the Netorigo model there is ONE place.

10 attributes, 8 storefronts, one admin

The Netorigo catalog is a single source of truth. A product (say NIT-AI-ASSISTANT-PRO) sits in the products table on one row, with roughly 10 attributes:

  • id, sku, slug
  • name, description — these via product_translations across multiple locales (HU, EN, DE)
  • base_price, currency
  • category_id
  • image_url (main thumbnail) + product_media table for the gallery
  • tags (JSONB)
  • metadata (JSONB — domain-specific extras)

These 10 attributes are the truth. Everything else — SEO title, long marketing copy, store-specific category placement — either derives from these or lives in a storefront-specific override table.

The storefront-specific override

The storefront_product_overrides table is the compromise. A row here can override a field for a (storefront_domain, product_id) pair:

  • display_name (e.g. on travelium.hu show "Barcelona city break" instead of "Barcelona 4 nights")
  • display_description (longer, marketing copy)
  • display_price (only if the tenant allows storefront-level price overrides — netorigo-kft does not)
  • visibility (visible / hidden)
  • category_position (integer 0-100, where on the category list it appears)
  • seo_title, seo_meta_description

With no row here, the default products values are used. This is the "opt-in override" pattern: not 8 rows of override-per-storefront duplication, but a new row only when display is truly unique.

The "Draft → Active" rolling release

The products table has a status field: draft, active, archived. A draft product is not visible on any storefront — but is editable in the Catalog module admin UI.

The important part is the published_at field. A product can be marked active but only become live at a future date. So the marketing team can prepare all new products two weeks before a campaign, all in draft, with images and descriptions, then set the publish date and on campaign day they go live automatically across all storefronts at once.

A concrete example: 80 products land on 5 storefronts

Our most recent large campaign: 80 new AI-consulting packages (NC-* SKU prefix) on all 5 relevant storefronts (nortinia.com, mediaorigo.hu, netorigo.com, meta-architects.hu, lunda.eu). All data entry happened in one admin UI:

  1. CSV import to the Catalog module: 80 rows, 10 columns. → 80 products rows, all draft.
  2. AI image generation (Style A 3D-isometric): 80 PNGs generated, uploaded to R2, image_url fields filled.
  3. AI translation: from HU source descriptions to EN + DE. → 240 product_translations rows.
  4. Storefront-specific overrides (only on 8 products, where we wanted a different SEO title on mediaorigo.hu).
  5. Publish — one button, all 80 products to active, appearing on all 5 storefronts simultaneously.

In a classic 3-system ERP this is 4-5 days of work, with a lot of manual data entry. Here it was 1 day.

The developer takeaway

If you build a new storefront, DON'T pull the catalog into your own DB. Read the Catalog module's public API (GET /api/products?storefront_domain=X), and write storefront_product_overrides only when the storefront genuinely wants to override something. The catalog is the source — everything else is just a presentation layer.

Closing

10 attributes, 8 (often 13) storefronts, ONE admin. The Netorigo catalog being a single source of truth means a customer on travelium.hu or nortinia.com sees the same product, just with context-appropriate presentation. That is the essence of a multi-storefront ERP, and it's what pulls a company struggling with 3-system synchronization into the ecosystem.