Commit Graph

17 Commits

Author SHA1 Message Date
shawn 78dbdfd5c5 EXIF round-trip: read before upload, re-embed server-side
- Client: exifr.parse() reads full EXIF before upload, sent as exif_data
- Server: piexif re-embeds EXIF into saved JPEG after upload
- Auto-extract GPS from picked gallery photos on selection
- Removed Google Photos button (needs OAuth, not feasible)
2026-05-21 21:29:55 -04:00
shawn 58f8b67b28 auth: full session-based auth with remember-me support
- Seed user: shawn / Brett85!@ (SHA-256)
- Sessions table with expires_at column
- login endpoint supports remember_me flag (30d vs 1d expiry)
- logout endpoint invalidates server-side token
- auth middleware + /api/auth/me check session expiry
- Frontend sends remember_me in login request body
- Frontend calls /api/auth/logout on client logout
- Migration function for existing databases
2026-05-21 20:17:21 -04:00
shawn 0824075048 t_68f4f6a2: Strip admin API routes from main server.py 2026-05-21 17:27:06 -04:00
shawn 7cf566ad6d t_2f17b1b4: Add EXIF GPS extraction to upload/photo and OCR endpoints
- _extract_gps_from_bytes helper reads GPSInfo IFD via PIL get_ifd()
- Converts DMS to decimal degrees, returns {lat, lng} or None
- /api/upload/photo: reads bytes first, extracts GPS before saving
- /api/ocr: extracts GPS from raw bytes before OCR processing
- exif_gps returned alongside path/machine_id in both endpoints
- Photos without EXIF GPS omit the exif_gps key entirely
- Raw file bytes preserved (no re-compression, no EXIF stripping)
2026-05-21 17:17:38 -04:00
shawn 09d83da4e2 server OCR: accept any file extension, detect format from bytes
- Removed extension whitelist — no more 'unsupported format' errors
- Falls back to .jpg temp file for unknown/no extension
- PIL detects actual image format from file bytes (handles DNG as TIFF)
- Android browsers often strip DNG extensions when picking from gallery
- Tested: works with .dng, .jpg, no extension, and .bogus
2026-05-21 15:05:39 -04:00
shawn 0cf5dddf83 DNG/RAW photo support for gallery upload
- Server: accept .dng in OCR endpoint (PIL opens as TIFF)
- Server: bump OCR size limit to 20MB (DNG files can be large)
- Client: gallery upload tries server OCR first (with 6s timeout),
  then falls back to client-side Tesseract.js — matches 📸 capture flow
- DNG photos now work with 'Pick from Gallery'
2026-05-21 14:51:57 -04:00
shawn 622996624a T4: Connect Label upload workflow — unified photo + OCR + GPS
- Added 'Connect' mode toggle on Add Asset tab with Camera/Gallery options
- processConnectLabelPhoto(file): parallel OCR + GPS extraction
- Shows results card with editable machine_id, lat/lng, map preview
- POST /api/connect-label endpoint with photo upload + GPS + reverse geocode
- Connect Label section in Assets list (localStorage-backed recent scans)
- Handles OCR failure (manual entry) and missing EXIF GPS gracefully
2026-05-21 11:50:09 -04:00
shawn 62016bae83 Revert all UX sweep changes (T5-T11, 16 commits)
This reverts all commits from 828fd5c..bc8cc99, undoing the entire
canteen-ux-sweep board changes: Dashboard Fixes, Map Improvements,
Modal System, Navigate fixes, Empty States, Search & Filter, Reports,
Navigate Route-Finding UI, T6 cleanup, Page Transitions, Skeleton Loading.

Restores codebase to pre-UX-sweep state at d844429.
2026-05-21 07:36:58 -04:00
shawn 88694e6b8e T6 Map Page Improvements: geolocation fallback, location coordinates, friendly error messages
- Improved geolocation error messages (maps error codes to friendly text: Location blocked, GPS unavailable, GPS timed out)
- Added location data to list_assets API (location_latitude, longitude, address, building_name, building_number, name) via LEFT JOIN
- Map pins now use location coordinates as direct fallback when asset lacks own lat/lng
- GeocodeAndPin now falls back to location address fields when asset address is empty
- All 96 map-related tests pass (66 API + 30 frontend)
2026-05-20 23:33:47 -04:00
shawn 51f9bcfacd fix: reports page — add asset lat/lng to /api/visits for map button, fix null field guard in form error handler 2026-05-20 22:58:50 -04:00
shawn 828fd5c482 T5 - Dashboard Fixes: active technicians, interactive bars, quick actions, caching
- Fix Active Technicians: query users WHERE role='technician' instead of counting from visit data
- Interactive bar charts: hover tooltips show label+count, click drills down to filtered asset list
- Quick action icons: coin for Assets, Sites, Check-in replaces CSV export buttons
- No visit data: suggestion card with 'Add a Check-in' button
- No manufacturer data: hide section entirely when empty
- 30-second TTL cache on both backend (/api/stats) and frontend (loadDashboard)
- Add dashboard cache module with time-based invalidation
2026-05-20 22:25:24 -04:00
shawn d7f2e07c68 feat: 6 UX improvements for field technicians
F1: Scan existing asset → auto check-in (handleBarcode now autoCheckins)
F2: Auto-generate address from GPS reverse geocode (Nominatim, all 3 modes)
F3: Larger camera viewport (3:4 aspect ratio, full-width)
F4: Building # already syncs to Address/Trailer field (existing)
F5: Parking location GPS button already exists (fillGpsParking)
F6: Navigation tool with route line on map (existing navigateToAsset)

Backend: Added GET /api/geocode endpoint for reverse geocoding
2026-05-20 18:01:39 -04:00
shawn b69bffe44a feat: auto check-in on barcode scan of existing assets
- handleBarcode() now calls autoCheckin() after finding asset via barcode
- showScannedAsset() no longer shows manual checkin card
- Replace 'Check In' button with 'Auto checked in' indicator
- Add CSS for sr-checkin-done span
2026-05-20 17:57:04 -04:00
shawn 02b3ba665e feat: oninput handler copies building # to trailer number
- Manual asset form: manBuildingNumber → manAddress (address/trailer field)
- Location form: locFormBldgNum → locFormTrailer
2026-05-20 17:55:00 -04:00
shawn fc0a3ee9be fix: auto-update asset lat/lng on check-in so map shows pins
Previously assets never had coordinates populated - only checkins did.
Now when a checkin is created with GPS data, the asset's latitude/longitude
fields are auto-updated. Also backfilled existing assets from their latest
checkin history. This fixes empty maps — loadAssetPins() filters by
a.latitude != null.
2026-05-20 15:43:43 -04:00
shawn b20998e8e3 fix: OCR last-5-digits extraction, barcode 1D-only scanning, auto-checkin on create
- OCR: Extract only last 5 digits from Connect ID (XXXXX-XXXXXX → last 5)
- Barcode: Switch to decodeFromVideoDevice with 1D-only format hints
  (Code 128/39/EAN/UPC/ITF/Codabar), TRY_HARDER, 50ms scan interval
- Auto check-in: New assets auto-checkin with GPS on creation via
  all three entry modes (barcode, OCR, manual)
- Tests: Updated e2e tests for login wait and API flow
2026-05-20 15:03:20 -04:00
shawn 7da3f28c6a Initial commit: Canteen Asset Geolocation Tool v2 2026-05-17 18:55:28 -04:00