Closed bug report

Parts snapshot: is_basic is false for JLCPCB basic parts (C25744, C26083, ...), stock stale

John Lauer · 16d ago ·closed by John Lauer

The parts snapshot's is_basic (and stock) are stale

Ordering a 12 V to 5 V buck board from JLCPCB (2026-10-05), I used adom-jlcpcb search / adom-parts-search to find JLCPCB basic parts (no $3 per-type extended fee). The snapshot marked every part is_basic: false / "flags": ["extended"], including parts JLCPCB's live site lists as Basic:

LCSC MPN snapshot jlcpcb.com/partdetail (live, 2026-10-05)
C25744 0402WGF1002TCE (10k) is_basic false, stock 1,256,270 Basic, stock 21,539,575
C26083 0402WGF1004TCE (1M) extended Basic
C25879 0402WGF2201TCE (2.2k) extended Basic
C14663 CC0603KRX7R9BB104 (100nF) extended Basic
C45783 CL21A226MAQNNNE (22uF) extended Basic

JLCPCB's own BOM matcher agreed with the live pages (Lib Type = Basic for all five).

Effect: an AI searching for basic parts gets none, falls back to checking candidates one page at a time, and misses basic options entirely (it took the live site's "Parts Type: Basic" filter to find them). On this board that was about $15 of avoidable fees on a 2-board prototype.

Ask:

  1. Refresh is_basic / is_preferred (and stock) from JLCPCB, and stamp the snapshot date in every response so a caller can tell how fresh it is.
  2. Add a basic-only filter to search (--basic, libraryType=basic), passed through adom-parts-search too.
  3. Optionally a part <LCSC> verb that returns the live library type for one part.

Repro: adom-jlcpcb search C25744 → "is_basic": false; https://jlcpcb.com/partdetail/C25744 → Basic.

1 Reply

John Lauer · 16d ago ·edited

Fixed, and live. You were right on both counts, and each had its own silent cause.

1. is_basic was false for every part in the catalogue, all 634,264 of them

Two mistakes, neither of which ever raised an error:

  • The flag came from the wrong field. Our build ran CDFER's generate-database.py, which sets basic by matching a scraped CSV. That CSV stopped matching: every nightly run since 2026-08-26 printed Basic Parts Corrected: 0 into a log nobody reads. Upstream's own field, library_type (base / expand), was correct for all five of your parts the whole time. basic now derives from it.
  • Every stock number was undated. The adapter ran an integer unix timestamp through strftime('%s', ...), which returns NULL, so last_update was 0 on every row. Nothing could tell you a stock figure was from June.

Your five parts, from the live service now:

LCSC MPN is_basic stock as of
C25744 0402WGF1002TCE true 21,529,252 2026-10-05
C26083 0402WGF1004TCE true 2,465,043 2026-10-05
C25879 0402WGF2201TCE true 2,192,991 2026-10-05
C14663 CC0603KRX7R9BB104 true 57,456,859 2026-10-05
C45783 CL21A226MAQNNNE true 3,965,740 2026-10-05

(Your report had C25744 at 1,256,270 from our snapshot against 21,539,575 on the live site. We now read 21,529,252, straight from JLCPCB.)

2. Stock: dated per part, and the Basic set refreshed from JLCPCB nightly

The catalogue comes from a public crawl that re-reads JLCPCB over months, so one part can be a day old and the next a hundred days old. One freshness number per snapshot was never honest enough:

  • Every part now carries stock_as_of and stock_age_days; every response carries a snapshot block with the build time.
  • JLCPCB's entire Basic library is 351 parts, which their own endpoint will list. Since that set is what decides the bill, it is now refreshed straight from JLCPCB nightly at 04:30, in four requests. 350 of the 351 refreshed just now in 9 s. The one we cannot flag is C25804, which is not in the upstream catalogue at all.

3. A basic-only filter, end to end

is_basic existed on the API but was filtering the fetched page rather than the search. Basic is 351 parts out of 634k, so it almost always ranks below the page: the filter saw none and answered "none".

$ adom-jlcpcb search "0402 10k resistor" --basic
C25744  0402WGF1002TCE  21,529,252 in stock, as of 2026-10-05

$ adom-parts-search search "0402 10k resistor" --basic
Mouser: 3 hit(s) | DigiKey: 0 | JLCPCB: 1 hit(s) -> 0402WGF1002TCE

The unfiltered search still returns the two Extended 10k parts it always did, so this is the filter working rather than a reordering. --basic and --preferred are on search, category-search and list, and on adom-parts-search (where it narrows the JLCPCB column only, since Mouser and DigiKey have no equivalent). The API accepts is_basic, basic, libraryType=basic and library_type=base, because guessing which spelling we picked is not the caller's job.

4. A live single-part lookup

adom-jlcpcb part <LCSC or MPN> reads one part from JLCPCB directly (their public parts endpoint, no key, no quota), says when our snapshot disagrees, and falls back to the snapshot if JLCPCB cannot be reached. It is never used to enrich a search, because that would be one request per result on someone else's service.

$ adom-jlcpcb part C25744
OK: JLCPCB now: 0402WGF1002TCE BASIC, 21,529,252 in stock
differs: stock: snapshot 1,256,270 (as of 2026-06-23), JLCPCB 21,529,252 now

--offline answers from the snapshot alone. SKILL.md had documented this verb, including MPN lookups, before it existed; it exists now and takes both.

Shipped

adom-jlcpcb 1.0.9 and adom-parts-search 2.0.17 are published, the service is deployed, the 13-test smoke suite passes, and the live snapshot was backfilled in place rather than waiting for tonight's build.

What is still imperfect: parts outside the Basic set still carry whatever stock date upstream last gave them, which today can be ~100 days. The fix for a specific part is adom-jlcpcb part, which asks JLCPCB. Refreshing all 634k live is not something I will do to their service; if Extended stock accuracy starts costing real money, the honest next step is a licensed data source, and that is worth a separate conversation.

Log in to reply.