-- =============================================================================
-- Fireside Communications — Tracksolid Pro Fleet Telemetry
-- Schema Migration: Webhook Receiver Support
-- =============================================================================
-- Adds tables and columns required by the FastAPI webhook receiver service
-- that ingests push data from Jimi's Data Push API.
--
-- All statements are idempotent (IF NOT EXISTS / ADD COLUMN IF NOT EXISTS).
-- Run against production with: psql $DATABASE_URL -f 03_webhook_schema_migration.sql
-- =============================================================================

-- =============================================================================
-- 1. Expand obd_readings for push data
-- =============================================================================
-- The Jimi /pushobd webhook sends a rich obdJson payload with device-model-
-- specific dataID fields. We store the full JSON as JSONB for flexibility,
-- plus commonly-needed columns for direct querying.

ALTER TABLE tracksolid.obd_readings
    ADD COLUMN IF NOT EXISTS car_type      SMALLINT,
    ADD COLUMN IF NOT EXISTS acc_state     SMALLINT,
    ADD COLUMN IF NOT EXISTS status_flags  INTEGER,
    ADD COLUMN IF NOT EXISTS lat           DOUBLE PRECISION,
    ADD COLUMN IF NOT EXISTS lng           DOUBLE PRECISION,
    ADD COLUMN IF NOT EXISTS geom          geometry(Point, 4326),
    ADD COLUMN IF NOT EXISTS obd_data      JSONB;

COMMENT ON COLUMN tracksolid.obd_readings.obd_data IS
    'Raw obdJson from Jimi push. Contains dataID1..N fields (engine RPM, coolant temp, fuel level, etc.)';

-- =============================================================================
-- 2. Create fault_codes table
-- =============================================================================
-- Stores DTC fault codes from /pushfaultinfo webhook.
-- One row per fault code per report for queryability.

CREATE TABLE IF NOT EXISTS tracksolid.fault_codes (
    id              BIGSERIAL PRIMARY KEY,
    imei            TEXT NOT NULL REFERENCES tracksolid.devices(imei),
    reported_at     TIMESTAMPTZ NOT NULL,
    fault_code      TEXT NOT NULL,
    status_flags    INTEGER,
    lat             DOUBLE PRECISION,
    lng             DOUBLE PRECISION,
    geom            geometry(Point, 4326),
    event_time      TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT fault_codes_dedup UNIQUE (imei, reported_at, fault_code)
);

CREATE INDEX IF NOT EXISTS idx_fault_codes_imei_time
    ON tracksolid.fault_codes (imei, reported_at DESC);

CREATE INDEX IF NOT EXISTS idx_fault_codes_code
    ON tracksolid.fault_codes (fault_code);

-- =============================================================================
-- 3. Create heartbeats table (hypertable)
-- =============================================================================
-- Stores device heartbeat data from /pushhb webhook.
-- High volume, low long-term value — retained for 30 days.

CREATE TABLE IF NOT EXISTS tracksolid.heartbeats (
    imei            TEXT NOT NULL REFERENCES tracksolid.devices(imei),
    gate_time       TIMESTAMPTZ NOT NULL,
    power_level     SMALLINT,
    gsm_signal      SMALLINT,
    acc_status      SMALLINT,
    power_status    SMALLINT,
    fortify         SMALLINT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (imei, gate_time)
);

SELECT create_hypertable('tracksolid.heartbeats', 'gate_time',
    chunk_time_interval => INTERVAL '7 days', if_not_exists => TRUE);

SELECT add_retention_policy('tracksolid.heartbeats', INTERVAL '30 days',
    if_not_exists => TRUE);

-- =============================================================================
-- 4. Expand trips for push data
-- =============================================================================
-- The /pushtripreport webhook provides fuel consumption, idle time, and
-- trip sequence numbers not available from the polling API.

ALTER TABLE tracksolid.trips
    ADD COLUMN IF NOT EXISTS fuel_consumed_l   NUMERIC(8,2),
    ADD COLUMN IF NOT EXISTS idle_time_s       INTEGER,
    ADD COLUMN IF NOT EXISTS driving_time_s    INTEGER,
    ADD COLUMN IF NOT EXISTS trip_seq          INTEGER,
    ADD COLUMN IF NOT EXISTS source            TEXT DEFAULT 'poll';

COMMENT ON COLUMN tracksolid.trips.driving_time_s IS 'runTimeSecond from API: total driving time in seconds';

COMMENT ON COLUMN tracksolid.trips.source IS 'poll = from API polling, push = from webhook push';

-- =============================================================================
-- 5. Expand position_history for push data
-- =============================================================================
-- The /pushgps webhook provides altitude and positioning type not available
-- from the polling API.

ALTER TABLE tracksolid.position_history
    ADD COLUMN IF NOT EXISTS altitude    NUMERIC(8,2),
    ADD COLUMN IF NOT EXISTS post_type   SMALLINT,
    ADD COLUMN IF NOT EXISTS source      TEXT DEFAULT 'poll';

-- =============================================================================
-- 6. Expand alarms for push data
-- =============================================================================

ALTER TABLE tracksolid.alarms
    ADD COLUMN IF NOT EXISTS alarm_name  TEXT,
    ADD COLUMN IF NOT EXISTS source      TEXT DEFAULT 'poll';

-- =============================================================================
-- 7. Permissions
-- =============================================================================

GRANT ALL ON tracksolid.fault_codes TO tracksolid_owner;
GRANT ALL ON tracksolid.heartbeats TO tracksolid_owner;
GRANT SELECT ON tracksolid.fault_codes TO grafana_ro;
GRANT SELECT ON tracksolid.heartbeats TO grafana_ro;

-- Grant sequence permissions for BIGSERIAL columns
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA tracksolid TO tracksolid_owner;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA tracksolid TO grafana_ro;
