- New disney_group query param on /api/assets (park, resort, office, springs, other) - Both list and map filter dropdowns show group options above individual parks - Backend uses IN queries for grouped park values - Map view handles groups via client-side PARK_GROUP_MAP Closes #69
Canteen Asset Geolocation Tool
Mobile-friendly webapp for tracking physical assets with barcode scanning, OCR sticker reading, and GPS check-ins. Built with FastAPI + SQLite + vanilla JS.
Quick Start
cd ~/projects/canteen-asset-tracker
./start.sh
Then open https://canteen.ourpad.casa on your phone. HTTPS via NPMPlus reverse proxy → backend on :8901.
Default Login
The server seeds a default admin account on first startup:
| Field | Value |
|---|---|
| Username | admin |
| Password | Brett85!@ |
Change this password on first login via the Settings → Users tab.
Features
- Add Asset tab — Three entry modes:
- Barcode — Live camera scanning via ZXing. Uses 1D-only format hints (Code 128, Code 39, EAN/UPC, ITF, Codabar) with
decodeFromVideoDevicefor fast, accurate detection. Auto-looks up assets or offers to create new ones. - OCR — Snap a photo of the Connect ID sticker. Extracts the last 5 digits from the
XXXXX-XXXXXXpattern (e.g.,05912-095330→95330). - Manual — Full form with photo capture, customer/location assignment, keys, and badges.
- Barcode — Live camera scanning via ZXing. Uses 1D-only format hints (Code 128, Code 39, EAN/UPC, ITF, Codabar) with
- Auto check-in — Every new asset (from any entry mode) gets an automatic GPS check-in on creation. If GPS isn't available yet, the manual check-in button remains.
- Assets tab — Browse, search, filter, create, edit, delete assets. View check-in history per asset with map.
- Dashboard tab — Stats: total assets, check-ins, breakdown by category and status. CSV export.
- Activity tab — Full activity feed with user filtering.
- Map tab — View all assets and check-ins on an interactive Leaflet map.
- GPS auto-acquired on page load for location-tagged check-ins.
Tech Stack
| Layer | Tech |
|---|---|
| Backend | FastAPI + SQLite (WAL mode) |
| Frontend | Vanilla HTML/CSS/JS (single file, ~280KB) |
| Scanner | @zxing/library 0.20.0 (CDN) |
| OCR | Tesseract (pytesseract + PIL) |
| Maps | Leaflet + Leaflet.Draw + Leaflet.Heat |
| TLS | Self-signed cert, port 8901, proxied via NPMPlus |
API
Base URL: https://canteen.ourpad.casa
Auth: Bearer token (obtained via /api/auth/login)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/login |
Login, returns token |
| GET | /api/auth/me |
Current user info |
| POST | /api/assets |
Create asset |
| GET | /api/assets |
List assets (filterable) |
| GET | /api/assets/search?machine_id= |
Lookup by machine ID |
| GET | /api/assets/{id} |
Get single asset |
| PUT | /api/assets/{id} |
Update asset |
| DELETE | /api/assets/{id} |
Delete asset + check-ins |
| POST | /api/checkins |
Create check-in (GPS + photo) |
| GET | /api/checkins |
List check-ins (filterable) |
| POST | /api/ocr |
OCR sticker image → machine_id |
| GET | /api/stats |
Dashboard stats |
| GET | /api/export/assets |
Export assets CSV |
| GET | /api/export/checkins |
Export check-ins CSV |
| GET | /api/activity |
Activity feed |
| * | /api/settings/{entity} |
Dynamic CRUD for 6 entity types |
| * | /api/customers |
Customer CRUD |
| * | /api/locations |
Location CRUD + rooms |
| * | /api/users |
User CRUD |
| * | /api/geofences |
Geofence CRUD + user assignment |
| * | /api/visits |
Visit CRUD + stats |
| * | /api/proximity |
Find assets near GPS point |
| POST | /api/upload/photo |
Upload asset photo |
| POST | /api/upload/icon |
Upload icon |
OCR endpoint
POST /api/ocr — Upload a sticker image (multipart form, field file). Extracts machine ID from XXXXX-XXXXXX Connect ID pattern, returning only the last 5 digits.
{
"machine_id": "95330",
"raw_text": "CONNECT ...",
"raw_match": "05912-095330",
"confidence": "high"
}
Asset fields
machine_id (unique, required), name (required), serial_number, description, category (Furniture/Appliances/Utensils & Serveware/Equipment/Other), status (active/maintenance/retired), make, model, address, building_name, building_number, floor, room, trailer_number, walking_directions, map_link, parking_location, photo_path, customer_id, location_id, assigned_to, created_at, updated_at.
Check-in fields
asset_id (required), latitude, longitude, accuracy, photo_path, notes, created_at.
Environment Variables
| Variable | Default | Description |
|---|---|---|
CANTEEN_PORT |
8901 |
Listen port |
CANTEEN_DB_PATH |
./assets.db |
SQLite database path |
CANTEEN_WIPE_DB |
(empty) | Set to 1 to clear DB |
CANTEEN_SKIP_AUTH |
(empty) | Set to 1 for tests |
Running Tests
pip install -r requirements.txt
python -m pytest tests/ -v
Project Structure
canteen-asset-tracker/
├── server.py # FastAPI app (all routes, DB, auth, OCR)
├── openapi.yaml # API contract (source of truth)
├── start.sh # One-command startup with cert gen
├── static/
│ └── index.html # SPA frontend (vanilla JS, self-contained)
├── tests/ # pytest test suite
├── docs/ # Documentation
├── uploads/ # Photo/OCR storage (gitignored)
├── cert.pem # Self-signed TLS cert (auto-generated)
├── key.pem # TLS private key (auto-generated)
├── requirements.txt # Python deps
├── PROJECT.md # Detailed project structure
└── README.md