Files
canteen-asset-tracker/PROJECT.md
T
shawn ba6921eade t_4a71eab5: Strip admin UI from main index.html
- Replaced loadSettingsCache() with hardcoded seed data (categories, makes, keys, badges)
- Removed tabActivity lifecycle hook (activity log moved to admin app)
- Updated version to v3.0 + Admin Panel link in drawer footer
- Updated PROJECT.md with v3 project structure (3 repos, admin server docs)
- Removed backup files (.bak, .orig)
- Main index.html reduced from 7645 to 4228 lines
2026-05-21 17:47:22 -04:00

7.2 KiB

Canteen Asset Tracker — Project Structure (v3)

Three projects, shared DB.

Repositories

~/projects/canteen-asset-tracker/           ← Main app (technician-facing: scan, check-in, assets, map, nav)
~/projects/canteen-asset-tracker-android/   ← Android app (Kotlin, Jetpack Compose)
~/projects/canteen-admin-server/            ← Admin app (users, customers, settings, exports, activity)

Web App (canteen-asset-tracker)

canteen-asset-tracker/
├── server.py              FastAPI backend — core technician API routes (assets, checkins, visits, auth, OCR, upload)
├── openapi.yaml           **Shared API contract** — source of truth for both projects
├── assets.db              SQLite database (WAL mode, foreign keys on)
├── static/
│   └── index.html         Single-page frontend (technician UI: scan, assets, map, nav)
├── tests/                 pytest test suite
├── uploads/               User-uploaded photos
├── cert.pem / key.pem     Self-signed TLS certs
├── requirements.txt       Python deps (fastapi, uvicorn, pytesseract, pillow)
├── start.sh               Launch script (production)
└── smoke_test.sh          Smoke test suite
  • Port: 8901 (HTTPS)
  • URL: https://canteen.ourpad.casa (NPMPlus reverse proxy → backend :8901)
  • Frontend: Single HTML file — no build step, no npm (~200KB, technician-focused).
  • Backend: FastAPI with SQLite (WAL mode). Auth via Bearer tokens. OCR via Tesseract. EXIF GPS extraction via PIL.

Admin App (canteen-admin-server)

canteen-admin-server/
├── admin_server.py        FastAPI backend — admin-only API routes (users, customers, locations, rooms, settings, activity, stats, exports, geofences)
├── static/
│   └── index.html         Single-page admin frontend (settings, user mgmt, activity, reports)
├── requirements.txt       Python deps (fastapi, uvicorn)
└── run.sh                 Launch script (port 8900)

Admin functions separated into their own project:

  • Port: 8900
  • URL: https://admin.canteen.ourpad.casa (NPMPlus proxy → backend)
  • Shared DB: Uses same assets.db via CANTEEN_DB_PATH env var
  • Auth: Same login system as main app (admin role required for admin endpoints)
  • Frontend: Standalone SPA with Dashboard, Settings, Users, Customers/Locations, Activity Log, CSV Exports, DB Reset

Android App (canteen-asset-tracker-android)

canteen-asset-tracker-android/
├── app/
│   ├── src/main/java/com/canteen/assettracker/
│   │   ├── network/
│   │   │   └── RetrofitModule.kt   API client config (points to web app URL)
│   │   ├── ui/
│   │   │   ├── login/              Login screen + ViewModel
│   │   │   ├── dashboard/          Dashboard screen + ViewModel
│   │   │   └── settings/           Settings screen + ViewModel
│   │   └── location/
│   │       └── ProximityEngine.kt  GPS proximity logic
│   └── build/                      Build outputs (APK, test reports)
├── build.gradle.kts                Root build config
├── settings.gradle.kts
├── gradlew / gradlew.bat           Gradle wrapper
└── keystore.properties             Signing keys
  • Package: com.canteen.assettracker
  • API Base URL: https://canteen.ourpad.casa:8901/ (hardcoded in RetrofitModule.kt)
  • Tests: 3 ViewModel/engine test classes, all passing (debug + release)
  • Built APK: run ./gradlew assembleRelease

API Contract

openapi.yaml is the single source of truth. When you change the backend:

  1. Update server.py
  2. Update openapi.yaml to match
  3. Android team (or future-you) can see exactly what changed

The spec covers:

  • 48 named routes across assets, check-ins, customers, locations, rooms, users, auth, geofences, visits, activity, stats, exports, uploads, and OCR
  • 30 dynamic settings routes (/api/settings/{entity} for 6 entity types)
  • All request/response schemas
  • Query parameters and path parameters

Quick reference — main route groups

Group Routes
Auth login, me
Assets CRUD + search by machine ID
Check-ins CRUD (GPS + photo + notes)
Customers CRUD with contacts
Locations CRUD + child rooms
Rooms CRUD (nested under locations)
Users CRUD
Geofences CRUD + user assignment (service areas)
Visits CRUD + stats
Stats Dashboard aggregates
Exports Assets CSV, Check-ins CSV, Service Summary CSV
Uploads Icon + Photo upload
OCR Extract machine ID from sticker image
Settings Dynamic CRUD for 6 entity types
Proximity Find assets near GPS point
Activity Activity feed

Working with both projects

Adding a feature to BOTH web + Android

  1. Design the endpoint in openapi.yaml first
  2. Implement in server.py
  3. Run backend tests
  4. Implement Android client code + run Android tests

Adding a feature to web ONLY

  1. Add endpoint to server.py
  2. Update openapi.yaml
  3. Android app ignores the new endpoint — no changes needed

Adding a feature to Android ONLY

  1. Plan the endpoint in openapi.yaml (even if backend isn't ready)
  2. Build Android client against the planned contract
  3. Backend implements later

Running

# Web app
cd ~/projects/canteen-asset-tracker
./start.sh                          # production
# or: uvicorn server:app --reload   # development

# Tests
cd ~/projects/canteen-asset-tracker
python -m pytest tests/ -v

# Android
cd ~/projects/canteen-asset-tracker-android
./gradlew assembleRelease           # build APK
./gradlew test                      # run unit tests

Recent Changes (May 2026 — v3)

  • v3 admin separation — Admin functionality extracted to separate project ~/projects/canteen-admin-server/ (port 8900). Main server.py reduced from 3005→1946 lines by removing admin routes. Main index.html reduced from 7645→4228 lines by removing admin UI panels. Admin app live at https://admin.canteen.ourpad.casa.
  • EXIF GPS extraction/api/ocr and /api/upload/photo now extract GPS coordinates from image EXIF data server-side (PIL getexif()) and return {exif_gps: {lat, lng}} alongside results. Raw file bytes preserved — no re-compression, no EXIF stripping.
  • OCR fix — Now extracts only the last 5 digits from Connect ID (e.g., 05912-09533095330). Added raw_match field to response for debugging.
  • Barcode scanner fix — Switched from decodeFromVideoElement to decodeFromVideoDevice with 1D-only format hints (Code 128, Code 39, EAN/UPC, ITF, Codabar). Added TRY_HARDER hint and 50ms scan interval for fast, reliable detection.
  • Auto check-in — New assets automatically check in with GPS on creation (all three entry modes: barcode, OCR, manual). Best-effort: silently skips if GPS unavailable.
  • Service stability — Added NPMPlus reverse proxy. Service runs as background process on port 8901.