Adds scripts/import_from_excel.py that reads Cantaloupe .xlsx exports
and imports missing machines into the canteen-asset-tracker DB.
- Dry-run by default, --write to commit, --prod for production DB
- Maps all 62 spreadsheet columns to assets table schema
- Stores full raw row as JSON in seed_data table
- Backs up DB before import
All GPS from MSFS account addresses and Cantaloupe seed data removed.
Only 5 authentic app check-in GPS entries remain.
Reverts the bulk restore from earlier commit (gps restore was address-based).
- 221 GPS entries restored via serial_number match from pre-MSFS backup
- 5,730 GPS entries restored via MSFS account address data
- Coverage improved from 1.6% (124) to 80.4% (6,075) of 7,560 assets
- Remaining 1,485 have no GPS in MSFS account records
- Auto-save photo_path to matched assets when photo uploaded via /api/ocr
- Auto-extract and save serial_number from OCR text to blank-serial matched assets
- Add _extract_serial_from_text helper for serial number pattern matching
- Create scripts/backfill_vision_photos.py for batch-processing unlinked photos
- Add docs/OCR_PIPELINE.md documenting the full OCR/vision pipeline
- Fix test DB schema: add connect_id, equipment_id, barcode, customer_name
- Fix OCR test assertions to match actual endpoint behavior
- Scanned all 15 photos in uploads/photos/ via vision + Tesseract OCR
- Matched keurig_label.jpg → Asset #5144 (machine_id 636671)
- Updated Asset #5144 photo_path in assets.db
- Created scripts/crossref_photos.py for reusable batch matching
- Reported unmatched IDs for coca_cola_label.jpg and telemetry_device.jpg
- Generated crossref_report.md with full findings
- normalize_identifier() strips dots/dashes/prefixes, keeps alphanumeric
- find_asset_by_normalized_id() searches serial_number, connect_id,
equipment_id, barcode with normalized comparison
- /api/ocr now returns matched_assets in addition to legacy machine_id
- New /api/match-text endpoint for client-side text matching
- scripts/match_label_photo.py CLI tool for OCR + DB matching
- Vision model fixed (mimo-v2-omni at opencode.ai, was using
truncated placeholder key)
- 1,606 more assets now get company from branch/territory name
(e.g. 'Canteen Corp/Orlando, FL') when the connect_id exists
in extraction DB but has no linked account name
- Coverage: 7,349/7,488 (98.1%) have company + customer_name
- Only 139 remain empty (4 prefixes not in branch cache)
- Updated AGENTS.md with data population docs
- New script: scripts/populate_asset_company_place.py maps connect_id →
account name (company/customer_name) + city (place) + address via
extraction DB (msdyn_customerasset + account join)
- 5,743/7,488 assets now have company + customer_name populated
- 5,647/7,488 assets now have place (city) populated
- Fix: SELECT COALESCE(c.name, a.customer_name) so stored customer_name
isn't overridden to NULL when customer_id FK is missing
- Bump SW v4→v5, version v3.1→v3.2 to force cache refresh