Scenario · B2B configurator · Custom manufacturing
From quotes by email
to a real-time configurator.
A company that makes custom components and prepares every quote by hand, across price lists, spreadsheets and questions to the engineering office. A web configurator that calculates price and item code while the customer chooses.
Web app scenario — B2B product configurator
300 product variants.
Every quote made by hand.
The scenario: a maker of custom industrial valves and hydraulic components, supplying process plants, shipyards and the food industry across Europe. The products are highly configurable: diameter, nominal pressure, body material, connection type, internal lining, certifications. Combining the variables gives hundreds of possible configurations, each with a different price.
Without a configurator, every quote request follows the same loop: the salesperson collects the specs, emails them to the technical office, which checks feasibility and passes the data to the pricing office, which prepares the quote in Excel and sends it back to sales. Typical time: 3–5 working days.
In a market where foreign competitors reply within 24 hours, this process becomes a real disadvantage: some deals are lost purely on response time.
«We already know we can make the product. The problem is that the customer doesn't — because it takes four days to tell them. Meanwhile they've already called someone else.»
— What I often hear in manufacturing companiesIndustrial B2B configurator requirements
From days to minutes.
With no configuration errors.
Guided step-by-step configurator with real-time validation
The system must guide the user through the product parameters, showing only technically valid combinations. If you select DN 150 with 40 bar pressure, the "bronze" material must disappear from the list — because that combination isn't certified. Compatibility rules are handled server-side, not client-side.
Real-time pricing with customer-specific price lists
The price must update at every parameter change, without clicking "calculate". Each B2B customer has a personalized price list (discounts, surcharges for certifications, locked prices on some product families). The pricing engine must apply the right rules for the logged-in user, without ever exposing the base price list to the frontend.
One-click branded PDF quote generation
The quote PDF must include: company header, customer data, full technical description of the configured product, net price with breakdown, supply terms, quote validity and the salesperson's digital signature. Generated in under 5 seconds and emailed to the customer automatically.
Automatic sync with HubSpot CRM
Every generated quote must automatically create a deal in HubSpot with all the configuration details, the quote value and the assigned salesperson. If the customer already exists in the CRM, the deal is linked to the existing contact. If they're new, the contact is created. No double manual entry.
Self-service access for direct customers with a private area
The largest customers must be able to access the configurator directly, without going through a salesperson. They see only their own price list and the history of previous quotes, and can start again from a saved configuration. The sales office is notified of every new quote generated by a customer on their own.
Technical challenges of a real-time pricing engine
A pricing engine
that never lies.
A wrong configurator is worse than none: if it produces a wrong price or accepts an impossible combination, the company has to renegotiate an offer already accepted. The main challenge isn't technical — it's absolute correctness.
B2B configurator development process
9–10 weeks to turn
tacit knowledge into software.
Two weeks with the technical lead and the most experienced salesperson to map every compatibility rule. They're usually not documented: they live in people's heads and in some internal Excel file. The result is a structured document with every rule in the form "IF [parameter A] = X AND [parameter B] = Y → THEN [parameter C] cannot be Z", which becomes the engine's data model.
The heart of the system: the Node.js rule engine reads rules from PostgreSQL, evaluates them by priority and returns each step's options. The pricing engine applies the logged-in user's price list — base price × material coefficient × pressure coefficient + options, then the contract discount. Redis caches price lists for 15 minutes. Load tests to check it handles hundreds of requests per second.
A step-by-step React interface: each choice asks the backend for the next step's valid options. The price updates in real time with a 300 ms debounce on the call. State is saved to PostgreSQL every 30 seconds — close and reopen the browser and everything is as it was. Plus a "quote history" for customers with direct access.
The PDF template is built in HTML/CSS and faithfully reproduces the existing paper one. Puppeteer turns it into a PDF in a few seconds in a dedicated process. The file goes to S3 and is emailed to the customer and the salesperson. In parallel the same quote reaches the CRM via API: contact created or updated, a deal with every configuration field, assigned to the salesperson.
Two weeks of testing with some salespeople and external agents. It's normal for a couple of missing rules (very rare cases never mentioned in interviews) or a discount misapplied on a product family to come up: with the configurable rule engine they're fixed without a new release. Gradual go-live: internal sales first, then agents, then self-service customers after a few weeks of stability.
Solution: Node.js rule and pricing engine
The rule engine:
hundreds of constraints, none in the code.
The most important architectural choice is separating business rules from code. Every time the technical office adds a variant or changes a compatibility, it edits a row in the database — no new release.
Configurable rule engine — editable without code
Each rule is a PostgreSQL row with four fields: param_key, param_value, excluded_key, excluded_values and a priority for conflict handling. The Node.js engine loads the rules relevant to the current configuration, evaluates them in order and returns an array of valid options for the next step. The technical office manages the rules from an admin panel built with React Table — no developer involvement needed to add or change constraints.
PDFs in seconds — identical to the paper template
Puppeteer renders an HTML/CSS template with the quote data filled in on the server. The template reproduces the company's paper format: header with vector logo, technical parameter table with units, price breakdown, supply terms, validity and the salesperson's signature. The Puppeteer process is separate from the main server, with a 10-second timeout and automatic retry. Goal: a quote ready in under 5 seconds.
An always up-to-date CRM — without touching HubSpot
Each quote triggers a background sequence: first the PDF goes to S3, then CRM sync starts. The contact is looked up by email — updated if it exists, created if not. Then the deal is created or updated with an offerta_id field as the idempotency key: if the job runs twice, it doesn't create a duplicate. Salespeople find every quote in the CRM already linked to the right contact, with the PDF attached, the value and the "Quote sent" stage. Goal: zero manual entry.
Why it matters: the sales manager stops doing the "evening round" to update the CRM by hand, and the data stays clean, with no duplicates.
Node.js React PostgreSQL tech stack
Node.js at the center.
Every tool in its place.
Why Node.js and not PHP/Laravel?
The pricing engine evaluates dozens of rules in sequence for each request: fast but very frequent work. Node.js handles well the concurrency typical of an API making many Redis and PostgreSQL queries in parallel. Using TypeScript on both front end and back end reduces context switching and interface bugs between the two layers.
Why Puppeteer and not a PDF library?
Libraries like PDFKit or jsPDF require building the layout programmatically — every line, every table, every margin defined in code. An HTML/CSS template is infinitely more maintainable: a designer can change the look of the quote by editing CSS, without touching JavaScript. The price is a slightly heavier process, solved with the isolated worker and pre-warming Puppeteer when the server starts.
Example goals — B2B configurator
From days to minutes.
Every quote tracked.
Example figures, not a client's results: realistic goals for a scenario like this, to be measured in the first months after launch against the same period before.
«A customer sends an order through direct access at 10:30 p.m. on a Friday. Before, they'd have waited until Monday.» That's the scenario to aim for: a company that answers even when the office is closed.
— The concrete goal of self-service accessProduct configurator development learnings
What I bring
to every project like this.
Separating business rules from code pays off immediately. After launch new variants and compatibilities always arrive: with the rule engine the technical office handles them from the panel, with no development work.
Prices are always calculated on the server, and only there. Calculating in the browser would cut calls but expose the price-list coefficients to anyone opening developer tools — handing your pricing structure to competitors. With a 300 ms debounce the experience still feels real-time.
Autosave is always worth the cost. One accidental refresh is enough to lose ten minutes of configuration: for any web app with complex forms it's non-negotiable.
Idempotent sync jobs aren't a detail. In production a job sometimes runs twice (timeout + retry). Without a check on a unique ID, the CRM fills up with duplicates in the first days after launch, exactly when data quality matters most.
Direct access for B2B customers changes the relationship more than any feature. Some quotes arrive outside office hours, and a transparent, fast process builds a different kind of trust than a phone call with a salesperson.
Do you have a sales process that deserves to be automated?
Configurators, quotes, complex catalogs — if the logic already exists, it can be coded.
Have a similar project in mind?
Tell me about it: we start from goals and priorities, and the first call is free.