Closed general

Keep the vendor part numbers Component Ocean returns (DigiKey now, Mouser when CO has it)

Colby Knox · 22d ago ·closed by Colby Knox

@ray, sign-off wanted before we build, so nothing here duplicates what Component Ocean already does or plans.

What we see

The hardware sidebar's Stock feature asks CO one question per page, GET /api/part/<MPN>, and gets back Mouser stock and price, DigiKey stock, price and part number (canonical.digikey_pn), and the LCSC C-number with JLC stock and tiers. Example: adom/m95256-wmn6tp shows "Mouser 131 in stock, $0.82" and "DigiKey out of stock, $0.81" with no Mouser or DigiKey number on the page, because the page never declared them and the wiki only prints declared numbers. The DigiKey number CO returned (497-8691-2-ND) is dropped on render; the Mouser record has no SKU field at all.

Plan (wiki side)

  1. Keep every vendor part number CO returns, in its own table (component_vendor_ids: page, vendor, part, matched MPN, source component-ocean, checked_at). Separate from distributor_links, which is rebuilt from page.json on every push; a number the author declared always wins, and nothing is written into page.json.
  2. Sidebar shows the found number when the page declares none, titled "matched by MPN via Component Ocean" so provenance is visible.
  3. Page JSON exposes component.distributor_links_found, so Cloud Library exports and the Altium/KiCad import params can carry Mouser and DigiKey numbers.
  4. Filling happens on the page's own stock lookups (no extra CO rounds). No crawl of CO for the back catalog.

Asks (CO side), if you agree

  • A Mouser part number on the part record (mo_pn or whatever you name it), next to mo_stock / mo_price, so the wiki can show it like the DigiKey one.
  • For the basic-parts set (~138 MPNs) and later the rest of adom's hardware pages: a bulk form of /api/part (the enrich endpoint?) we can call once, instead of 20k single rounds against the 300/day budget.

If CO already keeps a per-MPN vendor-id record the wiki could read directly, say so and we will read that instead of storing our own copy.

6 Replies

Ray · 22d ago

Mostly in line, but a few things here are already done on the CO side, so the wiki half can get smaller.

  • Mouser number: CO already returns it. /api/part/<MPN> has mouser_pn and digikey_pn at the top level and on canonical (live since 09-22). For M95256-WMN6TP that's 511-M95256-WMN6TP / 497-8691-2-ND. The mo_* fields are stock/price only, which is probably why it looked missing.
  • Why the page doesn't show it: that's the wiki's CO lookup, which hard-codes the Mouser number to null and only renders declared numbers. git-wiki PR #289 (https://github.com/adom-inc/git-wiki/pull/289) fixes exactly that and has been open since 09-22. Can you start from it rather than rebuild it?
  • Bulk: POST /api/enrich (≤50 MPNs) now returns mouser_pn/digikey_pn per row too, as of today. The ~138 basic parts are 3 calls. CO already tracks that set as adom_basic.
  • Budget: app class is 1,500/day, not 300. /api/assign-pns has its own 6,000/day backfill class if you ever need to learn numbers CO doesn't have yet.
  • Per-MPN record: yes, CO keeps one. It holds Mouser/DigiKey numbers for ~11k MPNs from the factory backfill, and misses are stored for 30 days. So I'd rather the wiki read CO than keep its own component_vendor_ids copy that can drift. A short cache is fine.

Everything else sounds right to me: declared numbers win, nothing written into page.json, the "matched by MPN via Component Ocean" label, and distributor_links_found for exports.

Colby Knox · 21d ago

Thanks, that shrinks it to what you said. Done on main (staging now, prod with the next tag):

  • Your PR #289 is merged as-is (18b7867, credited), on top of the sidebar changes from last week: coLookup reads mouser_pn and digikey_pn, a number the page does not declare but CO matched for the exact MPN renders in its row, declared numbers win, an explicit false stays.
  • The learned number is marked on the page (title: matched by MPN via Component Ocean, not declared by the page).
  • The page API now carries metadata.distributor_links_found ({mouser, digikey, lcsc}) beside the declared links, read from the cached stock row, so exports and the CLI can use them. No wiki-side table: CO is the record, the stock row is the short cache.
  • Budget numbers updated in my notes (1,500/day app class; /api/enrich for the basic set when we want to warm it).

Closing when it is on prod.

Colby Knox · 21d ago

On prod (git-wiki a71c750). Pages show CO's numbers as their cached stock rows refresh (24 h TTL, or Refresh on the page); the API field distributor_links_found is live now.

Colby Knox · 21d ago

@ray one follow-up from a real page this morning: adom/mcp6002drg (HANSCHIP MCP6002DRG, an LCSC-only part) shows Mouser and DigiKey as "no data yet". CO's record for it has the LCSC number and JLC stock, but mouser_pn / digikey_pn are null and mo_fetched_at / dk_fetched_at are null too, so from the outside "never tried" and "tried, nobody sells it" look the same, and the wiki keeps saying "no data yet" forever.

Two small asks on the CO side, either one closes it:

  1. When /api/part is asked for an MPN with no vendor numbers, queue it for /api/assign-pns (your backfill class), so the next ask has either a number or a recorded miss.
  2. Put that miss in the record: e.g. mouser_pn_checked_at / digikey_pn_checked_at (or a not_listed flag) once assign-pns has looked. The wiki will then print "not listed at Mouser" instead of "no data yet", which is the honest state for a HANSCHIP part.

Nothing needed from the wiki until the record carries it; the render is a one-line change on our side.

Ray · 20d ago

Both done, live on CO now (adom-inc/component-ocean 9e0ff28).

/api/part now returns pn_status per vendor, so "never asked" and "not sold there" no longer look the same:

"pn_status": {
  "mouser":  { "state": "not_sold", "checked_at": "2026-09-24T01:48:46Z" },
  "digikey": { "state": "not_sold", "checked_at": "2026-09-24T01:48:46Z" }
}

state is one of known (the number is on record), not_sold (asked within the last 30 days, no exact match; checked_at says when), queued (never asked, a lookup is now queued), or unchecked (never asked and the queue is full or today's budget is spent).

And an MPN that comes in without a number and without a recent miss is queued automatically. A background worker asks one part every 2 s on the backfill budget, so the next ask has a number or a recorded miss.

Checked against real parts: MCP6002DRG (your example) comes back not_sold for both, checked Sep 24, so that page can say "not sold at Mouser/DigiKey" instead of "no data yet". AMS1117-3.3-XIN, never asked before, came back queued and was not_sold with today's timestamp 15 s later.

Colby Knox · 20d ago

Wiki half of pn_status is on prod (git-wiki 1cf3afc): a not_sold verdict renders as a muted "not sold here" row with the check date on hover; queued and unchecked stay "no data yet" and are asked again within 30 minutes, or immediately when a person clicks Refresh (next tag). Thanks for the fast turnaround.

Log in to reply.