Files
KSP-MissionControl/infra/init-sql/01-schema.sql
T

85 lines
3.3 KiB
SQL

-- Schema bootstrap for the kerbal-rt Postgres + Timescale install.
-- Runs automatically on first container start.
--
-- See kerbalrealtime-clone-plan.md §Component B for the full data model.
-- This is the Phase 0 minimum; Phase 1 fills in the rest.
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Bodies (celestial body catalog; small, mostly static)
CREATE TABLE IF NOT EXISTS bodies (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
kind TEXT NOT NULL CHECK (kind IN ('star','planet','moon','asteroid','comet')),
parent_id TEXT REFERENCES bodies(id),
radius DOUBLE PRECISION NOT NULL,
sphere_of_influence DOUBLE PRECISION NOT NULL,
gravitational_parameter DOUBLE PRECISION NOT NULL,
rotation_period DOUBLE PRECISION NOT NULL,
axial_tilt DOUBLE PRECISION NOT NULL,
elements JSONB NOT NULL
);
-- Vessels (slowly-changing dimension)
CREATE TABLE IF NOT EXISTS vessels (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
type TEXT,
owner TEXT,
status TEXT NOT NULL CHECK (status IN ('ACTIVE','DECOMMISSIONED','LOST')) DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
retired_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS vessels_status_idx ON vessels(status);
-- Telemetry snapshots (high-volume time series)
CREATE TABLE IF NOT EXISTS telemetry_snapshots (
ts TIMESTAMPTZ NOT NULL,
ut DOUBLE PRECISION NOT NULL,
payload JSONB NOT NULL
);
SELECT create_hypertable('telemetry_snapshots', 'ts', if_not_exists => TRUE);
CREATE INDEX IF NOT EXISTS telemetry_snapshots_ut_idx ON telemetry_snapshots(ut DESC);
-- Mission events
CREATE TABLE IF NOT EXISTS mission_events (
id BIGSERIAL PRIMARY KEY,
mission TEXT NOT NULL,
vessel_id TEXT REFERENCES vessels(id),
title TEXT NOT NULL,
description TEXT,
scheduled_at TIMESTAMPTZ NOT NULL,
ut_at_event DOUBLE PRECISION,
duration_s INTEGER,
kind TEXT NOT NULL CHECK (kind IN ('LAUNCH','BURN','FLYBY','LANDING','DOCKING','EVA','ECLIPSE','OPERATION','OTHER')),
created_by TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS mission_events_scheduled_idx ON mission_events(scheduled_at);
-- Media
CREATE TABLE IF NOT EXISTS media (
id BIGSERIAL PRIMARY KEY,
kind TEXT NOT NULL CHECK (kind IN ('image','youtube')),
url TEXT NOT NULL,
thumbnail_url TEXT,
caption TEXT,
tags TEXT[] NOT NULL DEFAULT '{}',
mission_id TEXT,
vessel_id TEXT REFERENCES vessels(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS media_tags_idx ON media USING GIN(tags);
CREATE INDEX IF NOT EXISTS media_created_idx ON media(created_at DESC);
-- Ground stations
CREATE TABLE IF NOT EXISTS ground_stations (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
body_id TEXT NOT NULL REFERENCES bodies(id),
lat DOUBLE PRECISION NOT NULL,
lon DOUBLE PRECISION NOT NULL,
alt DOUBLE PRECISION NOT NULL
);