From 45af1410735be9cd205847a380522811a118364b Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 20 May 2026 15:06:05 -0400 Subject: [PATCH] docs: update README and PROJECT.md with OCR, barcode, auto-checkin changes --- PROJECT.md | 16 +++++-- README.md | 136 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 95 insertions(+), 57 deletions(-) diff --git a/PROJECT.md b/PROJECT.md index 8590ee4..9cae958 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -27,10 +27,10 @@ canteen-asset-tracker/ ``` - **Port:** 8901 (HTTPS) -- **URL:** https://canteen.ourpad.casa:8901 -- **Frontend:** Single HTML file — no build step, no npm. All JS/CSS/HTML in one file. -- **Backend:** FastAPI with SQLite (WAL mode). 48 named routes + 30 dynamic settings routes. -- **Tests:** 319 backend tests passing. No frontend tests yet. +- **URL:** https://canteen.ourpad.casa (NPMPlus reverse proxy → backend :8901) +- **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`) @@ -128,3 +128,11 @@ 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!@`. diff --git a/README.md b/README.md index 223f2ff..594352e 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,100 @@ # Canteen Asset Geolocation Tool -Mobile-friendly webapp for tracking physical assets with barcode scanning and GPS check-ins. Built with FastAPI + SQLite + vanilla JS. +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 ```bash +cd ~/projects/canteen-asset-tracker ./start.sh ``` -Then open `https://:8901` on your phone. Accept the self-signed cert warning. +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 | `changeme` | +| Field | Value | +|----------|-------------| +| Username | `admin` | +| Password | `Brett85!@` | **Change this password on first login** via the Settings → Users tab. ## Features -- **Scan tab** — Barcode scanning via camera. Auto-looks up assets or offers to create new ones. -- **Assets tab** — Browse, search, filter, create, edit, delete assets. View check-in history per asset. +- **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 `decodeFromVideoDevice` for 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-XXXXXX` pattern (e.g., `05912-095330` → `95330`). + - **Manual** — Full form with photo capture, customer/location assignment, keys, and badges. +- **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 | -| Scanner | ZXing library (CDN) | -| TLS | Self-signed cert, port 8901 | +| 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://:8901` +Base URL: `https://canteen.ourpad.casa` -| Method | Endpoint | Description | -|--------|-------------------------------|------------------------------------| -| GET | `/health` | Health check | -| POST | `/api/assets` | Create asset | -| GET | `/api/assets` | List assets (filterable) | -| GET | `/api/assets/search?barcode=` | Lookup by barcode | -| 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 | -| GET | `/api/checkins` | List check-ins (filterable) | -| GET | `/api/stats` | Dashboard stats | -| GET | `/api/export/assets` | Export assets CSV | -| GET | `/api/export/checkins` | Export check-ins CSV | -| POST | `/api/geofences` | Create geofence (opt. `user_ids`) | -| GET | `/api/geofences` | List geofences (includes assigned users) | -| PUT | `/api/geofences/{id}` | Update geofence (+ reassign users) | -| DELETE | `/api/geofences/{id}` | Delete geofence | -| GET | `/api/users/{id}/geofences` | List geofences assigned to a user | -| GET | `/api/locations` | List locations | -| GET | `/api/locations/{id}` | Get location with rooms | -| GET | `/api/rooms` | List rooms | -| GET | `/api/activity` | Activity feed | +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. + +```json +{ + "machine_id": "95330", + "raw_text": "CONNECT ...", + "raw_match": "05912-095330", + "confidence": "high" +} +``` ### Asset fields -`barcode` (unique, required), `name` (required), `description`, `category` (Furniture/Appliances/Utensils & Serveware/Equipment/Other), `status` (active/maintenance/retired), `photo_path`, `created_at`, `updated_at`. +`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 @@ -75,11 +102,12 @@ Base URL: `https://:8901` ## 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 on start | +| 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 @@ -92,15 +120,17 @@ python -m pytest tests/ -v ``` canteen-asset-tracker/ -├── server.py # FastAPI app (all routes, DB, error handling) -├── start.sh # One-command startup with cert gen +├── 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 (3 tabs + scanner) -├── tests/ -│ └── test_server.py # 47 integration tests -├── uploads/ # Photo storage (gitignored) -├── cert.pem # Self-signed TLS cert (auto-generated) -├── key.pem # TLS private key (auto-generated) -├── requirements.txt # Python deps +│ └── 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 ```