Skip to content

Solution Proposal: Adapting Product Selection for Rise ​

Author: Damian Dibbets Date: 2026-06-10 Status: Proposal


Executive Summary ​

This proposal recommends adapting the Product Selection application to integrate with Rise (the Vulcan platform). The Product Selection is a production-ready, standalone catalogue browser that connects field workers to live supplier data, pricing, and product specifications from 2BA — the primary Dutch construction product database. With ENK Project 8 being discontinued, Product Selection is being migrated forward into Vulcan rather than maintained in ENK. Adapting Product Selection to Vulcan's auth, cart, and API contracts delivers immediate value without rebuilding catalogue UX from scratch.


Problem Statement ​

Rise needs a way for craftsmen to browse supplier catalogues, find the right articles, and push them directly into purchase orders or work order material lists. Building this from scratch would require:

  • A product catalogue browser with category-driven navigation
  • Live integration with one or more supplier data platforms (2BA, ETIM, regional equivalents)
  • Cart → ERP line item submission flow
  • Multi-market and multi-locale support

Estimated build effort from scratch: 3–6 months.

Additionally, 2BA offers their own embedded catalogue UI called Unifeed, but it is not a viable off-the-shelf solution. Unifeed uses an inverted discovery model — the user starts from a known product and navigates upward to its class or group. For craftsmen this is backwards: they think in terms of the type of work first, not the specific article. Unifeed does not support the class-first, context-driven browsing model that field users expect.


Context: ENK Project 8 Discontinued ​

ENK Project 8 is being discontinued. Product Selection is extracted from that codebase and adapted to run against Rise's backend services. The adaptation work lives in Product Selection itself — replacing ENK-specific API clients, auth mechanisms, and backend contracts with Rise equivalents.


Proposed Solution ​

Adapt the Product Selection application to integrate directly with Rise. It continues to run as a standalone Next.js application embedded via iframe in rise-web (or equivalent frontend). Auth, cart submission, tenant mapping, and supplier sources are wired against Rise's API contracts — these become adaptation points within Product Selection, not in an intermediary layer.

What the Product Selection is ​

A standalone Next.js application that lets field workers browse a product catalogue, select articles, and add them to a purchase cart. It embeds cleanly into any frontend via iframe.

Unifeed (2BA)Product Selection
Starting pointKnown productETIM work category
Discovery flowProduct → class → groupGroup → class → product
Direct searchProduct search onlySearch lands in correct class/group context
Suited forProcurement specialistsField workers and craftsmen

Our navigation model matches how craftsmen actually work: "I need fittings for a 22mm copper installation" → group → class → product → supplier. This is not something Unifeed provides and cannot be configured into it.

Capabilities ​

AreaDescription
Product browserETIM class tree → product list with filters and search
Product detailsSpecs, features, attachments, time standards, couplings
Suppliers / trade itemsLive price + availability from 2BA per product
CartAdd/remove items, set quantities, submit to backend
Multi-source data2BA (primary), Cafca CMC, internal CAFCA, KetenStandaard/ETIM
i18nnl, en, nl-BE, fr-BE

Technical Architecture ​

Core flow ​

vulcan-web owns session initiation. Product Selection communicates only with 2BA for product data and returns the cart to vulcan-web via the mechanism provided at iframe open time (postMessage or a callback URL). The 2BA access token is obtained by vulcan-web via vulcan-be-integrations (VIL) — the platform's integration layer — so credentials never touch the browser directly.

mermaid
sequenceDiagram
    actor U as User
    participant F as vulcan-web
    participant VIL as vulcan-be-integrations
    participant PS as Product Selection
    participant 2BA as 2BA API

    U->>F: Open product selection
    F->>VIL: GET /api/integrations/2ba/token (tenant-scoped)
    VIL-->>F: accessToken2BA (VIL resolves credentials from K8s secret)
    F->>PS: Open iframe with accessToken2BA, locale, cartId,<br/>and cart submission callback
    PS-->>F: Session ready, redirect to /{locale}/classes

    U->>PS: Browse ETIM groups → classes → products
    PS->>2BA: Fetch products & trade items (Bearer accessToken2BA)
    2BA-->>PS: Products, suppliers, pricing

    U->>PS: Add items to cart, submit
    PS->>F: Cart submitted via callback (postMessage / callback URL)
    F->>F: Handle cart lines (vulcan-be-quotation or vulcan-be-calculations)

