Every object, field, source and destination — one map. Intake is the client-facing front door to Adesio’s matching engine: it ingests messy BOM files, learns each format, resolves every line to an MPN or a structured generic, and hands one clean canonical BOM across a fixed contract. This page traces what flows through it, and exactly where the portal stops and the Adesio Stack begins.
BOM import is the first step of a longer process already built in the Adesio Stack. The portal owns Extract + Transform + the Load contract; everything past the canonical handoff already exists downstream. The canonical schema is the boundary object between the two.
Any messy BOM format, dropped or uploaded. A file that is not a bill of materials is refused rather than analysed. .ebom · .xlsx · .xls · .csv
A reader per format turns the file into raw tables. New formats are new readers in front of the same pipeline. readBomFile → RawTable[]
Encoding, column roles, two-track resolution, canonical manufacturer, generics, noise removal — with a confidence and a basis on every line.
One fixed schema. Any format in, one clean canonical BOM out; Adesio never sees a raw format. adesio.bom.canonical/v1
Emit the project and its BOMs; each line becomes a bomLine, joined on IdTech. PLANNED
Authoritative match, enrich, risk and price — then RFQ and PO off the project. This is where a line the portal could not resolve gets resolved.
The portal’s KPI is resolution coverage and a clean Load. The anti-goal is rebuilding a second matching, risk or pricing engine downstream.
Real customer formats, each with its own quirks. Encoding is decided first — over the whole buffer, never a sniff — before any structure is read.
Semicolon-delimited; the MPN sits inside DESCRIPTION at a different position per family. Per-family extraction took this fixture 68% → 88% → 94%. BUILT
Read via SheetJS. A multi-sheet workbook becomes one project with several BOMs; non-BOM tabs are skipped. BUILT
Multi-level French exports: MPNs packed as MANUFACTURER (MPN), decimal commas, and printed reports whose nested sub-tables are folded back into their parent line by a named reshaper. BUILT
A reader per format in front of the unchanged pipeline. Not built. PLANNED
Decode before structure. Windows-1252 is decoded without ICU, so Node 20 stops silently dropping the 0x80–0x9F bytes. .xlsx is zip/XML and skips the ladder entirely.
The product is Intake. A drop zone, a command line, an HTTP API and a Claude connector are four ways to reach it — not four products, and not a core with integrations bolted on. Whichever door a file comes through it meets the same readers, the same resolution, the same adesio.bom.canonical/v1 contract and the same rules about what may be claimed. And the same INSTALLATION: a format learned in the app is recognised by the connector, and a part an operator confirmed anywhere is already settled everywhere.
Drop a file, read the report, correct a column, confirm a part. The only door with a human in front of it — and the only one that can offer the correction and confirmation gestures. BUILT
bom-analyzer <file> writes the report, the canonical document, the CSV and the search worklist. Deliberately applies NO operator confirmations: a figure it prints is about what the tool reads, not about what somebody clicked. BUILT
The same routes the app uses, described in OpenAPI 3.1 and rendered from the table the server dispatches on — so the description cannot drift from the API. An instance serves its own schema at /api/schema. BUILT
MCP over stdio: analyse, page through what needs review, export the searches, record a decision — inside a conversation. Every listing is paginated, because a real BOM does not fit in a model’s context. BUILT
What is not built, and is the same gap for three of them: there is no authentication and one client. A multi-tenant API, a remote connector added on claude.ai with OAuth, job semantics for large files and webhooks all wait on one thing — an API key that resolves to a client id. The stores are already scoped by client; nothing else is. PLANNED
Adesio matches downstream two ways, so a line is resolved if it carries either a confident MPN or a confident value + package. Only lines with neither are review items — and even those are not lost: they carry on into Adesio.
Has a real manufacturer part number. An MPN guessed from inside a description lands ambiguous with its candidate attached — never found. The manufacturer is resolved through the alias subsystem without ever overwriting what the file stated.
A chip R/C or inductor has no identity beyond its value and its package, extracted as a defined parse rather than a guess. A generic maps to a set of equivalents, not one part.
Competitors turn a description into candidate MPNs. The portal already did the hard half — structured extraction — and now wires the second half as a preview: a generic’s value and package are matched against parts the portal has already resolved confidently, offline, with no external call. Measured on the customer corpus, run 13 Sep 2026: 181 of 417 generic lines (43.4%) came back with at least one candidate. A candidate is never authoritative — the line stays ambiguous and Adesio’s matcher is the authority after Load.
The contract between portal and Adesio: adesio.bom.canonical/v1. Named fields are always present and null when unknown, so the shape is stable. Some fields carry to Adesio’s Parts view by name; the rest describe how confidently each was extracted.
| Field | → Adesio | What it carries |
|---|---|---|
| Identity — the payload | ||
| mpn | Part | Manufacturer part number, where the line has one. |
| manufacturer | — | Exactly what the file stated, never replaced. |
| manufacturer_canonical | join half | The maker the stated spelling resolved to — half of the natural key. |
| internal_pn | CPN | Client / internal part number. |
| idtech | join key | Surrogate UUID of the shared part. Null until resolved downstream. |
| refdes | — | Reference designator(s) on the board. |
| line | — | The source BOM’s own line number — traceability only, never matched on. |
| Generic track — required where there is no MPN | ||
| value | match input | Structured electrical value, with its basis. |
| package | match input | Structured package / footprint. |
| parametric_candidates | advisory | The preview set — ordered, tiered, never an override. |
| Status envelope — extraction basis, not a catalog match | ||
| mpn_status | bomLine status | found · ambiguous · not_found · not_sourceable · placeholder. |
| mpn_status_basis | envelope flag | Says this is what the FILE states, so nothing downstream reads it as a catalog confirmation. |
| mpn_source | — | Where the identity came from — a column, a description position, an alias. |
| resolution | — | mpn · matchable_generic · needs_review · not_sourceable. |
| review_reason | — | Why a line is in review — and whether that is our gap or the file’s. |
| Context & passthrough | ||
| quantity | Req. Qty. | Quantity, decimal-comma tolerant. |
| description | Description | The original line description, preserved. |
| custom_fields | passthrough | Operator-labelled columns — carried through, explicitly non-matching. |
Sourcing is driven by which map a column lands in, never by its label. Reserved roles are a fixed, closed vocabulary that maps to Adesio; a custom header is preserved but can never drive matching. The two maps never collide.
A hierarchy-depth column (Level / Niveau) and a parent-assembly code (code père) are vetoed out of the identity roles: neither is a weaker identity, they are not identities at all.
An operator can name any other column. It is carried into canonical as labelled passthrough — preserved and saved into the format profile, but it never reaches the classifier, and a custom label may never collide with a reserved role name.
The portal reports what it extracted, and on what basis — it does not confirm a part against a catalog. It uses Adesio’s status words but limits itself to extraction-basis outcomes; Adesio’s matcher produces the one authoritative FOUND. IdTech is the join.
found here means the FILE states one unambiguous part number — never that a catalog confirmed it. The basis flag on every line says so.
A surrogate UUID for the shared part, which absorbs normalisation and merge churn. The portal resolves or creates it; Adesio reads by it.
Only the core matcher, after Load, turns a line into a confirmed catalog FOUND.
The storage model is defined by what may be pooled across clients and what may not. A client’s BOMs and their part linkage never leave their boundary; how to read a format, and universal facts about a part, are shared — which is what makes the system get better with every file.
Raw BOMs, the CPN → IdTech linkage, quantities, board side, reports and canonical outputs. Isolated per client, never pooled. Never committed to this repo — fixtures are synthetic and structure-only.
How to read a format — headers, delimiter, column roles. No part data, so it is pooled: learned once, reused for every client using that exporter. The assumption is stated rather than assumed: a BOM’s column HEADERS are not treated as confidential.
Part number, manufacturer, family and the value+package it has been seen with. Universal — true whoever sent the file — so pooling them is the network effect: every BOM processed makes the next client’s generic line more resolvable.
The report, the FILENAME, the quantities, the dates. Never pooled, and the filename is why: BOM 40-00000001-001-F.CSV is a project code. Stored as a per-client ledger against the pooled facts, joined only for that client’s own view.
A bad row in a shared tier poisons every client, so a class-level change passes a confidence and provenance gate before any create or merge.
Format learning lives at the edge, so Adesio’s core only ever sees normalized data. Corrections feed the profile; nothing is ever silently self-applied.
The identity key is STRUCTURE only — headers, delimiter, column count, header row — and describes the file as it ARRIVES. 68 / 68 auto-recognised on the second pass of the corpus run.
Delimiter, column roles, refdes-prefix → family map, per-family description layout, and a named reshaper where a file is not one table. A recognised format brings its customer profile with it.
A near match is never auto-applied: every override is by column index, and a near match has shifted columns. It is proposed instead.
Many spellings resolve to one maker, keyed off the MPN rather than fuzzy name matching, against an 84k-row world-manufacturer reference. An inferred maker is badged and never overwrites the file.
Risk, alternates and sources already exist in the Adesio Stack. The portal’s leverage is upstream: hand them better inputs, and preview a lightweight version at intake. The authoritative numbers are always Adesio’s, after Load.
Feed a clean, canonical manufacturer to the existing risk engine — country-of-origin risk is only as good as that identity — and carry file-stated RoHS/SVHC through canonical. PLANNED
The parametric candidate set is exactly this object; file-declared Équivalent columns feed the same surface. BUILT
A clean, resolved BOM is what makes availability, price and RFQ run well downstream. PLANNED
Encoding detection, two-track resolution, the coverage headline, structure analytics, canonical export, and per-family MPN extraction from a fixed-layout description.
Fingerprint → format profile → auto-recognition, a JSON format store, the correction loop, the manufacturer alias subsystem, the Tier-3 catalog and the parametric preview.
Login, per-client isolation, hosting, object storage, encryption, the shared parts database — and the Load handoff to Adesio over an API. Deploy targets promote by tag. PLANNED
The map above says what the parts are. This says what HAPPENS, in order, and where four real scenarios diverge from each other. It is a process frise, not a calendar: the steps are in sequence, and nothing here is a duration. Only the cells that differ from the standard run are written out — a blank cell means that scenario does exactly what scenario A does, which is the point of laying them side by side.
| Scenario | ImportClient | EncodingPortal | FormatPortal | ResolutionPortal | ReportPortal | LearningPortal | Canonical BOMPortal | LoadPortal | Adesio downstreamAdesio |
|---|---|---|---|---|---|---|---|---|---|
| A · Standard BOMA known format, already learned. The path the portal is built to make ordinary. | One file, dropped. | Decided over the whole buffer, before any structure is read. | Fingerprint matches a saved profile; its column roles are applied with no prompt. | Each line resolves as an MPN or as a structured generic. | Coverage headline, the six sections, and the lines still waiting on a human. | Skipped — there is nothing new to learn about this format. | One document, every named field present, null where unknown. | Handed over the fixed contract. | Match, enrich, risk, price — Adesio resolves what intake could not. |
| B · New formatNobody has seen this exporter before. The extra work happens once; the second file of this shape is scenario A. | same as A | same as A | No fingerprint match. Column roles are decided from the content alone, and the report says so. | same as A | An operator corrects a column; the file is re-read and the whole analysis re-runs. | The corrected reading is saved as a named format, keyed on STRUCTURE — so the next file of this shape needs no prompt. | same as A | same as A | same as A |
| C · Part listA client whose policy forbids exporting a full BOM. The same parts without the structure — inherently reverse-engineering-safe, and the natural fit for a zero-egress sovereign deployment. | A flat list of part codes, with no reference designators and no placement. | same as A | same as A | Unchanged. The resolver never needed structure — most corpus fixtures state no board side anyway. | Missing structure is EXPECTED, not a gap: coverage is computed on what a part list can carry, and nothing is docked for absent design fields. | same as A | The design fields are null — not omitted. The shape stays identical. | same as A | same as A |
| D · Multi-sheet workbookOne file, several boards. The unit that arrives is a project, not a BOM. | One workbook, or a folder. Tabs that are not bills of materials are skipped. | No encoding decision — a workbook is zip/XML and stores its text as UTF-8. | same as A | same as A | same as A | same as A | One project carrying N BOMs, each one a document of its own. | The project is the unit handed over, with its BOMs under it. | same as A |