85 lines
3.3 KiB
SQL
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
|
|
);
|