Adaptation points ​

These are changes within Product Selection to replace ENK-specific contracts.

ConcernCurrent (ENK)Vulcan adaptation
Session initENK backend starts cart, issues cookievulcan-web initiates directly — passes 2BA token (from VIL), locale, cartId at iframe open
2BA credentialsENK-managedvulcan-be-integrations (VIL) resolves tenant 2BA credentials from K8s secret; exposes a token endpoint; credentials stored in vulcan-be-integrations-credentials K8s secret sourced from Key Vault
Cart submitPOST to ENK backendSubmit via callback mechanism vulcan-web provides (postMessage or callback URL); vulcan-web submits lines to vulcan-be-quotation (quote materials) or vulcan-be-calculations (budget line items)
User & tenant identityENK MongoDB ObjectIdsProvided by vulcan-web at init time via the Better Auth JWT session; no additional backend lookup needed
Supplier sources2BA + CafcaConfigure per tenant/country in VIL registry (config/registry.json); no Product Selection code change per market
Localenl, en, nl-BE, fr-BEExtend locale files; SE pack already exists via VUL-167's L10N engine — sv locale is a straight add
Backend API client@enk/project8-backend-coreRemove entirely — Product Selection calls 2BA only; all ERP-side ops go through vulcan-web callbacks

Deployment ​

Product Selection follows Vulcan's standard container deployment pattern.

AspectValue
Repovulcan-product-selection (new submodule, follows vulcan-* naming)
Docker imagevulcanacrprod.azurecr.io/vulcan-product-selection:<tag>
K8s namespacevulcan (same as all other services)
Helm charthelm/ in repo root, matching vulcan-web-components pattern
Ingressproduct-selection.<env>.aceve.cloud
CI/CDGitLab CI using the workspace's .NET/Node.js pipeline templates

The vulcan-web frontend only needs the iframe URL. Product Selection can be scaled, deployed, and versioned independently.


Benefits ​

  1. Immediate value for the Netherlands launch. 2BA covers the Dutch and Belgian markets. The OAuth flow, product APIs, and trade item pricing are production-ready today.

  2. Saves 3–6 months of catalogue UX work. The product browser, supplier data integration, cart flow, and ETIM taxonomy are fully built and battle-tested.

  3. Scales across Europe with minimal effort. Adding a new market's supplier source requires one new adapter configuration. The product browser UX is inherited.

  4. ETIM taxonomy included. Class trees, feature filters, synonym maps, and KetenStandaard API integration are already wired. This is the standard European construction product classification system.

  5. Clean ERP integration pattern. The cart → work/calculation line submission flow maps directly to Rise's purchase requisition and work order concepts.

  6. Decoupled and independently deployable. No tight coupling to the Rise frontend. The iframe boundary keeps concerns clean.


Next Steps ​

  1. VIL 2BA adapter — Implement a 2BA adapter in vulcan-be-integrations (Sdk-only, follows the ExactOnlineConstruction adapter pattern). Add a token-vending endpoint so vulcan-web can fetch accessToken2BA without exposing raw credentials. Register credentials in vulcan-be-integrations-credentials K8s secret (Key Vault source: vil-2ba-nl-client-id, vil-2ba-nl-client-secret).
  2. Session init contract — Agree on the iframe init message shape: { accessToken2BA, locale, cartId, callbackType: 'postMessage' | 'url', callbackTarget }.
  3. Cart submission contract — Agree on the postMessage schema for cart lines; map to vulcan-be-quotation quote materials or vulcan-be-calculations budget line items depending on entry point.
  4. Remove ENK client — Strip @enk/project8-backend-core from Product Selection; ensure only 2BA API calls remain.
  5. Locale: add sv — Connect to VUL-167's sv/SE country pack. sv locale file is a straight add to Product Selection's i18n directory.
  6. New submodule — Create vulcan-product-selection repo, add to workspace as submodule, wire into docker-compose.yml and workspace Makefile alongside other services.

Built with VitePress | v1.2.0 | 🚀 Week One Sprint