Files
canteen-asset-tracker/PROJECT.md
T
shawn 9a1a5d9caa docs: add admin.canteen.ourpad.casa proxy config to PROJECT.md
NPMPlus proxy ID 20, cert ID 21, backend 192.168.0.127:8901
Cloudflare DNS A record grey cloud, Let's Encrypt SSL

Closes gitea issue #26
2026-05-21 17:18:21 -04:00

140 lines
5.8 KiB
Markdown

# Canteen Asset Tracker — Project Structure
Two projects, one API contract.
## Repositories
```
~/projects/canteen-asset-tracker/ ← Web app (Python/FastAPI backend + SPA frontend)
~/projects/canteen-asset-tracker-android/ ← Android app (Kotlin, Jetpack Compose)
```
## Web App (`canteen-asset-tracker`)
```
canteen-asset-tracker/
├── server.py FastAPI backend — all 78 API routes + DB logic
├── 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 (276 KB, self-contained)
├── tests/ pytest test suite (319 tests)
├── uploads/ User-uploaded photos/icons
├── 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)
- **Admin URL:** https://admin.canteen.ourpad.casa (NPMPlus proxy ID 20, same backend :8901 — admin user login)
- **Frontend:** Single HTML file — no build step, no npm. All JS/CSS/HTML in one file (~284KB).
- **Backend:** FastAPI with SQLite (WAL mode). Auth via Bearer tokens. OCR via Tesseract.
- **Tests:** pytest test suite + Playwright E2E browser tests.
## 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
```bash
# 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)
- **OCR fix** — Now extracts only the last 5 digits from Connect ID (e.g., `05912-095330``95330`). 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.
- **Admin password** — Updated to `Brett85!@`.