# topology_api/seed/seed_ghc01_to_ghc05.py """ Seed the topology database with GHC-01 through GHC-05 mission data. Idempotent: can be run multiple times safely. Usage: PYTHONPATH="d:/My Coding Project/KSP_Project" python topology_api/seed/seed_ghc01_to_ghc05.py """ import json from datetime import datetime, timezone from topology_api.db import write_cursor UTC = timezone.utc def ts(s): """Parse ISO timestamp string to datetime.""" return datetime.fromisoformat(s).replace(tzinfo=UTC) def seed(): with write_cursor() as cur: # ============================================================ # PHASE 0: Clean existing data (reverse dependency order) # ============================================================ cur.execute("DELETE FROM topology_connections") cur.execute("DELETE FROM component_states") cur.execute("DELETE FROM component_versions") cur.execute("DELETE FROM ports") cur.execute("DELETE FROM components") cur.execute("DELETE FROM mission_events") cur.execute("DELETE FROM missions") cur.execute("DELETE FROM bases") print("Cleared existing data.") # ============================================================ # PHASE 1: Base # ============================================================ cur.execute(""" INSERT INTO bases (id, code, name, description) VALUES (gen_random_uuid(), 'guanghan', '广寒基地', '月球东方海常驻月面基地') ON CONFLICT (code) DO UPDATE SET name = EXCLUDED.name RETURNING id """) base_id = cur.fetchone()["id"] print(f"Base: guanghan ({base_id})") # ============================================================ # PHASE 2: Missions # ============================================================ mission_specs = [ ("BL-01", "冰轮部署任务-01"), ("GHC-01", "广寒基地建设任务-01"), ("JC-01", "金蟾部署任务-01"), ("BL-02", "冰轮部署任务-02"), ("GHC-02", "广寒基地建设任务-02"), ("GHC-03", "广寒基地建设任务-03"), ("BL-03", "冰轮部署任务-03"), ("GHC-04", "广寒基地建设任务-04"), ("GHC-05", "广寒基地建设任务-05"), ] mission_ids = {} for code, title in mission_specs: cur.execute(""" INSERT INTO missions (id, base_id, code, title, occurrence_status) VALUES (gen_random_uuid(), %(base)s, %(code)s, %(title)s, 'occurred') ON CONFLICT (base_id, code) DO UPDATE SET title = EXCLUDED.title RETURNING id """, {"base": base_id, "code": code, "title": title}) mission_ids[code] = cur.fetchone()["id"] print(f"Missions: {len(mission_ids)}") # ============================================================ # PHASE 3: Mission Events # ============================================================ def add_event(mission_code, effective_at, event_order, event_type, title, details=None, source_ref=None): cur.execute(""" INSERT INTO mission_events (id, mission_id, effective_at, event_order, event_type, title, details, source_ref) VALUES (gen_random_uuid(), %(mid)s, %(at)s, %(ord)s, %(typ)s, %(title)s, %(det)s, %(ref)s) ON CONFLICT (mission_id, effective_at, event_order) DO NOTHING RETURNING id """, { "mid": mission_ids[mission_code], "at": effective_at, "ord": event_order, "typ": event_type, "title": title, "det": json.dumps(details) if details else None, "ref": source_ref, }) row = cur.fetchone() if row: return row["id"] cur.execute(""" SELECT id FROM mission_events WHERE mission_id = %(mid)s AND effective_at = %(at)s AND event_order = %(ord)s """, {"mid": mission_ids[mission_code], "at": effective_at, "ord": event_order}) return cur.fetchone()["id"] events = {} # ---- BL-01 ---- events["BL-01_0"] = add_event("BL-01", ts("2024-04-19T22:58:00Z"), 0, "component_introduced", "冰轮一号着陆东方海", source_ref="Timeline.md BL-01") # ---- GHC-01 ---- events["GHC-01_0"] = add_event("GHC-01", ts("2024-06-16T07:23:00Z"), 0, "component_introduced", "广寒核心舱着陆东方海,引擎模块分离坠毁", source_ref="Timeline.md GHC-01") # ---- BL-02 ---- events["BL-02_0"] = add_event("BL-02", ts("2024-06-23T05:23:00Z"), 0, "component_introduced", "冰轮二号着陆东方海(核心舱以东112米)", source_ref="Timeline.md BL-02") # ---- JC-01 (mission only, no components in M1) ---- events["JC-01_0"] = add_event("JC-01", ts("2024-06-17T08:19:00Z"), 0, "component_introduced", "金蟾一号部署至LEO 400×400 km(轨道资产,M1不录入组件)", source_ref="Timeline.md JC-01") # ---- GHC-02 ---- events["GHC-02_0"] = add_event("GHC-02", ts("2024-07-01T10:37:00Z"), 0, "connection_established", "冰轮一号与冰轮二号通过柔性管道完成燃料连接", source_ref="Timeline.md GHC-02 EVA-1") # ---- GHC-03 ---- events["GHC-03_0"] = add_event("GHC-03", ts("2024-08-15T23:51:00Z"), 0, "component_introduced", "电力模块搭载广寒01模块着陆东方海", source_ref="Timeline.md GHC-03") events["GHC-03_1"] = add_event("GHC-03", ts("2024-08-17T00:00:00Z"), 1, "component_installed", "电力模块存储支架安装至电力模块北部", details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-6") events["GHC-03_2"] = add_event("GHC-03", ts("2024-08-18T00:00:00Z"), 2, "component_installed", "核反应堆、ISRU模块、采矿模块、矿石/燃料存储模块安装完成", details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-7/8") events["GHC-03_3"] = add_event("GHC-03", ts("2024-08-19T00:00:00Z"), 3, "connection_established", "核心舱南侧与电力模块北部建立结构直连", details={"time_precision": "date"}, source_ref="Timeline.md GHC-03 EVA-8") events["GHC-03_4"] = add_event("GHC-03", ts("2024-08-19T00:00:00Z"), 4, "state_changed", "核反应堆以15%功率开始运行", details={"time_precision": "date", "power_percent": 15}, source_ref="Timeline.md GHC-03") # ---- BL-03 ---- events["BL-03_0"] = add_event("BL-03", ts("2024-09-23T19:20:00Z"), 0, "component_introduced", "冰轮三号(首艘Block 2)着陆东方海", source_ref="Timeline.md BL-03") # ---- GHC-04 ---- events["GHC-04_0"] = add_event("GHC-04", ts("2024-10-25T00:00:00Z"), 0, "component_installed", "核燃料存储模块安装至电力模块东部", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-7") events["GHC-04_1"] = add_event("GHC-04", ts("2024-10-27T00:00:00Z"), 1, "component_installed", "离心机模块吊装至电力模块顶部安装位", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-9") events["GHC-04_2"] = add_event("GHC-04", ts("2024-10-31T00:00:00Z"), 2, "connection_removed", "冰轮一号与冰轮二号之间燃料连接断开(为跳跃做准备)", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-13") events["GHC-04_3"] = add_event("GHC-04", ts("2024-11-03T00:00:00Z"), 3, "state_changed", "核反应堆升至100%功率,ISRU全功率运行", details={"time_precision": "date", "power_percent": 100}, source_ref="Timeline.md GHC-04") events["GHC-04_4"] = add_event("GHC-04", ts("2024-11-05T00:00:00Z"), 4, "connection_established", "冰轮一号接入基地统一燃料/电力网络", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-14") events["GHC-04_5"] = add_event("GHC-04", ts("2024-11-06T00:00:00Z"), 5, "connection_established", "冰轮二号接入基地统一燃料/电力网络", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-15") events["GHC-04_6"] = add_event("GHC-04", ts("2024-11-08T00:00:00Z"), 6, "connection_established", "冰轮三号接入基地统一燃料/电力网络", details={"time_precision": "date"}, source_ref="Timeline.md GHC-04 EVA-16") # ---- GHC-05 ---- events["GHC-05_0"] = add_event("GHC-05", ts("2024-12-14T04:21:00Z"), 0, "component_introduced", "吴刚二号着陆东方海广寒基地(手动模式)", source_ref="Timeline.md GHC-05") events["GHC-05_1"] = add_event("GHC-05", ts("2024-12-23T01:11:00Z"), 1, "component_introduced", "广寒03模块(温室+居住舱段一号+居住舱段二号+实验舱段)由冰轮三号运抵月面", source_ref="Timeline.md GHC-05") events["GHC-05_2"] = add_event("GHC-05", ts("2024-12-26T00:00:00Z"), 2, "connection_removed", "核心舱南侧与电力模块北部结构直连断开(为舱段安装腾出三号位)", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-8") events["GHC-05_3"] = add_event("GHC-05", ts("2024-12-27T00:00:00Z"), 3, "component_installed", "温室舱段安装至核心舱四号位(西侧),手动展开至工作构型", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-9") events["GHC-05_4"] = add_event("GHC-05", ts("2024-12-28T00:00:00Z"), 4, "component_installed", "居住舱段一号安装至核心舱三号位(南侧),电力模块经加压走道连接至居住舱段一号远端", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-10") events["GHC-05_5"] = add_event("GHC-05", ts("2024-12-29T00:00:00Z"), 5, "component_installed", "居住舱段二号安装至核心舱一号位(北侧)", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-11") events["GHC-05_6"] = add_event("GHC-05", ts("2024-12-30T00:00:00Z"), 6, "component_installed", "实验舱段安装至核心舱二号位(东侧),启动航电和环控回路", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-12") events["GHC-05_7"] = add_event("GHC-05", ts("2024-12-31T00:00:00Z"), 7, "connection_established", "吴刚二号通过加压走道连接至温室舱段远端接口", details={"time_precision": "date"}, source_ref="Timeline.md GHC-05 EVA-13") events["GHC-05_8"] = add_event("GHC-05", ts("2025-01-02T00:00:00Z"), 8, "state_changed", "核反应堆功率调整至30%,全基地整合验证完成", details={"time_precision": "date", "power_percent": 30}, source_ref="Timeline.md GHC-05 EVA-15") print(f"Events: {len(events)}") # ============================================================ # PHASE 4: Components # ============================================================ def add_component(component_key, component_type, introduced_event_key, metadata=None): cur.execute(""" INSERT INTO components (id, base_id, component_key, component_type, introduced_by_event_id, metadata) VALUES (gen_random_uuid(), %(base)s, %(key)s, %(typ)s, %(ev)s, %(meta)s) ON CONFLICT (base_id, component_key) DO NOTHING RETURNING id """, { "base": base_id, "key": component_key, "typ": component_type, "ev": events[introduced_event_key], "meta": json.dumps(metadata) if metadata else None, }) row = cur.fetchone() if row: return row["id"] cur.execute( "SELECT id FROM components WHERE base_id = %(base)s AND component_key = %(key)s", {"base": base_id, "key": component_key}) return cur.fetchone()["id"] comp = {} comp["core_cabin"] = add_component("core_cabin", "module", "GHC-01_0", metadata={"dryMassT": 28.2, "batteryKwh": 50, "dockingNodes": 4}) comp["binglun_1"] = add_component("binglun_1", "vehicle", "BL-01_0", metadata={"block": 1, "role": "fuel_transport"}) comp["binglun_2"] = add_component("binglun_2", "vehicle", "BL-02_0", metadata={"block": 1, "role": "fuel_transport"}) comp["power_module_hub"] = add_component("power_module_hub", "node", "GHC-03_0") comp["power_storage_rack"] = add_component("power_storage_rack", "equipment", "GHC-03_1") comp["nuclear_reactor"] = add_component("nuclear_reactor", "equipment", "GHC-03_2") comp["isru_module"] = add_component("isru_module", "equipment", "GHC-03_2") comp["mining_module"] = add_component("mining_module", "equipment", "GHC-03_2") comp["ore_fuel_storage"] = add_component("ore_fuel_storage", "equipment", "GHC-03_2") comp["binglun_3"] = add_component("binglun_3", "vehicle", "BL-03_0", metadata={"block": 2, "role": "fuel_transport"}) comp["fuel_storage_mod"] = add_component("fuel_storage_mod", "equipment", "GHC-04_0") comp["centrifuge_mod"] = add_component("centrifuge_mod", "equipment", "GHC-04_1") comp["habitat_1"] = add_component("habitat_1", "module", "GHC-05_1", metadata={"capacity": 4, "sleepBags": 2}) comp["habitat_2"] = add_component("habitat_2", "module", "GHC-05_1", metadata={"capacity": 4, "sleepBags": 2}) comp["greenhouse"] = add_component("greenhouse", "module", "GHC-05_1", metadata={"foldingArms": 4}) comp["lab_module"] = add_component("lab_module", "module", "GHC-05_1", metadata={"zones": 3}) comp["wugang_2"] = add_component("wugang_2", "vehicle", "GHC-05_0", metadata={"block": 2, "type": "lunar_lander"}) print(f"Components: {len(comp)}") # ============================================================ # PHASE 5: Component Versions # ============================================================ def add_version(component_key, event_key, display_name, **kwargs): cid = comp[component_key] cur.execute(""" INSERT INTO component_versions (id, component_id, display_name, summary, description, length_m, width_m, height_m, diameter_m, mass_t, detail_url, properties, valid_from, started_by_event_id) VALUES (gen_random_uuid(), %(cid)s, %(name)s, %(sum)s, %(desc)s, %(len)s, %(wid)s, %(hei)s, %(dia)s, %(mass)s, %(url)s, %(props)s, (SELECT effective_at FROM mission_events WHERE id = %(ev)s), %(ev)s) ON CONFLICT DO NOTHING """, { "cid": cid, "name": display_name, "sum": kwargs.get("summary"), "desc": kwargs.get("description"), "len": kwargs.get("length_m"), "wid": kwargs.get("width_m"), "hei": kwargs.get("height_m"), "dia": kwargs.get("diameter_m"), "mass": kwargs.get("mass_t"), "url": kwargs.get("detail_url"), "props": json.dumps(kwargs.get("properties")) if kwargs.get("properties") else None, "ev": events[event_key], }) add_version("core_cabin", "GHC-01_0", "广寒核心舱", summary="广寒基地核心中枢,四向安装节点", description="核心舱本体干重28.2吨,搭载2.5吨维生资源。配备4个标准安装节点和50kWh蓄电池组。", mass_t=28.2, detail_url="/home/mission/Guanghan_Program/GHC-01") add_version("binglun_1", "BL-01_0", "冰轮一号", summary="首艘冰轮着陆器,Block 1,GHC-04后ISRU已关闭,转为专职燃料运输", detail_url="/home/Spacecraft/Binglun_Lander") add_version("binglun_2", "BL-02_0", "冰轮二号", summary="第二艘冰轮着陆器,Block 1,专职燃料运输", detail_url="/home/Spacecraft/Binglun_Lander") add_version("power_module_hub", "GHC-03_0", "电力模块安装节点", summary="十字型四向安装节点,电力模块中枢", description="电力模块是独立十字结构,中心为四向安装节点。北部连接存储支架和加压走道模块,南部连接核反应堆,东部连接核燃料存储模块和离心机模块,西部连接ISRU、采矿模块和矿石/燃料存储模块。四个方向顶部各安装一组大型折叠散热面板。") add_version("power_storage_rack", "GHC-03_1", "电力模块存储支架") add_version("nuclear_reactor", "GHC-03_2", "核反应堆", summary="广寒基地主电力来源,GHC-05后以30%功率运行", properties={"powerPercent": 30}) add_version("isru_module", "GHC-03_2", "ISRU 模块", summary="基地级原位资源利用设备,负责氢氧燃料生产") add_version("mining_module", "GHC-03_2", "采矿模块", summary="月面矿石采集设备,含采矿车和传送系统") add_version("ore_fuel_storage", "GHC-03_2", "矿石/燃料存储模块", summary="矿石原料和成品氢氧燃料的存储设施") add_version("binglun_3", "BL-03_0", "冰轮三号", summary="首艘Block 2冰轮着陆器,加宽燃料罐,接口与Block 1完全兼容", detail_url="/home/Spacecraft/Binglun_Lander") add_version("fuel_storage_mod", "GHC-04_0", "核燃料存储模块", summary="核反应堆燃料组件存储及废料暂存") add_version("centrifuge_mod", "GHC-04_1", "离心机模块", summary="科学实验离心机,安装于电力模块顶部") add_version("habitat_1", "GHC-05_4", "居住舱段一号", summary="核心舱三号位(南侧),4铺位+2睡袋,远端连接电力模块", description="运输构型高2.7m、长6.2m、宽5.0m(12.2吨)。展开后高3.2m、长6.2m、宽7.6m,含4个折叠铺位和2个睡袋挂点。", length_m=6.2, width_m=7.6, height_m=3.2, mass_t=12.2, properties={"capacity": 4, "sleepBags": 2, "transportHeightM": 2.7, "transportLengthM": 6.2, "transportWidthM": 5.0}) add_version("habitat_2", "GHC-05_5", "居住舱段二号", summary="核心舱一号位(北侧),4铺位+2睡袋", description="运输构型与居住舱段一号相同。展开后高3.2m、长6.2m、宽7.6m。展开过程中西侧折叠臂曾出现短暂卡滞,手动辅助释放后正常。", length_m=6.2, width_m=7.6, height_m=3.2, mass_t=12.2, properties={"capacity": 4, "sleepBags": 2}) add_version("greenhouse", "GHC-05_3", "温室舱段", summary="核心舱四号位(西侧),4组折叠臂展开的透明面板,远端连接吴刚二号", description="运输构型高2.8m、长8.7m、宽5.0m(13.5吨)。手动展开折叠框架后达到工作构型高3.2m、长8.7m、宽7.4m。配备自动灌溉系统和温度传感器。", length_m=8.7, width_m=7.4, height_m=3.2, mass_t=13.5, properties={"foldingArms": 4, "transportHeightM": 2.8, "transportLengthM": 8.7, "transportWidthM": 5.0}) add_version("lab_module", "GHC-05_6", "实验舱段", summary="核心舱二号位(东侧),3个可调温区,四个舱段中质量最大", description="运输构型高2.7m、长7.5m、宽5.0m(14.2吨)。展开后高3.2m、长7.5m、宽7.5m。含生物培养、材料科学、地质分析三个独立温区。", length_m=7.5, width_m=7.5, height_m=3.2, mass_t=14.2, properties={"zones": 3, "zoneNames": ["生物培养", "材料科学", "地质分析"], "transportHeightM": 2.7, "transportLengthM": 7.5, "transportWidthM": 5.0}) add_version("wugang_2", "GHC-05_0", "吴刚二号", summary="首艘Block 2吴刚月面着陆器,GHC-05乘组搭乘抵达,高度雷达故障后手动着陆", detail_url="/home/Spacecraft/Wugang_Lunar_Lander", properties={"block": 2, "landingMode": "manual"}) print("Versions created") # ============================================================ # PHASE 6: Ports # ============================================================ def add_port(component_key, port_key, display_name, direction=None, interface_type="structural"): cur.execute(""" INSERT INTO ports (id, component_id, port_key, display_name, direction, interface_type) VALUES (gen_random_uuid(), %(cid)s, %(pkey)s, %(dname)s, %(dir)s, %(iface)s) ON CONFLICT (component_id, port_key) DO NOTHING """, { "cid": comp[component_key], "pkey": port_key, "dname": display_name, "dir": direction, "iface": interface_type, }) # Core cabin: 4 docking nodes for d, name in [("north", "一号位(北)"), ("east", "二号位(东)"), ("south", "三号位(南)"), ("west", "四号位(西)")]: add_port("core_cabin", d, name, d) # Power module hub: 4 directional nodes for d in ["north", "east", "south", "west"]: add_port("power_module_hub", d, f"{'北东南西'['north east south west'.split().index(d)]}部安装口", d) # Power sub-equipment for key in ["power_storage_rack", "nuclear_reactor", "isru_module", "mining_module", "ore_fuel_storage", "fuel_storage_mod", "centrifuge_mod"]: add_port(key, "mount", "安装接口") # Habitat modules: core-side + distal add_port("habitat_1", "core", "核心端接口", "north") add_port("habitat_1", "distal", "远端对接口", "south") add_port("habitat_2", "core", "核心端接口", "south") # Greenhouse: core-side + distal add_port("greenhouse", "core", "核心端接口", "east") add_port("greenhouse", "distal", "远端对接口", "west") # Lab: core-side only add_port("lab_module", "core", "核心端接口", "west") # Wugang #2 add_port("wugang_2", "dock", "对接口", interface_type="docking") # Bingluns: fuel and power ports for bl in ["binglun_1", "binglun_2", "binglun_3"]: add_port(bl, "fuel_port", "燃料接口", interface_type="fuel") add_port(bl, "power_port", "供电接口", interface_type="power") print("Ports created") # ============================================================ # PHASE 7: Connections # ============================================================ def add_connection(comp_a, port_a, comp_b, port_b, conn_type, event_key, valid_to_event=None): cur.execute( "SELECT id FROM ports WHERE component_id = %(cid)s AND port_key = %(pkey)s", {"cid": comp[comp_a], "pkey": port_a}) pa = cur.fetchone() cur.execute( "SELECT id FROM ports WHERE component_id = %(cid)s AND port_key = %(pkey)s", {"cid": comp[comp_b], "pkey": port_b}) pb = cur.fetchone() if not pa or not pb: print(f" WARN: port not found for {comp_a}.{port_a} <-> {comp_b}.{port_b}") return cur.execute( "SELECT effective_at FROM mission_events WHERE id = %(ev)s", {"ev": events[event_key]}) valid_from = cur.fetchone()["effective_at"] valid_to = None ended_by_id = None if valid_to_event: cur.execute( "SELECT effective_at, id FROM mission_events WHERE id = %(ev)s", {"ev": events[valid_to_event]}) row = cur.fetchone() if row: valid_to = row["effective_at"] ended_by_id = row["id"] cur.execute(""" INSERT INTO topology_connections (id, base_id, port_a_id, port_b_id, connection_type, valid_from, valid_to, established_by_event_id, ended_by_event_id) VALUES (gen_random_uuid(), %(base)s, %(pa)s, %(pb)s, %(ct)s, %(vf)s, %(vt)s, %(ev)s, %(end_ev)s) ON CONFLICT DO NOTHING """, { "base": base_id, "pa": pa["id"], "pb": pb["id"], "ct": conn_type, "vf": valid_from, "vt": valid_to, "ev": events[event_key], "end_ev": ended_by_id, }) # GHC-02: Binglun #1 <-> #2 historical fuel connection add_connection("binglun_1", "fuel_port", "binglun_2", "fuel_port", "fuel", "GHC-02_0", valid_to_event="GHC-04_2") # GHC-03: Core <-> Power (historical, removed in GHC-05) add_connection("core_cabin", "south", "power_module_hub", "north", "structural_mount", "GHC-03_3", valid_to_event="GHC-05_2") # GHC-03: Power sub-module connections add_connection("power_module_hub", "north", "power_storage_rack", "mount", "structural_mount", "GHC-03_1") add_connection("power_module_hub", "south", "nuclear_reactor", "mount", "structural_mount", "GHC-03_2") add_connection("power_module_hub", "west", "isru_module", "mount", "structural_mount", "GHC-03_2") add_connection("power_module_hub", "west", "mining_module", "mount", "structural_mount", "GHC-03_2") add_connection("power_module_hub", "west", "ore_fuel_storage", "mount", "structural_mount", "GHC-03_2") # GHC-04: Power east-side equipment add_connection("power_module_hub", "east", "fuel_storage_mod", "mount", "structural_mount", "GHC-04_0") add_connection("power_module_hub", "east", "centrifuge_mod", "mount", "structural_mount", "GHC-04_1") # GHC-04: Binglun fuel & power network bl_events = {"binglun_1": "GHC-04_4", "binglun_2": "GHC-04_5", "binglun_3": "GHC-04_6"} for bl, ev in bl_events.items(): add_connection(bl, "fuel_port", "power_module_hub", "west", "fuel", ev) add_connection(bl, "power_port", "power_module_hub", "west", "power", ev) # GHC-05: Core <-> four new modules (structural) add_connection("core_cabin", "north", "habitat_2", "core", "structural_mount", "GHC-05_5") add_connection("core_cabin", "east", "lab_module", "core", "structural_mount", "GHC-05_6") add_connection("core_cabin", "south", "habitat_1", "core", "structural_mount", "GHC-05_4") add_connection("core_cabin", "west", "greenhouse", "core", "structural_mount", "GHC-05_3") # GHC-05: Pressurized passages add_connection("greenhouse", "distal", "wugang_2", "dock", "pressurized_passage", "GHC-05_7") add_connection("habitat_1", "distal", "power_module_hub", "north", "pressurized_passage", "GHC-05_4") print("Connections created") # ============================================================ # PHASE 8: Component States # ============================================================ def add_state(component_key, state_kind, state_value, event_key, details=None): cur.execute(""" INSERT INTO component_states (id, component_id, state_kind, state_value, details, valid_from, started_by_event_id) VALUES (gen_random_uuid(), %(cid)s, %(kind)s, %(val)s, %(det)s, (SELECT effective_at FROM mission_events WHERE id = %(ev)s), %(ev)s) ON CONFLICT DO NOTHING """, {"cid": comp[component_key], "kind": state_kind, "val": state_value, "det": json.dumps(details) if details else None, "ev": events[event_key]}) # Lifecycle: installed for all components lifecycle_pairs = [ ("core_cabin", "GHC-01_0"), ("binglun_1", "BL-01_0"), ("binglun_2", "BL-02_0"), ("power_module_hub", "GHC-03_0"), ("power_storage_rack", "GHC-03_1"), ("nuclear_reactor", "GHC-03_2"), ("isru_module", "GHC-03_2"), ("mining_module", "GHC-03_2"), ("ore_fuel_storage", "GHC-03_2"), ("binglun_3", "BL-03_0"), ("fuel_storage_mod", "GHC-04_0"), ("centrifuge_mod", "GHC-04_1"), ("habitat_1", "GHC-05_1"), ("habitat_2", "GHC-05_1"), ("greenhouse", "GHC-05_1"), ("lab_module", "GHC-05_1"), ("wugang_2", "GHC-05_0"), ] for ck, ev in lifecycle_pairs: add_state(ck, "lifecycle", "installed", ev) # Operation: operational ops_pairs = [ ("core_cabin", "GHC-01_0"), ("binglun_1", "BL-01_0"), ("binglun_2", "BL-02_0"), ("binglun_3", "BL-03_0"), ("isru_module", "GHC-03_2"), ("mining_module", "GHC-03_2"), ("wugang_2", "GHC-05_0"), ] for ck, ev in ops_pairs: add_state(ck, "operation", "operational", ev) # Nuclear reactor states: 15% (GHC-03) -> 100% (GHC-04) -> 30% (GHC-05) add_state("nuclear_reactor", "operation", "operational", "GHC-03_4", details={"powerPercent": 15}) # Close 15% at GHC-04 full power cur.execute(""" UPDATE component_states SET valid_to = (SELECT effective_at FROM mission_events WHERE id = %(ev)s), ended_by_event_id = %(ev)s WHERE component_id = %(cid)s AND state_kind = 'operation' AND details @> '{\"powerPercent\": 15}' AND valid_to IS NULL """, {"ev": events["GHC-04_3"], "cid": comp["nuclear_reactor"]}) # Insert 100% add_state("nuclear_reactor", "operation", "operational", "GHC-04_3", details={"powerPercent": 100}) # Close 100% at GHC-05 power adjustment cur.execute(""" UPDATE component_states SET valid_to = (SELECT effective_at FROM mission_events WHERE id = %(ev)s), ended_by_event_id = %(ev)s WHERE component_id = %(cid)s AND state_kind = 'operation' AND details @> '{\"powerPercent\": 100}' AND valid_to IS NULL """, {"ev": events["GHC-05_8"], "cid": comp["nuclear_reactor"]}) # Insert 30% (current) add_state("nuclear_reactor", "operation", "operational", "GHC-05_8", details={"powerPercent": 30}) print("States created") print("\nSeed complete!") print(f" Base: 1") print(f" Missions: {len(mission_ids)}") print(f" Events: {len(events)}") print(f" Components: {len(comp)}") if __name__ == "__main__": seed()