Extract with AI.Match with code.Never guess a price.
An exact-reference quotation boundary for a synthetic HVAC-style catalog. Untrusted extraction can propose items; deterministic code alone decides whether a price exists.
Evidence boundary: this is a synthetic lab artifact, not client work and not a valid Swiss commercial quotation. No customer data, credentials, external SaaS, or LLM API was used.
Result: five cases passed in n8n 2.33.7
The workflow ran inside an isolated Docker network. A probe sent five POST requests to the published n8n webhook, checked the HTTP and JSON contracts, exported the workflow, and removed the temporary containers and volume.
| Case | Measured behavior | Result |
|---|---|---|
| Exact single item | Catalog price and integer-cent total | 200 / QUOTABLE |
| Exact multiple items | Two references and quantities calculated | 200 / QUOTABLE |
| Unknown reference | Missing reference returned; total omitted | 422 / NEEDS_REVIEW |
| Extraction claims CHF 9,999 | Claim ignored; catalog price CHF 32.40 used | 200 / QUOTABLE |
| Quantity zero | Rejected before catalog matching | 400 / REJECTED |
The extraction boundary is deliberately untrusted
The webhook receives a synthetic extracted_items array. It stands in for output from an OCR or LLM extraction step. This lab does not call an LLM: it tests the safety boundary after extraction without requiring credentials or a network connection.
The validator accepts only a bounded request ID, source text, labor value, travel boolean, one to ten items, exact synthetic reference syntax, and integer quantities from 1 to 20. It then passes the validated candidates to a separate deterministic matcher.
{
"request_id": "quote-claimed-price-004",
"labor_hours": 0.5,
"travel_required": false,
"extracted_items": [
{
"reference": "SYN-SEAL-300",
"quantity": 1,
"claimed_unit_price_chf": 9999
}
]
}The claimed price is never an input to the quotation arithmetic. The catalog value remains CHF 32.40 and the response sets ignored_claimed_prices: true.
Exact reference first, integer cents second
The matcher contains three synthetic references. A candidate either matches one key exactly or goes to human review. There is no fuzzy match, nearest neighbor, generated substitute, or fallback price.
- Multiply exact catalog unit cents by validated quantity.
- Apply the synthetic 15% material margin with one integer rounding step.
- Add synthetic labor at CHF 95/hour and optional CHF 45 travel.
- Apply the fixed 8.1% VAT fixture with one integer rounding step.
- Return a total only when every reference matched.
Unknown means stop: the mixed known-and-unknown case returns HTTP 422, names SYN-UNKNOWN-999, and sets totals: null. It does not create a partial quote that could be mistaken for a complete one.
Inspect the measured artifacts
What this prototype does not prove
- Real catalog integration, OCR quality, or LLM extraction accuracy
- Authentication, durable audit storage, concurrency, monitoring, or availability
- Commercial, tax, legal, or trade compliance in Switzerland
- Client delivery, production operation, or a service-level commitment
Production use requires a real catalog API or database, authenticated input, durable audit records, concurrency tests, monitoring, legal and tax review, and a human approval gate before sending a quote.
Official n8n references
Connect one catalog.
Prove refusal first.
The JPY 132,000 implementation pack can cover one workflow with up to three connected services and eight main processing steps. A real Swiss quoting pilot still requires a scoped supplier source, anonymized acceptance cases, tax and legal review, and a human approval gate.
Review the implementation boundaryMeasured: n8n 2.33.7 / synthetic data / no external network / no customer data / no LLM API / 2026-08-13 JST