The test suite login as 'admin'/'changeme' but only 'shawn' was seeded.
Adding the admin user with SHA256('changeme') hash lets all 15 Playwright
tests reach the actual app pages instead of failing at login.
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