Adds a new Cleanup page in the admin Dashboard for reviewing
and sanitizing asset records.
Features:
- Filter by Company, Place/City, or Make with live counts
- Inline edit for make, model, building, floor on each asset
- Bulk edit bar: set any field for ALL matching assets at once
- Auto-generates names in '<make> <model> @ <company> - <Building> <Floor>' format
- Paginated results (50/page) with prev/next navigation
- Backend: POST /api/assets/batch-update for efficient batch updates
- Backend: company/place/make filter params on GET /api/assets
- Added Remember Me checkbox to login form with 30-day session expiry
- Sessions default to 1 day; when remember_me=true, expire in 30 days
- User info stored in localStorage (persistent) vs sessionStorage (per-tab)
- initAuth() checks localStorage first, then sessionStorage for user info
- Backend: new /api/admin/workorders/by-asset endpoint for
work orders linked to a specific asset name
- Backend: enhanced WO search to also match by
msdyn_customerasset!name and msdyn_serviceaccount!name
- Frontend: added 🔧 column to asset table linking to
work orders tab pre-filtered by asset name
- Frontend: added showAssetWorkOrders() function
- Frontend: made asset name in WO detail modal clickable
(navigates to asset search)
Closes#21
- Added validate_roles() and roles_contain() helpers for comma-separated roles
- Updated create_user/update_user to accept role combinations (e.g. 'admin,technician')
- Changed all exact role queries (='technician', IN('technician','admin')) to LIKE
- Replaced single <select> with checkboxes in add/edit user modals
- Added renderRoleBadges() to display multiple role badges per user
- Added checkbox-group/checkbox-label CSS styles
- Updated tech-photo-upload technician query to use LIKE
- Updated db reset auth check to use roles_contain()
- Set shawn's role to 'admin,technician'
- Cleaned up unused imports (hashlib, io, etc.)
Applies to canteen-admin-server, canteen-admin-server-dev, and tech-photo-upload
- Add heuristic entries: dex_report_date, deployed, pulled_date
- Include in COMPARE_FIELDS for diff detection
- Add to approve_batch() UPDATE field_map and INSERT statement
- Add v4 DB migration for three new TEXT columns
- Datetime serialization already handled by parse_excel()
Kanban: t_3bef3c9c
- /api/assets/search must be registered before /api/assets/{asset_id}
to prevent FastAPI path param from catching 'search' as an asset_id.
Returning a 422 with array detail caused frontend to show [object Object].
- Improve error message extraction in clearAssetGps catch block.
- DELETE /api/assets/{id}/gps: clears lat/lng to NULL
- GET /api/assets/{id}: asset lookup by ID
- GET /api/assets/search?machine_id=: asset lookup by machine ID
- Export & Admin page: Clear Asset GPS card with lookup + confirmation
- Tests: 204 success + 404 not found
Same issue as canteen-asset-tracker — hardcoded category set was
{Furniture, Appliances, Utensils, Equipment, Other}, missing all
vending-machine categories (Bev, Snack, GF Bev, GF Food, etc.).
- admin_server.py: _load_categories() from DB at startup
- cantaloupe_sync.py: reads from categories table instead of
hardcoded set (was silently downgrading GF Bev→Other on sync!)
The /api/auth/me endpoint was never added after the admin server was
split from the main server. Without it, auth tokens couldn't be validated
against the admin server — the SPA catch-all would serve the frontend instead.
The catch-all @app.get('/{full_path:path}') was defined before API routes,
causing GET requests for /api/* endpoints to be intercepted and served
the admin SPA index.html instead of the actual API response. Moving
the catch-all to after all API routes ensures proper route resolution.
- New cantaloupe_sync.py module with complete pipeline
- Heuristic Excel column mapping (20+ keyword patterns)
- Diff engine: detects new/changed/removed/unchanged assets
- 5 API endpoints: sync, list batches, view batch, approve, reject
- cantaloupe_sync_batches table with status workflow
- Admin server port changed to 8090
- openpyxl added to requirements.txt