Files
shawn 2bdcfe0bae feat: branch fallback for assets without account linkage
- 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
2026-05-29 07:51:02 -04:00

96 lines
3.5 KiB
Markdown

# 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
```bash
# 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.py` contains routes, DB models, auth, OCR, and geolocation
- **OCR:** Extracts last 5 digits from `XXXXX-XXXXXX` Connect 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.sh` generates self-signed cert, backs up DB, starts uvicorn
- **No systemd** — runs via `nohup` from 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`)