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.
Navigation model (vs. Unifeed) ​
| Unifeed (2BA) | Product Selection | |
|---|---|---|
| Starting point | Known product | ETIM work category |
| Discovery flow | Product → class → group | Group → class → product |
| Direct search | Product search only | Search lands in correct class/group context |
| Suited for | Procurement specialists | Field 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 ​
| Area | Description |
|---|---|
| Product browser | ETIM class tree → product list with filters and search |
| Product details | Specs, features, attachments, time standards, couplings |
| Suppliers / trade items | Live price + availability from 2BA per product |
| Cart | Add/remove items, set quantities, submit to backend |
| Multi-source data | 2BA (primary), Cafca CMC, internal CAFCA, KetenStandaard/ETIM |
| i18n | nl, 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.
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.
| Concern | Current (ENK) | Vulcan adaptation |
|---|---|---|
| Session init | ENK backend starts cart, issues cookie | vulcan-web initiates directly — passes 2BA token (from VIL), locale, cartId at iframe open |
| 2BA credentials | ENK-managed | vulcan-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 submit | POST to ENK backend | Submit 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 identity | ENK MongoDB ObjectIds | Provided by vulcan-web at init time via the Better Auth JWT session; no additional backend lookup needed |
| Supplier sources | 2BA + Cafca | Configure per tenant/country in VIL registry (config/registry.json); no Product Selection code change per market |
| Locale | nl, en, nl-BE, fr-BE | Extend locale files; SE pack already exists via VUL-167's L10N engine — sv locale is a straight add |
| Backend API client | @enk/project8-backend-core | Remove 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.
| Aspect | Value |
|---|---|
| Repo | vulcan-product-selection (new submodule, follows vulcan-* naming) |
| Docker image | vulcanacrprod.azurecr.io/vulcan-product-selection:<tag> |
| K8s namespace | vulcan (same as all other services) |
| Helm chart | helm/ in repo root, matching vulcan-web-components pattern |
| Ingress | product-selection.<env>.aceve.cloud |
| CI/CD | GitLab 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 ​
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.
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.
Scales across Europe with minimal effort. Adding a new market's supplier source requires one new adapter configuration. The product browser UX is inherited.
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.
Clean ERP integration pattern. The cart → work/calculation line submission flow maps directly to Rise's purchase requisition and work order concepts.
Decoupled and independently deployable. No tight coupling to the Rise frontend. The iframe boundary keeps concerns clean.
Next Steps ​
- VIL 2BA adapter — Implement a 2BA adapter in
vulcan-be-integrations(Sdk-only, follows theExactOnlineConstructionadapter pattern). Add a token-vending endpoint sovulcan-webcan fetchaccessToken2BAwithout exposing raw credentials. Register credentials invulcan-be-integrations-credentialsK8s secret (Key Vault source:vil-2ba-nl-client-id,vil-2ba-nl-client-secret). - Session init contract — Agree on the iframe init message shape:
{ accessToken2BA, locale, cartId, callbackType: 'postMessage' | 'url', callbackTarget }. - Cart submission contract — Agree on the postMessage schema for cart lines; map to
vulcan-be-quotationquote materials orvulcan-be-calculationsbudget line items depending on entry point. - Remove ENK client — Strip
@enk/project8-backend-corefrom Product Selection; ensure only 2BA API calls remain. - Locale: add
sv— Connect to VUL-167'ssv/SE country pack.svlocale file is a straight add to Product Selection's i18n directory. - New submodule — Create
vulcan-product-selectionrepo, add to workspace as submodule, wire intodocker-compose.ymland workspace Makefile alongside other services.
