2bdcfe0bae
- 1,606 more assets now get company from branch/territory name (e.g. 'Canteen Corp/Orlando, FL') when the connect_id exists in extraction DB but has no linked account name - Coverage: 7,349/7,488 (98.1%) have company + customer_name - Only 139 remain empty (4 prefixes not in branch cache) - Updated AGENTS.md with data population docs
3.5 KiB
3.5 KiB
Canteen Asset Tracker
Mobile-friendly webapp for tracking physical assets with barcode scanning, OCR sticker reading, and GPS check-ins. The main technician-facing application.
...
Company & Place Data
Asset company, customer_name, and place fields are populated from the MSFS Dynamics 365 extraction DB. The migration script scripts/populate_asset_company_place.py maps each asset's connect_id → msdyn_customerasset → account table to get:
- company = account name (e.g. "Jeremy B - 1960 Broadway")
- place = city name (e.g. "Orlando")
- customer_name = account name (same as company, for search/filter)
5,743/7,488 assets (~77%) have company data; remaining 1,745 have connect_ids with no account linkage in the extraction DB.
Stack
- Python 3.11+, FastAPI, uvicorn
- SQLite (WAL mode, foreign keys)
- pytesseract — OCR for ConnectID stickers
- Pillow, piexif — image processing
- Frontend: vanilla HTML/CSS/JS (~200KB SPA), Leaflet maps, ZXing barcode scanner
- Tests: pytest
Project Structure
server.py # ~2.5K lines — ALL backend routes, DB, auth, OCR in one file
openapi.yaml # Shared API contract (source of truth for frontend)
requirements.txt
static/
index.html # SPA frontend (~200KB, no build step)
sw.js # Service worker for offline support
app-release.apk # Companion Android APK
docs/
ADMIN_GUIDE.md # Admin operations guide
USER_GUIDE.md # End-user operations
FEATURES.md # Feature catalog
images/ # Screenshots for docs
scripts/ # Data migration and helper scripts
PROJECT.md # v3 project structure doc
TEST_PLAN.md # Test plan
TEST_PLAN_MAP.md # Map test plan
How to Run
# Production (generates self-signed TLS cert, auto-installs deps, backs up DB)
./start.sh
# Quick restart
./restart_server.sh
Key Architecture
- Single-file backend —
server.pycontains routes, DB models, auth, OCR, and geolocation - OCR: Extracts last 5 digits from
XXXXX-XXXXXXConnect ID sticker format via Tesseract - Auth: Bearer token system, role-based (technician + admin)
- DB:
assets.db— SQLite with WAL mode, foreign keys enabled - Frontend: Pure vanilla JS SPA — no build step, no npm dependencies
Production
- URL: https://canteen.ourpad.casa
- Port: 8901 (HTTPS, self-signed cert → NPMPlus reverse proxy)
- Startup:
start.shgenerates self-signed cert, backs up DB, starts uvicorn - No systemd — runs via
nohupfrom start/restart scripts
Environment Variables
| Var | Description |
|---|---|
| CANTEEN_DB_PATH | Path to assets.db (default: ./assets.db) |
Related Projects
| Project | What it does |
|---|---|
canteen-admin-server |
Admin CRUD API, shares same SQLite DB |
canteen-seed-import |
Seed data import from Cantaloupe CSVs |
exif-test |
EXIF/OCR validation against this DB |
cantaloupe-downloader |
CLI to export machine data from Cantaloupe |
Pitfalls
- Single-file backend — server.py is ~2.5K lines; routes, DB, and OCR all in one file
- DB shared across canteen-admin-server, seed-import, exif-test — schema changes must be coordinated
- HTTPS — start.sh generates self-signed cert every restart; ports 8901 (production) vs 8904 (dev)
- OCR requires Tesseract installed system-wide (
apt install tesseract-ocr)