-- Phase 24 migration: add users table (browser auth) and server-side trips. -- Run manually against the live Postgres DB: -- psql $DSN -f sql/migrate_phase24.sql -- ── Browser session users ────────────────────────────────────────────────── 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() ); -- ── Server-side trip index ───────────────────────────────────────────────── -- Computed from tracking_points by compute_trips_for_device(). -- Idempotent: re-running recomputes and upserts without duplicating rows. 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);