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
- Add .ai-address and .ai-location CSS classes
- Increase .asset-item padding to 14px, align-items to flex-start
- Reduce .ai-name font to 14px, allow wrapping
- Render address line (📍 icon) when present
- Render floor · building · room location line when any field present
- Keep existing icon and meta line unchanged
- Add .filter-toggle.warn CSS styles (amber border/text with active bg)
- Add Data Health row with toggle button in filter panel HTML
- Add noDexFilterActive state variable and toggleNoDexFilter() function
- Wire no_dex_days=5 into API URL builder when toggle active
- Integrate into getActiveFilterCount, renderActiveFilterTags, removeFilter, clearAllFilters
- Extract from row[7] (Col 8), row[34] (Col 35), row[35] (Col 36)
- Handle datetime -> ISO conversion for date columns
- Include in UPDATE and INSERT statements
Kanban: t_3bef3c9c
- Add dex_report_date field to AssetCreate Pydantic model
- Include dex_report_date in _build_asset_insert columns/values
- Add test_list_assets_filter_no_dex_days test (11/11 pass)
- Magic Kingdom: accurate 60-point polygon from OSM way 297428432
- All parks: adjusted boundaries for better alignment
- Increased stroke weight (3px) and opacity for visibility
- Higher fill opacity (0.15)
- Polygons for Magic Kingdom, Epcot, Hollywood Studios, Animal Kingdom, Disney Springs
- Resort area outline (dashed) for Pop Century / Art of Animation
- Color-coded to match existing park badge colors
- Labels with park icons at polygon centers
- Toggle chip (🏰 Parks) in map controls to show/hide
- Outlines visible by default on map load
Replaced the Snack category emoji with an actual chips illustration
served from static/icons/chips.png. The icon renders in the asset
list category badges as a 28x28 object-fit:contain image within
the 42x42 circular badge.
- Added is_disney INTEGER DEFAULT 0 column to assets table
- Backfilled 996 Disney assets based on D- customer prefix
- Server: is_disney in AssetCreate/AssetUpdate models, INSERT/UPDATE
- Server: disney_filter query param now uses is_disney column (no JOIN needed)
- import_cantaloupe.py: sets is_disney=1 when customer starts with D-
- import_machines.py: sets is_disney=1 when customer starts with D-
- disney_classify.py: sets is_disney=1 when classifying
- Frontend: new Location Type dropdown with Disney/Non-Disney toggle
(replaces the __disney__/__non_disney__ park dropdown pseudo-options)
Backend:
- disney_filter query param on /api/assets (values: 'disney' | 'non_disney')
- Detects Disney by checking disney_park IS NOT NULL OR customer name LIKE 'D-%'
- Catches ESPN, Wide World of Sports, all Disney resorts, etc.
- Adds LEFT JOIN to customers table when disney_filter is active
Frontend:
- '🏰 Disney only' and '🏢 Non-Disney' options in Disney Park dropdown
- Active filter tag shows which is selected
- Works together with other dropdown filters
Backend:
- GET /api/customers — lists all customers for filter dropdown
- GET /api/locations?customer_id=X — cascading locations per customer
- GET /api/users — lists users for assigned_to filter
Frontend:
- Collapsible 'Filters' panel with Customer→Location cascade, Status, Assigned To
- Active filter tags showing what's currently filtering, removable individually
- 'Clear all filters' button to reset all at once
- Result count display ('X assets found')
- Better search placeholder showing searchable fields
- Filter count badge on the toggle button