Phase 9: scaffold remote server (Flask + Postgres, docker-compose for unraid)
- server/sql/init.sql: devices/tracking_points/dashcam_files schema - server/modules/db.py: psycopg3 pool + query helpers - server/modules/auth.py: X-Device-Name/X-Api-Key header auth - server/app.py: /health, /api/v1/tracking/batch, /api/v1/dashcam/upload - server/Dockerfile + docker-compose.yml: api (gunicorn) + postgres services - server/scripts/create_device.py: one-time device/API-key registration - server/README.md: unraid deployment + Cloudflare Tunnel exposure docs - PLAN.md: Phase 9 marked in progress with full build notes Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
-- yaris-obd remote server schema
|
||||
-- Applied automatically on first Postgres container start (mounted into
|
||||
-- /docker-entrypoint-initdb.d/), so it only ever runs once against a fresh
|
||||
-- empty database volume.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE, -- e.g. "yaris-2013"
|
||||
api_key_hash TEXT NOT NULL, -- sha256 hex digest of the device's API key, never the raw key
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tracking_points (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
||||
vehicle_name TEXT,
|
||||
driver_name TEXT,
|
||||
recorded_at TIMESTAMPTZ NOT NULL, -- timestamp taken on the Pi when the point was captured
|
||||
gps_lat DOUBLE PRECISION,
|
||||
gps_lon DOUBLE PRECISION,
|
||||
speed DOUBLE PRECISION,
|
||||
odometer DOUBLE PRECISION,
|
||||
received_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
-- Prevent the same locally-queued row from being inserted twice on retry
|
||||
UNIQUE (device_id, recorded_at)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_tracking_points_device_time
|
||||
ON tracking_points (device_id, recorded_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dashcam_files (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
||||
relative_path TEXT NOT NULL, -- original sub-folder path on the dashcam SD card
|
||||
size_bytes BIGINT NOT NULL,
|
||||
sha256 TEXT NOT NULL,
|
||||
storage_path TEXT NOT NULL, -- where the file landed on the server's disk
|
||||
uploaded_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (device_id, relative_path, sha256)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_dashcam_files_device
|
||||
ON dashcam_files (device_id, uploaded_at DESC);
|
||||
Reference in New Issue
Block a user