2026-04-07 18:34:40 +00:00
|
|
|
-- =============================================================================
|
|
|
|
|
-- Fireside Communications — Tracksolid Pro Fleet Telemetry
|
|
|
|
|
-- PostgreSQL 16 + PostGIS 3 + TimescaleDB 2.15
|
|
|
|
|
-- Complete Database Bootstrap Script (Revised & Unified)
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- Author: DevOps / Telematics Specialist
|
|
|
|
|
-- Version: 2.0 (DWH + TimescaleDB Integrated)
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 1 — DATABASE, EXTENSIONS, ROLES
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
-- Database creation (Run manually if needed, or logical script starts here)
|
|
|
|
|
-- CREATE DATABASE tracksolid_db ENCODING = 'UTF8';
|
|
|
|
|
-- \connect tracksolid_db
|
|
|
|
|
|
|
|
|
|
-- ── Extensions ────────────────────────────────────────────────────────────────
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS postgis CASCADE;
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
|
|
|
|
CREATE EXTENSION IF NOT EXISTS btree_gist;
|
|
|
|
|
|
|
|
|
|
-- ── Roles ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
DO $$
|
|
|
|
|
BEGIN
|
|
|
|
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'tracksolid_owner') THEN
|
|
|
|
|
CREATE ROLE tracksolid_owner WITH LOGIN PASSWORD 'SET_PASSWORD_IN_ENV';
|
|
|
|
|
END IF;
|
|
|
|
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'grafana_ro') THEN
|
|
|
|
|
CREATE ROLE grafana_ro WITH LOGIN PASSWORD 'SET_PASSWORD_IN_ENV';
|
|
|
|
|
END IF;
|
|
|
|
|
END$$;
|
|
|
|
|
|
|
|
|
|
GRANT CONNECT ON DATABASE tracksolid_db TO tracksolid_owner;
|
|
|
|
|
GRANT CONNECT ON DATABASE tracksolid_db TO grafana_ro;
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 2 — SCHEMAS
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
CREATE SCHEMA IF NOT EXISTS tracksolid AUTHORIZATION tracksolid_owner;
|
|
|
|
|
CREATE SCHEMA IF NOT EXISTS infrastructure AUTHORIZATION tracksolid_owner;
|
|
|
|
|
CREATE SCHEMA IF NOT EXISTS dwh_gold AUTHORIZATION tracksolid_owner;
|
|
|
|
|
|
|
|
|
|
ALTER DATABASE tracksolid_db SET search_path TO tracksolid, infrastructure, dwh_gold, public;
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 3 — OPERATIONAL TABLES (tracksolid)
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
-- 3.01 Master Device Registry
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.devices (
|
|
|
|
|
imei TEXT PRIMARY KEY,
|
|
|
|
|
device_name TEXT,
|
|
|
|
|
mc_type TEXT,
|
|
|
|
|
mc_type_use_scope TEXT,
|
|
|
|
|
vehicle_name TEXT,
|
|
|
|
|
vehicle_number TEXT,
|
|
|
|
|
vehicle_models TEXT,
|
|
|
|
|
vehicle_icon TEXT,
|
|
|
|
|
vin TEXT,
|
|
|
|
|
engine_number TEXT,
|
|
|
|
|
vehicle_brand TEXT,
|
|
|
|
|
fuel_100km NUMERIC(6,2),
|
|
|
|
|
driver_name TEXT,
|
|
|
|
|
driver_phone TEXT,
|
|
|
|
|
sim TEXT,
|
|
|
|
|
iccid TEXT,
|
|
|
|
|
imsi TEXT,
|
|
|
|
|
account TEXT,
|
|
|
|
|
customer_name TEXT,
|
|
|
|
|
device_group_id TEXT,
|
|
|
|
|
device_group TEXT,
|
|
|
|
|
activation_time TIMESTAMPTZ,
|
|
|
|
|
expiration TIMESTAMPTZ,
|
|
|
|
|
enabled_flag SMALLINT NOT NULL DEFAULT 1,
|
|
|
|
|
status TEXT DEFAULT 'active',
|
|
|
|
|
city TEXT,
|
|
|
|
|
current_mileage_km NUMERIC(12,2),
|
|
|
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
|
last_synced_at TIMESTAMPTZ
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.02 Token Cache
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.api_token_cache (
|
|
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
account TEXT NOT NULL UNIQUE,
|
|
|
|
|
access_token TEXT NOT NULL,
|
|
|
|
|
refresh_token TEXT,
|
|
|
|
|
app_key TEXT,
|
|
|
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
|
|
|
obtained_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.03 Ingestion Health Log
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.ingestion_log (
|
|
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
|
endpoint TEXT NOT NULL,
|
|
|
|
|
imei_count INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
rows_upserted INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
rows_inserted INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
duration_ms INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
success BOOLEAN NOT NULL DEFAULT TRUE,
|
|
|
|
|
error_code TEXT,
|
|
|
|
|
error_message TEXT
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.04 Live Positions (Hot Snapshots)
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.live_positions (
|
|
|
|
|
imei TEXT PRIMARY KEY REFERENCES tracksolid.devices(imei),
|
|
|
|
|
geom geometry(Point, 4326),
|
|
|
|
|
lat DOUBLE PRECISION,
|
|
|
|
|
lng DOUBLE PRECISION,
|
|
|
|
|
pos_type TEXT,
|
|
|
|
|
confidence SMALLINT,
|
|
|
|
|
gps_time TIMESTAMPTZ,
|
|
|
|
|
hb_time TIMESTAMPTZ,
|
|
|
|
|
speed NUMERIC(7,2),
|
|
|
|
|
direction NUMERIC(6,2),
|
|
|
|
|
acc_status TEXT,
|
|
|
|
|
gps_signal SMALLINT,
|
|
|
|
|
gps_num SMALLINT,
|
|
|
|
|
elec_quantity NUMERIC(5,2),
|
|
|
|
|
power_value NUMERIC(5,2),
|
|
|
|
|
battery_power_val NUMERIC(5,2),
|
|
|
|
|
tracker_oil TEXT,
|
|
|
|
|
temperature NUMERIC(8,2),
|
|
|
|
|
current_mileage NUMERIC(12,2),
|
|
|
|
|
device_status TEXT,
|
|
|
|
|
expire_flag TEXT,
|
|
|
|
|
activation_flag TEXT,
|
|
|
|
|
loc_desc TEXT,
|
|
|
|
|
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.05 Position History (Hypertable Source)
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.position_history (
|
|
|
|
|
imei TEXT NOT NULL REFERENCES tracksolid.devices(imei),
|
|
|
|
|
gps_time TIMESTAMPTZ NOT NULL,
|
|
|
|
|
geom geometry(Point, 4326),
|
|
|
|
|
lat DOUBLE PRECISION,
|
|
|
|
|
lng DOUBLE PRECISION,
|
|
|
|
|
speed NUMERIC(7,2),
|
|
|
|
|
direction NUMERIC(6,2),
|
|
|
|
|
acc_status TEXT,
|
|
|
|
|
satellite SMALLINT,
|
|
|
|
|
current_mileage NUMERIC(12,2),
|
|
|
|
|
recorded_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
|
PRIMARY KEY (imei, gps_time)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.06 Trip Summaries
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.trips (
|
|
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
imei TEXT NOT NULL REFERENCES tracksolid.devices(imei),
|
|
|
|
|
start_time TIMESTAMPTZ NOT NULL,
|
|
|
|
|
end_time TIMESTAMPTZ,
|
|
|
|
|
start_geom geometry(Point, 4326),
|
|
|
|
|
end_geom geometry(Point, 4326),
|
|
|
|
|
distance_m NUMERIC(12,2), -- QA-02: Stored in Meters
|
|
|
|
|
avg_speed_kmh NUMERIC(7,2),
|
|
|
|
|
max_speed_kmh NUMERIC(7,2),
|
|
|
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
|
CONSTRAINT trips_imei_start_unique UNIQUE (imei, start_time)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.07 Parking & Idling
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.parking_events (
|
|
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
imei TEXT NOT NULL REFERENCES tracksolid.devices(imei),
|
|
|
|
|
event_type TEXT CHECK (event_type IN ('parking', 'idling')),
|
|
|
|
|
start_time TIMESTAMPTZ NOT NULL,
|
|
|
|
|
end_time TIMESTAMPTZ,
|
|
|
|
|
duration_seconds INTEGER,
|
|
|
|
|
geom geometry(Point, 4326),
|
|
|
|
|
address TEXT,
|
|
|
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
|
CONSTRAINT parking_dedup UNIQUE (imei, start_time, event_type)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- 3.08 Alarms, OBD, Fault Codes
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.alarms (
|
Add webhook receiver, consolidate shared utilities, expand telemetry coverage
- Add FastAPI webhook receiver (webhook_receiver_rev.py) for Jimi push data:
OBD diagnostics, DTC fault codes, alarms, GPS, heartbeats, trip reports
- Add schema migration (03_webhook_schema_migration.sql) for webhook tables:
fault_codes, heartbeats, expanded obd_readings/trips/position_history/alarms
- Consolidate duplicated _safe/_shutdown into shared safe_task/setup_shutdown
in ts_shared_rev.py (DRY refactor)
- Add auto-commit to get_conn() context manager (prevents forgotten commits)
- Fix poll_trips to capture runTimeSecond and maxSpeed from API
- Add poll_parking via jimi.open.platform.report.parking
- Remove broken poll_obd (OBD is push-only, no polling endpoint exists)
- Fix alarms schema: add lat/lng/acc_status columns + dedup constraint
- Fix obd_readings schema: add dedup constraint
- Fix trigger DO block: replace nonexistent has_column with information_schema
- Narrow api_post exception handling to RequestException/ValueError
- Add webhook_receiver service to docker-compose.yaml
- Add fastapi/uvicorn/python-multipart to pyproject.toml
- Add clean_ts timestamp validator to ts_shared_rev.py
- Add Tracksolid Pro API documentation (tracksolidApiDocumentation.md)
- Populate .gitignore with Python/OS/secrets patterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:28:45 +00:00
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
imei TEXT REFERENCES tracksolid.devices(imei),
|
|
|
|
|
alarm_type TEXT,
|
|
|
|
|
alarm_time TIMESTAMPTZ,
|
|
|
|
|
geom geometry(Point, 4326),
|
|
|
|
|
lat DOUBLE PRECISION,
|
|
|
|
|
lng DOUBLE PRECISION,
|
|
|
|
|
speed NUMERIC(7,2),
|
|
|
|
|
acc_status TEXT,
|
|
|
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
|
CONSTRAINT alarms_dedup UNIQUE (imei, alarm_type, alarm_time)
|
2026-04-07 18:34:40 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE IF NOT EXISTS tracksolid.obd_readings (
|
Add webhook receiver, consolidate shared utilities, expand telemetry coverage
- Add FastAPI webhook receiver (webhook_receiver_rev.py) for Jimi push data:
OBD diagnostics, DTC fault codes, alarms, GPS, heartbeats, trip reports
- Add schema migration (03_webhook_schema_migration.sql) for webhook tables:
fault_codes, heartbeats, expanded obd_readings/trips/position_history/alarms
- Consolidate duplicated _safe/_shutdown into shared safe_task/setup_shutdown
in ts_shared_rev.py (DRY refactor)
- Add auto-commit to get_conn() context manager (prevents forgotten commits)
- Fix poll_trips to capture runTimeSecond and maxSpeed from API
- Add poll_parking via jimi.open.platform.report.parking
- Remove broken poll_obd (OBD is push-only, no polling endpoint exists)
- Fix alarms schema: add lat/lng/acc_status columns + dedup constraint
- Fix obd_readings schema: add dedup constraint
- Fix trigger DO block: replace nonexistent has_column with information_schema
- Narrow api_post exception handling to RequestException/ValueError
- Add webhook_receiver service to docker-compose.yaml
- Add fastapi/uvicorn/python-multipart to pyproject.toml
- Add clean_ts timestamp validator to ts_shared_rev.py
- Add Tracksolid Pro API documentation (tracksolidApiDocumentation.md)
- Populate .gitignore with Python/OS/secrets patterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:28:45 +00:00
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
imei TEXT REFERENCES tracksolid.devices(imei),
|
|
|
|
|
reading_time TIMESTAMPTZ,
|
|
|
|
|
engine_rpm INTEGER,
|
|
|
|
|
fuel_level_pct NUMERIC(5,2),
|
|
|
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
|
CONSTRAINT obd_readings_dedup UNIQUE (imei, reading_time)
|
2026-04-07 18:34:40 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 4 — TIMESCALEDB CONFIGURATION
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
-- Convert to Hypertable
|
|
|
|
|
SELECT create_hypertable('tracksolid.position_history', 'gps_time', chunk_time_interval => INTERVAL '7 days', if_not_exists => TRUE);
|
|
|
|
|
|
|
|
|
|
-- Enable Compression
|
|
|
|
|
ALTER TABLE tracksolid.position_history SET (timescaledb.compress, timescaledb.compress_segmentby = 'imei');
|
|
|
|
|
SELECT add_compression_policy('tracksolid.position_history', INTERVAL '14 days');
|
|
|
|
|
|
|
|
|
|
-- Retention: 90 Days for Hot History
|
|
|
|
|
SELECT add_retention_policy('tracksolid.position_history', INTERVAL '90 days');
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 5 — DATA WAREHOUSE GOLD LAYER (dwh_gold)
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
CREATE TABLE dwh_gold.dim_vehicles (
|
|
|
|
|
vehicle_key SERIAL PRIMARY KEY,
|
|
|
|
|
imei TEXT UNIQUE,
|
|
|
|
|
vehicle_number TEXT,
|
|
|
|
|
is_active BOOLEAN DEFAULT TRUE
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CREATE TABLE dwh_gold.fact_daily_fleet_metrics (
|
|
|
|
|
day DATE NOT NULL,
|
|
|
|
|
vehicle_key INTEGER REFERENCES dwh_gold.dim_vehicles(vehicle_key),
|
|
|
|
|
total_distance_km NUMERIC(12,2),
|
|
|
|
|
max_speed_kmh NUMERIC(7,2),
|
|
|
|
|
idle_hours NUMERIC(5,2),
|
|
|
|
|
PRIMARY KEY (day, vehicle_key)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 6 — TRIGGERS & VIEWS
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
-- Updated_at Trigger Function
|
|
|
|
|
CREATE OR REPLACE FUNCTION tracksolid.set_updated_at() RETURNS TRIGGER AS $$
|
|
|
|
|
BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql;
|
|
|
|
|
|
Add webhook receiver, consolidate shared utilities, expand telemetry coverage
- Add FastAPI webhook receiver (webhook_receiver_rev.py) for Jimi push data:
OBD diagnostics, DTC fault codes, alarms, GPS, heartbeats, trip reports
- Add schema migration (03_webhook_schema_migration.sql) for webhook tables:
fault_codes, heartbeats, expanded obd_readings/trips/position_history/alarms
- Consolidate duplicated _safe/_shutdown into shared safe_task/setup_shutdown
in ts_shared_rev.py (DRY refactor)
- Add auto-commit to get_conn() context manager (prevents forgotten commits)
- Fix poll_trips to capture runTimeSecond and maxSpeed from API
- Add poll_parking via jimi.open.platform.report.parking
- Remove broken poll_obd (OBD is push-only, no polling endpoint exists)
- Fix alarms schema: add lat/lng/acc_status columns + dedup constraint
- Fix obd_readings schema: add dedup constraint
- Fix trigger DO block: replace nonexistent has_column with information_schema
- Narrow api_post exception handling to RequestException/ValueError
- Add webhook_receiver service to docker-compose.yaml
- Add fastapi/uvicorn/python-multipart to pyproject.toml
- Add clean_ts timestamp validator to ts_shared_rev.py
- Add Tracksolid Pro API documentation (tracksolidApiDocumentation.md)
- Populate .gitignore with Python/OS/secrets patterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:28:45 +00:00
|
|
|
-- Apply trigger to tables with updated_at column
|
2026-04-07 18:34:40 +00:00
|
|
|
DO $$
|
|
|
|
|
DECLARE t TEXT;
|
|
|
|
|
BEGIN
|
Add webhook receiver, consolidate shared utilities, expand telemetry coverage
- Add FastAPI webhook receiver (webhook_receiver_rev.py) for Jimi push data:
OBD diagnostics, DTC fault codes, alarms, GPS, heartbeats, trip reports
- Add schema migration (03_webhook_schema_migration.sql) for webhook tables:
fault_codes, heartbeats, expanded obd_readings/trips/position_history/alarms
- Consolidate duplicated _safe/_shutdown into shared safe_task/setup_shutdown
in ts_shared_rev.py (DRY refactor)
- Add auto-commit to get_conn() context manager (prevents forgotten commits)
- Fix poll_trips to capture runTimeSecond and maxSpeed from API
- Add poll_parking via jimi.open.platform.report.parking
- Remove broken poll_obd (OBD is push-only, no polling endpoint exists)
- Fix alarms schema: add lat/lng/acc_status columns + dedup constraint
- Fix obd_readings schema: add dedup constraint
- Fix trigger DO block: replace nonexistent has_column with information_schema
- Narrow api_post exception handling to RequestException/ValueError
- Add webhook_receiver service to docker-compose.yaml
- Add fastapi/uvicorn/python-multipart to pyproject.toml
- Add clean_ts timestamp validator to ts_shared_rev.py
- Add Tracksolid Pro API documentation (tracksolidApiDocumentation.md)
- Populate .gitignore with Python/OS/secrets patterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 13:28:45 +00:00
|
|
|
FOR t IN
|
|
|
|
|
SELECT pt.tablename
|
|
|
|
|
FROM pg_tables pt
|
|
|
|
|
JOIN information_schema.columns c
|
|
|
|
|
ON c.table_schema = pt.schemaname AND c.table_name = pt.tablename
|
|
|
|
|
WHERE pt.schemaname = 'tracksolid' AND c.column_name = 'updated_at'
|
2026-04-07 18:34:40 +00:00
|
|
|
LOOP
|
|
|
|
|
EXECUTE format('CREATE TRIGGER trg_upd_%I BEFORE UPDATE ON tracksolid.%I FOR EACH ROW EXECUTE FUNCTION tracksolid.set_updated_at()', t, t);
|
|
|
|
|
END LOOP;
|
|
|
|
|
END $$;
|
|
|
|
|
|
|
|
|
|
-- Enriched Live View
|
|
|
|
|
CREATE OR REPLACE VIEW tracksolid.v_fleet_status AS
|
|
|
|
|
SELECT
|
|
|
|
|
d.imei, d.vehicle_number, d.driver_name,
|
|
|
|
|
lp.lat, lp.lng, lp.geom, lp.speed, lp.acc_status, lp.gps_time,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN lp.gps_time >= NOW() - INTERVAL '5 minutes' THEN 'online'
|
|
|
|
|
WHEN lp.gps_time >= NOW() - INTERVAL '30 minutes' THEN 'recent'
|
|
|
|
|
ELSE 'offline'
|
|
|
|
|
END AS connectivity_status,
|
|
|
|
|
EXTRACT(EPOCH FROM (NOW() - lp.gps_time))::int AS seconds_since_fix
|
|
|
|
|
FROM tracksolid.devices d
|
|
|
|
|
LEFT JOIN tracksolid.live_positions lp USING (imei)
|
|
|
|
|
WHERE d.enabled_flag = 1;
|
|
|
|
|
|
|
|
|
|
-- Ingestion Health View
|
|
|
|
|
CREATE OR REPLACE VIEW tracksolid.v_ingestion_health AS
|
|
|
|
|
SELECT DISTINCT ON (endpoint) endpoint, run_at, success, error_message, EXTRACT(EPOCH FROM (NOW() - run_at))::int AS seconds_ago
|
|
|
|
|
FROM tracksolid.ingestion_log ORDER BY endpoint, run_at DESC;
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 7 — CONTINUOUS AGGREGATES (Performance)
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
CREATE MATERIALIZED VIEW tracksolid.v_mileage_daily_cagg
|
|
|
|
|
WITH (timescaledb.continuous) AS
|
|
|
|
|
SELECT
|
|
|
|
|
time_bucket('1 day', gps_time) AS bucket,
|
|
|
|
|
imei,
|
|
|
|
|
(MAX(current_mileage) - MIN(current_mileage)) AS dist_km,
|
|
|
|
|
AVG(speed) AS avg_speed
|
|
|
|
|
FROM tracksolid.position_history
|
|
|
|
|
GROUP BY bucket, imei;
|
|
|
|
|
|
|
|
|
|
SELECT add_continuous_aggregate_policy('tracksolid.v_mileage_daily_cagg',
|
|
|
|
|
start_offset => INTERVAL '3 days', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour');
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 8 — PERMISSIONS
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
|
|
|
|
|
GRANT USAGE ON SCHEMA tracksolid, infrastructure, dwh_gold TO tracksolid_owner, grafana_ro;
|
|
|
|
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA tracksolid, infrastructure, dwh_gold TO tracksolid_owner;
|
|
|
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA tracksolid, infrastructure, dwh_gold TO grafana_ro;
|
|
|
|
|
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO grafana_ro;
|
|
|
|
|
|
|
|
|
|
ALTER DEFAULT PRIVILEGES IN SCHEMA tracksolid GRANT ALL ON TABLES TO tracksolid_owner;
|
|
|
|
|
ALTER DEFAULT PRIVILEGES IN SCHEMA tracksolid GRANT SELECT ON TABLES TO grafana_ro;
|
|
|
|
|
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
-- STEP 9 — VERIFICATION
|
|
|
|
|
-- =============================================================================
|
|
|
|
|
SELECT PostGIS_Full_Version();
|
|
|
|
|
SELECT * FROM timescaledb_information.hypertables;
|