Files
yaris-obd/server/sql/init.sql
T
Mathieu MoranandCopilot ba682fbf3a feat: add multi-device provisioning and local remote-config UI
- add multi-device portal device management, key rotation, and sync request APIs
- add Pi settings UI for remote server URL, device name, and API key
- add local test-connection and sync-now actions
- make upload and config sync reuse dynamic shared credentials
- add Phase 25.5c migration and docs updates

Co-authored-by: Copilot <[email protected]>
2026-08-10 18:02:09 -04:00

85 lines
3.4 KiB
SQL

-- 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,
owner_name TEXT DEFAULT '',
car_model TEXT DEFAULT '',
device_name TEXT DEFAULT '',
avatar_path TEXT DEFAULT 'img/yaris.png',
config_version INTEGER NOT NULL DEFAULT 0,
config_updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_config_sync_at TIMESTAMPTZ,
last_config_sync_version INTEGER,
force_sync_requested_at TIMESTAMPTZ,
api_key_rotated_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);
-- ── Phase 24: browser auth + server-side trips ─────────────────────────────
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL, -- bcrypt hash
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS trips (
id BIGSERIAL PRIMARY KEY,
device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
distance_km DOUBLE PRECISION NOT NULL DEFAULT 0,
duration_s INTEGER NOT NULL DEFAULT 0,
avg_speed_kmh DOUBLE PRECISION,
max_speed_kmh DOUBLE PRECISION,
start_lat DOUBLE PRECISION,
start_lon DOUBLE PRECISION,
end_lat DOUBLE PRECISION,
end_lon DOUBLE PRECISION,
point_count INTEGER NOT NULL DEFAULT 0,
computed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (device_id, start_time)
);
CREATE INDEX IF NOT EXISTS idx_trips_device_start
ON trips (device_id, start_time DESC);