mirror of
https://github.com/IS1DI/x0gp.git
synced 2026-07-16 20:47:55 +00:00
feat(server): integrate UDP video service and normalize database schema
- Implement UDPVideoService to stream MJPEG video frames from ESP32s via UDP and send control commands. - Normalize race database schema: - Remove redundant driver_ids array from races table (migration 011). - Move per-driver outcomes (total_time_ms, best_lap_ms, position) to race_drivers table (migration 012). - Add device_id column to lobby_drivers to link active physical devices (migration 013). - Update WebSocket handler to pass lobbySvc, driversSvc, and videoSvc for driver identity tracking, syncing in-memory driver metadata, and forwarding WS controls to physical cars. - Add CORS middleware to HTTP routes. - Regenerate Swagger documentation.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
-- 011_drop_driver_ids.sql — remove the driver_ids array column from
|
||||
-- the unified races table.
|
||||
--
|
||||
-- The authoritative source for "which drivers are in this race" is
|
||||
-- the race_drivers join table. The denormalised driver_ids TEXT[] was
|
||||
-- redundant (and racy — the mirror goroutines could write one side
|
||||
-- without the other). After this migration the only place where the
|
||||
-- driver list lives is race_drivers, and the PgStore methods hydrate
|
||||
-- it on read.
|
||||
|
||||
ALTER TABLE races DROP COLUMN IF EXISTS driver_ids;
|
||||
@@ -0,0 +1,45 @@
|
||||
-- 012_normalize_race_results.sql — move per-driver race outcomes
|
||||
-- (total time, best lap, finishing position) from races into
|
||||
-- race_drivers. The races table is left with only the metadata that
|
||||
-- applies to the race as a whole; everything that depends on a
|
||||
-- specific driver now lives in the join table.
|
||||
--
|
||||
-- Drop from races:
|
||||
-- * podium (JSONB) — derived from race_drivers ordered by
|
||||
-- total_time_ms ASC, top-3.
|
||||
-- * winner_driver_id (TEXT) — first row by total_time_ms.
|
||||
-- * winner_name (TEXT) — derived.
|
||||
-- * best_lap_ms (BIGINT) — moved to race_drivers as the
|
||||
-- MIN(best_lap_ms) over all rows in the race
|
||||
-- (or stored on each row from the engine;
|
||||
-- the aggregate is the same).
|
||||
--
|
||||
-- Add to race_drivers:
|
||||
-- * total_time_ms BIGINT NOT NULL DEFAULT 0 (the driver's total race time)
|
||||
-- * best_lap_ms BIGINT NOT NULL DEFAULT 0 (the driver's fastest lap)
|
||||
-- * position INT (1..N, NULL when DNF/DSQ)
|
||||
--
|
||||
-- Note: race_drivers is shared by the live surface too. For live
|
||||
-- races total_time_ms and best_lap_ms stay 0 (default) and position
|
||||
-- stays NULL. The semantics of `position` is "final position when
|
||||
-- the race finished"; the engine writes it on the finishing tick.
|
||||
|
||||
ALTER TABLE races DROP COLUMN IF EXISTS podium;
|
||||
ALTER TABLE races DROP COLUMN IF EXISTS winner_driver_id;
|
||||
ALTER TABLE races DROP COLUMN IF EXISTS winner_name;
|
||||
ALTER TABLE races DROP COLUMN IF EXISTS best_lap_ms;
|
||||
|
||||
DROP INDEX IF EXISTS finished_races_podium_gin;
|
||||
|
||||
ALTER TABLE race_drivers
|
||||
ADD COLUMN IF NOT EXISTS total_time_ms BIGINT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE race_drivers
|
||||
ADD COLUMN IF NOT EXISTS best_lap_ms BIGINT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE race_drivers
|
||||
ADD COLUMN IF NOT EXISTS position INT;
|
||||
|
||||
-- Keyset index over the join table for podium queries: "top-3 by
|
||||
-- total_time_ms within this race" is the canonical podium lookup.
|
||||
CREATE INDEX IF NOT EXISTS race_drivers_podium_idx
|
||||
ON race_drivers (race_id, total_time_ms ASC, position ASC)
|
||||
WHERE total_time_ms > 0;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- 013_driver_device.sql — add device_id to lobby_drivers.
|
||||
--
|
||||
-- Represents the currently selected physical ESP32 DEVICE_ID (0..127) for a driver.
|
||||
-- This device is pinned to the driver during races and released when the race ends or they leave.
|
||||
|
||||
ALTER TABLE lobby_drivers ADD COLUMN IF NOT EXISTS device_id INT;
|
||||
Reference in New Issue
Block a user