Configurator
Turn one part number into a parametric family. Inputs drive rules that resolve the BOM, routing, and price per order.
The configurator models a family of variants under one item. Users provide parameters, and rules use those values to resolve the item's at order time. Rules can select bill-of-materials components, routing details, and line cost.
Enable Requires Configuration in the part's manufacturing settings (requiresConfiguration, apps/erp/app/modules/items/ui/Item/ItemManufacturingForm.tsx:82). The stored method then becomes a template. Each job or quote line runs the rules to create its own resolved method.
Parameters — the inputs
Each parameter has a label, machine key, and data type (configurationParameterValidator, apps/erp/app/modules/items/items.models.ts:341). Rules reference the key. Use lowercase alphanumeric segments separated by single underscores, such as length or wall_thickness.
listOptions is required for this type).The base set (text, numeric, boolean, list, material) is configurationParameterDataTypes (items.models.ts:22); date is added by the validator (items.models.ts:347). material was added to the underlying enum in migration 20250809000000_add-material-configurator-type.sql.
Parameters can be sorted into groups so the order form reads as sections (Dimensions, Finish, Tolerances) rather than one flat list. A group is just a named heading with a sort order (configurationParameterGroupValidator, items.models.ts:325); parameters land in an auto-created "Ungrouped" group until you file them. Both groups and parameters reorder by drag-and-drop, and both surfaces edit the same rows (ConfigurationParameters.tsx).
Rules — deriving the method
A rule binds a method field to code that computes its value from the parameters (configurationRuleValidator, items.models.ts:369).
Rules attach per-field right on the embedded method editors. On the bill of materials each component exposes configurable fields — itemId (swap the component), quantity, unitOfMeasureCode, and methodType (BillOfMaterial.tsx:841,866,890,1043); on the bill of process, operation fields like the work center, process, and setup/labor/machine times. A field with a rule shows a "configured" marker instead of a static value.
You author the code in a Monaco editor (ConfigurationEditor.tsx) that generates the function skeleton and type definitions for you from the parameters, with a Run button to test the output before saving. The code is the body of a configure(params) function; params holds your parameters by key, and you return the value for that field:
function configure(params: Params): number {
// one thread every 2mm of engagement, minimum 4
return Math.max(4, Math.ceil(params.engagement_length / 2));
}Rules run in a sandbox — keep them pure
Rule code runs in an isolated JavaScript sandbox (QuickJS, packages/database/src/configuration-rule.ts), both when a method is created and when you test a rule in the editor. The parameters are the only input and the returned value is the only output: a rule has no network, timers, or access to the page or server it runs in, and each run is limited in time and memory. A rule that fails to compile, throws, or exceeds a limit is ignored: a field keeps its default, and a bill of materials or process keeps all of its lines. Rules are for deriving a value from the inputs, not for side effects.
Rules can also filter the method wholesale: a billOfMaterial or billOfProcess rule returns the list of component or operation names to keep, so a boolean parameter can drop a whole subassembly or an outside-processing step from the recipe.
Choosing a configured item at order time
Configuration runs when a configured part is added to a quote line, sales order line, or job. The form displays Configure and disables Save until the required parameters are submitted (QuoteLineForm.tsx:556, JobForm.tsx).
Submitting the configuration stores the answers on the line (quoteLine.configuration / job.configuration, JSON) and calls the get-method engine with those values (x+/quote+/$quoteId.$lineId.configure.tsx). The rules run, and the line gets its own resolved bill of materials, routing, and cost — a concrete instance of the parametric family, not the template. Reconfiguring clears the line's prices and re-derives everything.
A configured item's method can't be hand-overridden
Because the method is resolved from rules, you can't point a job or line at a different method for a configured item — the get-method engine rejects it ("Cannot override method of configured item"). Change the parameters, not the recipe.