186 lines
7.7 KiB
PL/PgSQL
186 lines
7.7 KiB
PL/PgSQL
BEGIN;
|
|
|
|
CREATE TABLE places (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
place_public_id TEXT NOT NULL UNIQUE,
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
region TEXT,
|
|
cover_url TEXT,
|
|
description TEXT,
|
|
center_point_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'disabled', 'archived')),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX places_status_idx ON places(status);
|
|
|
|
CREATE TRIGGER places_set_updated_at
|
|
BEFORE UPDATE ON places
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE map_assets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
map_asset_public_id TEXT NOT NULL UNIQUE,
|
|
place_id UUID NOT NULL REFERENCES places(id) ON DELETE CASCADE,
|
|
legacy_map_id UUID REFERENCES maps(id) ON DELETE SET NULL,
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
map_type TEXT NOT NULL DEFAULT 'standard',
|
|
cover_url TEXT,
|
|
description TEXT,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'disabled', 'archived')),
|
|
current_tile_release_id UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX map_assets_place_id_idx ON map_assets(place_id);
|
|
CREATE INDEX map_assets_legacy_map_id_idx ON map_assets(legacy_map_id);
|
|
CREATE INDEX map_assets_status_idx ON map_assets(status);
|
|
|
|
CREATE TRIGGER map_assets_set_updated_at
|
|
BEFORE UPDATE ON map_assets
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE tile_releases (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tile_release_public_id TEXT NOT NULL UNIQUE,
|
|
map_asset_id UUID NOT NULL REFERENCES map_assets(id) ON DELETE CASCADE,
|
|
legacy_map_version_id UUID REFERENCES map_versions(id) ON DELETE SET NULL,
|
|
version_code TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'published', 'retired', 'archived')),
|
|
tile_base_url TEXT NOT NULL,
|
|
meta_url TEXT NOT NULL,
|
|
published_asset_root TEXT,
|
|
metadata_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
published_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (map_asset_id, version_code)
|
|
);
|
|
|
|
CREATE INDEX tile_releases_map_asset_id_idx ON tile_releases(map_asset_id);
|
|
CREATE INDEX tile_releases_legacy_map_version_id_idx ON tile_releases(legacy_map_version_id);
|
|
CREATE INDEX tile_releases_status_idx ON tile_releases(status);
|
|
|
|
CREATE TRIGGER tile_releases_set_updated_at
|
|
BEFORE UPDATE ON tile_releases
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
ALTER TABLE map_assets
|
|
ADD CONSTRAINT map_assets_current_tile_release_fk
|
|
FOREIGN KEY (current_tile_release_id) REFERENCES tile_releases(id) ON DELETE SET NULL;
|
|
|
|
CREATE TABLE course_sources (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
course_source_public_id TEXT NOT NULL UNIQUE,
|
|
legacy_playfield_version_id UUID REFERENCES playfield_versions(id) ON DELETE SET NULL,
|
|
source_type TEXT NOT NULL CHECK (source_type IN ('kml', 'geojson', 'control_set', 'json')),
|
|
file_url TEXT NOT NULL,
|
|
checksum TEXT,
|
|
parser_version TEXT,
|
|
import_status TEXT NOT NULL DEFAULT 'imported' CHECK (import_status IN ('draft', 'imported', 'parsed', 'failed', 'archived')),
|
|
metadata_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
imported_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX course_sources_legacy_playfield_version_id_idx ON course_sources(legacy_playfield_version_id);
|
|
CREATE INDEX course_sources_source_type_idx ON course_sources(source_type);
|
|
CREATE INDEX course_sources_import_status_idx ON course_sources(import_status);
|
|
|
|
CREATE TRIGGER course_sources_set_updated_at
|
|
BEFORE UPDATE ON course_sources
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE course_sets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
course_set_public_id TEXT NOT NULL UNIQUE,
|
|
place_id UUID NOT NULL REFERENCES places(id) ON DELETE RESTRICT,
|
|
map_asset_id UUID NOT NULL REFERENCES map_assets(id) ON DELETE RESTRICT,
|
|
code TEXT NOT NULL UNIQUE,
|
|
mode TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'disabled', 'archived')),
|
|
current_variant_id UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX course_sets_place_id_idx ON course_sets(place_id);
|
|
CREATE INDEX course_sets_map_asset_id_idx ON course_sets(map_asset_id);
|
|
CREATE INDEX course_sets_status_idx ON course_sets(status);
|
|
|
|
CREATE TRIGGER course_sets_set_updated_at
|
|
BEFORE UPDATE ON course_sets
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
CREATE TABLE course_variants (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
course_variant_public_id TEXT NOT NULL UNIQUE,
|
|
course_set_id UUID NOT NULL REFERENCES course_sets(id) ON DELETE CASCADE,
|
|
source_id UUID REFERENCES course_sources(id) ON DELETE SET NULL,
|
|
name TEXT NOT NULL,
|
|
route_code TEXT,
|
|
mode TEXT NOT NULL,
|
|
control_count INTEGER,
|
|
difficulty TEXT,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'disabled', 'archived')),
|
|
is_default BOOLEAN NOT NULL DEFAULT FALSE,
|
|
config_patch_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
metadata_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX course_variants_course_set_id_idx ON course_variants(course_set_id);
|
|
CREATE INDEX course_variants_source_id_idx ON course_variants(source_id);
|
|
CREATE INDEX course_variants_status_idx ON course_variants(status);
|
|
CREATE INDEX course_variants_route_code_idx ON course_variants(route_code);
|
|
|
|
CREATE TRIGGER course_variants_set_updated_at
|
|
BEFORE UPDATE ON course_variants
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
ALTER TABLE course_sets
|
|
ADD CONSTRAINT course_sets_current_variant_fk
|
|
FOREIGN KEY (current_variant_id) REFERENCES course_variants(id) ON DELETE SET NULL;
|
|
|
|
CREATE TABLE map_runtime_bindings (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
runtime_binding_public_id TEXT NOT NULL UNIQUE,
|
|
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
|
place_id UUID NOT NULL REFERENCES places(id) ON DELETE RESTRICT,
|
|
map_asset_id UUID NOT NULL REFERENCES map_assets(id) ON DELETE RESTRICT,
|
|
tile_release_id UUID NOT NULL REFERENCES tile_releases(id) ON DELETE RESTRICT,
|
|
course_set_id UUID NOT NULL REFERENCES course_sets(id) ON DELETE RESTRICT,
|
|
course_variant_id UUID NOT NULL REFERENCES course_variants(id) ON DELETE RESTRICT,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'disabled', 'archived')),
|
|
notes TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX map_runtime_bindings_event_id_idx ON map_runtime_bindings(event_id);
|
|
CREATE INDEX map_runtime_bindings_place_id_idx ON map_runtime_bindings(place_id);
|
|
CREATE INDEX map_runtime_bindings_map_asset_id_idx ON map_runtime_bindings(map_asset_id);
|
|
CREATE INDEX map_runtime_bindings_tile_release_id_idx ON map_runtime_bindings(tile_release_id);
|
|
CREATE INDEX map_runtime_bindings_course_set_id_idx ON map_runtime_bindings(course_set_id);
|
|
CREATE INDEX map_runtime_bindings_course_variant_id_idx ON map_runtime_bindings(course_variant_id);
|
|
CREATE INDEX map_runtime_bindings_status_idx ON map_runtime_bindings(status);
|
|
|
|
CREATE TRIGGER map_runtime_bindings_set_updated_at
|
|
BEFORE UPDATE ON map_runtime_bindings
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
ALTER TABLE event_releases
|
|
ADD COLUMN runtime_binding_id UUID REFERENCES map_runtime_bindings(id) ON DELETE SET NULL;
|
|
|
|
CREATE INDEX event_releases_runtime_binding_id_idx ON event_releases(runtime_binding_id);
|
|
|
|
COMMIT;
|