- Created SVG sprite with 49 game-icons symbols (58KB)
- Added .gi CSS class for icon sizing/fill
- Replaced 77 emoji in static HTML with <use href='#gi-{name}'>
- Skip <option> elements (can't render SVG there)
- Added JS gi() helper for 33 dynamic icon assignments
- Replaced 📍🔒🔓📷📋✅↕️⚠ in JS-driven content
- Zero network requests, zero console errors
- Pairs with existing CATEGORY_MAP game-icons SVGs
Add a GPS map editor card at the top of asset details, allowing users to
manually set an asset's GPS coordinates via an interactive Leaflet map.
- GPS card with Leaflet map and draggable marker
- 🔒 Lock/unlock toggle (locked by default when GPS exists)
- 💾 Save GPS button (visible only when unlocked)
- Saves via PUT /api/assets/{id} with lat/lng
- Click on map or drag marker to set position
- Fallback to Orlando coords (28.5383, -81.3792) when no GPS
- Auto-refresh detail view after save
Closes#61
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
- Cleaned CATEGORY_MAP: removed dead entries (Furniture, GF Bev,
Snack/bev, Snack/food), fixed duplicate 'Food' key, proper
distinct icons for all 6 real categories
- Added categoryInfo() helper: 🥤/🍿/🍔/🔧/🔌/📦 for known cats,
❓ (red) for unmapped categories, 📦 for null
- Updated all render sites (list, map pins, map list, detail view,
scan result, OCR result) to use categoryInfo()
- Added category icons to detail view and scan/OCR result headers
- Synced categories DB table: added Equipment/Appliances with icons,
removed unused Unknown
- Updated seed data in both server.py and admin_server.py to match
real asset categories
- Added category_health to /api/stats with unmapped category detection
- Added Category Health card to admin dashboard (shown only when
unmapped categories exist)
- Updated CSS backgrounds for all real categories + .cat-unmapped
- 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)
- Add QR_CODE, DATA_MATRIX, PDF_417, AZTEC to barcode scanner hints
so serial number stickers with 2D barcodes can be scanned
- Update /api/assets/search to also match connect_id so full
Connect IDs (e.g. VM-05912-0000068454) work when scanned
- Bump SW cache v5→v6, footer v3.2→v3.3
- 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
The detail view's Asset Details card was missing location fields
(place, building_name, building_number, floor, room, trailer_number)
that were visible in the list cards. Added them alongside Model
so building/floor info appears in the main card rather than only
in the collapsed Directions & Access section below.
- Add/Find tab: removed check-in card and add-asset form, now pure lookup
- OCR: stop camera after capture, added GPS capture at photo time
- OCR: increased timeout from 8s to 15s to reduce 500 errors
- Nav tab: added GPS prompt + asset search when navigating directly
- Route: include all 26 techs from bookableresource table (not just Shawn)
- Added import_seed.py — reads Machine List(8).xlsx, matches by Asset ID → machine_id
- 51 new columns on assets table (route, barcode, sales, contact info, etc.)
- seed_data table with full 62-field JSON per asset for detail enrichment
- Seed data card in frontend asset detail view
- GET /api/assets/{id} now returns result.seed and result.seed_imported_at
- GPS columns from Seed ignored per request
- 1,654 matched, 199 unmatched (Seed-only assets not in MSFS)
Refs #47
- Cleared all MSFS-derived (address-geocoded) GPS
- Only real field GPS (28 assets from photo EXIF) remains
- Documented backup locations and clean-slate process
Refs #46
OCR endpoint (/api/ocr) now auto-saves EXIF GPS from the photo
to the asset's latitude/longitude fields when they are blank,
so the first photo scan at a machine permanently records its location.
GET /api/assets/{id} now includes an 'msfs' block enriched from
the merged Dynamics 365 Field Service data (merged-assets.json)
loaded at server start (1,834 matched assets). Fields shown:
equipment_id, connect_id, compass_asset_number, manufacturer,
model_text, dex_model, install_date, software_version, etc.
Frontend updates:
- New 'Field Service Data' card in asset detail view when MSFS
data is available (manufacturer, Connect ID, install date, etc.)
- '📍 GPS saved to asset' confirmation shown after OCR auto-save
- AppState.ocrGpsSaved flag to track the auto-save event
Root cause: rpLoadTechs() and all other route planner API calls used
raw fetch() instead of the api() wrapper, so no Authorization header
was attached. Auth middleware returned 401, technician list never
loaded, users saw 'Select at least one technician'.
Fixed by replacing all 6 fetch('/api/...') calls in the route planner
with api('/api/...') and removing redundant .json() parsing (api()
returns parsed data directly).
Tested in browser: technician checkboxes populate, Load Today's Route
returns 3 optimized stops with 12.5km route, map renders correctly,
search tab queries return Disney WO results via auth.
Closes: #issue-to-be-created
- Removed onclick=openDrawer() from user badge
- Removed '⋯ More' bottom tab (also opened drawer)
- Header hamburger ☰ remains the single drawer trigger
- Removed startVisitTracking / stopVisitTracking functions
- Removed checkProximityToAssets and haversineM
- Removed logAutoVisit and all visit timer logic
- Removed visitTracker UI div on Map tab
- Removed GPS watchPosition call (was polling at ~1-5s intervals)
- Kept server-side /api/visits endpoints (used by heatmap) and one-shot GPS for scan check-in
Reason: GPS auto-tracker can't distinguish machines above/below each other
on different floors.
When a user scans a barcode that matches an existing asset:
- Redirect directly to the asset detail view (Assets tab)
- Auto-checkin still runs in background if GPS available
- Show a toast notification with the asset name
When scanning a barcode not in database:
- Switch back to Add Asset tab and show the create form
- Deferred status update survives async startScanning
No backend changes needed.
Closes#39