Fix label scanner: full field mapping, vision follow-up lookup, SDS/TDS extraction

- LookupByUrlAsync now maps all identity + spec fields from Claude response
  (manufacturer, SKU, colorName, description, sdsUrl, tdsUrl, unitCostPerLb, etc.)
  Previously only augmenting fields were mapped; Columbia QR path left 80% blank
- Vision scan follow-up: after ScanLabelAsync reads label text, automatically run
  LookupAsync using the extracted manufacturer + color/SKU to fill SDS/TDS URLs,
  product page, image, description, and any specs not printed on the bag;
  label values (cure schedule, SKU) remain authoritative and are never overwritten
- SDS/TDS URL extraction: added ExtractDocumentLinks() that scans anchor tags in
  raw HTML before tag-stripping, injects found URLs as [Structured Data] lines so
  Claude can read and echo them back in the JSON response; previously all hrefs
  were lost with the HTML stripping
- Added SdsUrl/TdsUrl to InventoryAiLookupResult, Claude system prompt JSON schema,
  LookupAsync mapping, and ScanLabel response (catalog match ?? aiResult fallback)
- SDS/TDS now also stored on auto-contributed catalog entries
- jsQR inversionAttempts: 'dontInvert' → 'attemptBoth' for better QR detection
  under varying label contrast and lighting conditions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-03 18:22:53 -04:00
parent 1fc79b77fe
commit f881b7dd53
4 changed files with 135 additions and 18 deletions
@@ -104,7 +104,7 @@
ctx.drawImage(videoEl, 0, 0);
const imageData = ctx.getImageData(0, 0, canvasEl.width, canvasEl.height);
const code = window.jsQR(imageData.data, imageData.width, imageData.height, {
inversionAttempts: 'dontInvert'
inversionAttempts: 'attemptBoth'
});
if (code && code.data) {