-- Realtime GPS telemetry storage CREATE TABLE IF NOT EXISTS telemetry_samples ( id BIGSERIAL PRIMARY KEY, vehicle_id INTEGER REFERENCES vehicles(id) ON DELETE SET NULL, route_id INTEGER REFERENCES routes(id) ON DELETE SET NULL, source_type VARCHAR(30) NOT NULL DEFAULT 'manual', source_ref VARCHAR(120), location GEOGRAPHY(Point, 4326) NOT NULL, speed_kmh NUMERIC(6, 2), heading NUMERIC(6, 2), accuracy_meters NUMERIC(6, 2), recorded_at TIMESTAMP NOT NULL, received_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_valid BOOLEAN DEFAULT true, raw_payload JSONB DEFAULT '{}'::jsonb ); CREATE INDEX IF NOT EXISTS idx_telemetry_samples_vehicle_id ON telemetry_samples(vehicle_id); CREATE INDEX IF NOT EXISTS idx_telemetry_samples_route_id ON telemetry_samples(route_id); CREATE INDEX IF NOT EXISTS idx_telemetry_samples_recorded_at ON telemetry_samples(recorded_at DESC); CREATE INDEX IF NOT EXISTS idx_telemetry_samples_location ON telemetry_samples USING GIST(location); -- Latest live position for each vehicle CREATE TABLE IF NOT EXISTS vehicle_live_state ( vehicle_id INTEGER PRIMARY KEY REFERENCES vehicles(id) ON DELETE CASCADE, route_id INTEGER NOT NULL REFERENCES routes(id) ON DELETE CASCADE, location GEOGRAPHY(Point, 4326) NOT NULL, speed_kmh NUMERIC(6, 2), heading NUMERIC(6, 2), accuracy_meters NUMERIC(6, 2), source_type VARCHAR(30) NOT NULL DEFAULT 'manual', source_ref VARCHAR(120), last_seen_at TIMESTAMP NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_vehicle_live_state_route_id ON vehicle_live_state(route_id); CREATE INDEX IF NOT EXISTS idx_vehicle_live_state_last_seen_at ON vehicle_live_state(last_seen_at DESC); CREATE INDEX IF NOT EXISTS idx_vehicle_live_state_location ON vehicle_live_state USING GIST(location); DO $$ BEGIN IF EXISTS ( SELECT 1 FROM pg_proc WHERE proname = 'update_updated_at_column' ) AND NOT EXISTS ( SELECT 1 FROM pg_trigger WHERE tgname = 'update_vehicle_live_state_updated_at' ) THEN CREATE TRIGGER update_vehicle_live_state_updated_at BEFORE UPDATE ON vehicle_live_state FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); END IF; END $$;