- Add Flask-Login browser session auth (separate from device X-Api-Key auth)
- modules/user_auth.py: User model, require_login decorator, bcrypt helpers
- /login with CSRF token, /logout
- scripts/create_user.py to provision admin user
- Add server-side trip computation from tracking_points
- db.compute_trips_for_device(): gap > 5 min = new trip, haversine distance,
upserts into trips table, auto-triggered in bg thread after each upload batch
- db.list_trips(), db.get_trip_route(): same JSON shape as Pi API
- db.get_overview_stats(): aggregated totals for overview page
- db.list_dashcam_files(), db.get_dashcam_file(): browse/stream helpers
- Add web portal to server/app.py
- Overview page (/): stat cards + recent trips + recent clips
- Trip history (/history): reuses Pi history.js + data-list.js unchanged
via /api/trips + /api/trip/<id> compatibility aliases
- Dashcam archive (/dashcam): file list + inline video player
- /api/v1/portal/dashcam/stream/<id>: Range-request streaming, path traversal guard
- /api/geocode: same Nominatim→reverse_geocoder offline fallback as Pi
- Add server templates (server/templates/)
- base.html: shared shell with 'Remote server' badge in sidebar + mobile topbar
- login.html, index.html, history.html, dashcam.html, components.html
- DB schema: users + trips tables added to init.sql (fresh deploys) +
migrate_phase24.sql (existing deployments)
- Infrastructure: Dockerfile uses repo-root build context to copy shared
static/ assets; docker-compose updated; SECRET_KEY + DEVICE_NAME in .env;
requirements: Flask-Login, bcrypt, reverse_geocoder
Co-authored-by: Copilot <[email protected]>
50 lines
1.7 KiB
YAML
50 lines
1.7 KiB
YAML
services:
|
|
db:
|
|
image: postgres:17
|
|
container_name: yaris-obd-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB:-yarisobd}
|
|
POSTGRES_USER: ${POSTGRES_USER:-yarisobd}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set a POSTGRES_PASSWORD in .env}
|
|
volumes:
|
|
- ${DATA_DIR:-./data}/postgres:/var/lib/postgresql/data
|
|
- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
|
- ./sql/migrate_phase24.sql:/docker-entrypoint-initdb.d/migrate_phase24.sql:ro
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-yarisobd}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
# Not published to the host/LAN on purpose - only reachable from the
|
|
# `api` container over the internal compose network.
|
|
|
|
api:
|
|
build:
|
|
context: ..
|
|
dockerfile: server/Dockerfile
|
|
container_name: yaris-obd-api
|
|
restart: unless-stopped
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
environment:
|
|
POSTGRES_HOST: db
|
|
POSTGRES_PORT: 5432
|
|
POSTGRES_DB: ${POSTGRES_DB:-yarisobd}
|
|
POSTGRES_USER: ${POSTGRES_USER:-yarisobd}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set a POSTGRES_PASSWORD in .env}
|
|
DASHCAM_STORAGE_DIR: /data/dashcam
|
|
MAX_DASHCAM_UPLOAD_MB: ${MAX_DASHCAM_UPLOAD_MB:-2048}
|
|
SECRET_KEY: ${SECRET_KEY:?set a SECRET_KEY in .env}
|
|
DEVICE_NAME: ${DEVICE_NAME:-yaris-2013}
|
|
volumes:
|
|
- ${DATA_DIR:-./data}/dashcam:/data/dashcam
|
|
ports:
|
|
- "${API_PORT:-8098}:8098"
|
|
healthcheck:
|
|
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8098/health', timeout=3)"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|