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,slugname,description— these viaproduct_translationsacross multiple locales (HU, EN, DE)base_price,currencycategory_idimage_url(main thumbnail) +product_mediatable for the gallerytags(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. ontravelium.hushow "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-kftdoes 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:
- CSV import to the Catalog module: 80 rows, 10 columns. → 80
productsrows, alldraft. - AI image generation (Style A 3D-isometric): 80 PNGs generated, uploaded to R2,
image_urlfields filled. - AI translation: from HU source descriptions to EN + DE. → 240
product_translationsrows. - Storefront-specific overrides (only on 8 products, where we wanted a different SEO title on
mediaorigo.hu). - 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.