17 KiB
KSP Operation Hangar 交接文档
最后更新:2026-05-28
本文档介绍 KSP Operation Hangar 后台项目本身,不包含 Wiki.js 页面生产、图片资产上传、Wiki 发布脚本和 KSP_wiki 内容维护。Wiki 相关工作流见 handover/ksp_wiki_handover.md。
1. 项目定位
KSP Operation Hangar 是一个 Flask + SQLAlchemy 的 KSP 数据整理与任务运营后台。项目最初用于把 Excel 工作簿中的发动机、通信部件、燃料箱和载具成本数据导入数据库,随后扩展出任务资产、资产日志、状态节点和 Mission Ops 预览页面。
项目的主要目标是:
- 将分散的 KSP Excel 数据转为可查询、可编辑、可导入的数据库记录。
- 提供 Web 后台管理 Engine、Communication、Tank、Vehicle Cost 等资料。
- 提供 Fuel Converter 工具和 API,支持燃料体积与质量换算。
- 管理任务资产、任务日志和状态节点,用于构建任务运营视图。
- 通过 Mission Ops 页面按模拟时间查看任务状态、地点分布、未来事件和时间线。
当前项目更接近个人/小团队内部管理后台,不是面向公网的完整生产系统。鉴权、审计、自动化测试和正式权限隔离尚未完成。
2. 代码结构总览
KSP_Project/
├── main.py
├── app/
│ ├── __init__.py
│ ├── config.py
│ ├── extensions.py
│ ├── models.py
│ ├── routes/
│ │ ├── api.py
│ │ └── web.py
│ ├── services/
│ │ ├── fuel_conversion.py
│ │ ├── log_book_importer.py
│ │ ├── workbook_importer.py
│ │ └── workbook_inspector.py
│ ├── static/
│ │ └── styles.css
│ └── templates/
├── migrations/
│ └── versions/
├── scripts/
│ ├── import_log_book.py
│ ├── import_workbook.py
│ └── inspect_workbook.py
├── prototypes/
│ └── mission-ops/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example
非后台范围说明:
data/wiki/、data/KSP/wiki-*、scripts/wiki_*.py、根目录vulture_shuttle*.html/md属于 Wiki 工作流,见另一份交接文档。prototypes/mission-ops/是早期静态 Mission Ops 原型,虽然不是正式 Flask 页面,但可作为 UI 设计参考。
3. 运行入口与应用初始化
3.1 入口文件
入口是 main.py:
- 调用
app.create_app()创建 Flask app。 - 本地直接运行时监听
0.0.0.0:APP_PORT。 - 当
APP_ENV=development时启用 Flask debug。
常用本地命令:
pip install -r requirements.txt
python main.py
默认访问地址:
http://127.0.0.1:8000/
3.2 Flask app factory
app/__init__.py 中的 create_app() 负责:
- 创建 Flask 应用。
- 加载
app.config.Config。 - 初始化
db与migrate。 - 注册
web_bp和api_bp。 - 注册 Jinja filter:
fmt_decimal。
fmt_decimal 用于在模板中格式化 Decimal,默认保留 4 位并去掉尾随零。
3.3 扩展对象
app/extensions.py 定义全局扩展对象:
db = SQLAlchemy()migrate = Migrate()
不要在模型或路由中重新创建扩展实例,统一从 app.extensions 导入。
4. 依赖
requirements.txt 当前依赖:
Flask>=3.1,<4.0
Flask-SQLAlchemy>=3.1,<4.0
Flask-Migrate>=4.0,<5.0
python-dotenv>=1.0,<2.0
psycopg[binary]>=3.2,<4.0
openpyxl>=3.1,<4.0
gunicorn>=23.0,<24.0
用途说明:
- Flask:Web 框架。
- Flask-SQLAlchemy:ORM。
- Flask-Migrate:Alembic 迁移集成。
- python-dotenv:读取
.env。 - psycopg:PostgreSQL 驱动。
- openpyxl:读取 Excel 工作簿。
- gunicorn:容器/生产运行 WSGI server。
5. 配置读取方式
5.1 配置入口
配置逻辑在 app/config.py。
启动时会执行:
load_dotenv(BASE_DIR / ".env")
也就是说,项目根目录的 .env 是运行时真实配置来源;.env.example 只提供安全示例,不包含真实凭据。
5.2 数据库连接
_build_database_uri() 读取下列变量:
PGHOST
PGPORT
PGUSER
PGPASSWORD
PGDATABASE
如果这些变量全部存在,则拼接 PostgreSQL URI:
postgresql+psycopg://<user>:<password>@<host>:<port>/<database>
如果任一 PostgreSQL 配置缺失,则回退到本地 SQLite:
instance/ksp.sqlite3
注意:生产或 NAS 部署应使用 PostgreSQL。SQLite 主要用于临时本地开发。
5.3 应用配置项
Config 支持的主要变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
APP_ENV |
development |
控制 debug 等环境行为 |
APP_PORT |
8000 |
本地 Flask 启动端口,也被 docker-compose 用作宿主机端口 |
APP_SECRET_KEY |
development-only-secret-key |
Flask session secret |
PROJECT_TITLE |
KSP Data Hangar |
页面标题/项目展示名 |
WORKBOOK_PATH |
KSP Engine Tweak Chart.xlsx |
默认 KSP Excel 工作簿路径 |
SQLALCHEMY_ECHO |
false |
是否输出 SQL 日志 |
.env.example 还包含 Wiki.js 相关变量,但后台应用本身只依赖 PGDATABASE,不直接使用 WIKIDATABASE 或 Wiki 登录信息。
6. 数据模型
模型位于 app/models.py。所有核心表使用 UUID 主键;多数模型继承 TimestampMixin,提供 created_at 和 updated_at。
6.1 基础数据模型
| 模型 | 表 | 用途 |
|---|---|---|
EngineFamily |
engine_families |
发动机家族/基础型号 |
EngineVariant |
engine_variants |
发动机配置项,如燃料、环境、推力、比冲等 |
CommunicationPart |
communication_parts |
通信部件、天线类型、范围、功耗等 |
TankSpec |
tank_specs |
燃料箱质量、湿重、干重、体积与质量比 |
VehicleCost |
vehicle_costs |
载具发射成本或价格数据 |
发动机数据注意事项:
- 源 Excel 中
Engine + Config Name不是可靠唯一键。 - 早期巡检发现 48 组
Engine + Config Name冲突。 - 即使加入 Fuel Type,仍有 19 组冲突。
- 因此数据库采用 UUID 主键,自然键只用于展示、筛选和告警。
6.2 任务资产模型
| 模型 | 表 | 用途 |
|---|---|---|
Asset |
assets |
任务资产,例如母舰、航天飞机、站点、基地 |
AssetLogEntry |
asset_log_entries |
资产日志,支持事件点与状态区间 |
AssetStateNode |
asset_state_nodes |
状态区间内的时间节点和细节说明 |
任务运营页面主要基于这三张表构建:
- 当前状态。
- 未来事件。
- 任务标签和地点分组。
- 状态板、地点板和时间线。
Asset.is_retired 用于排除退役资产。
7. 数据迁移
迁移目录:migrations/versions/
当前有 6 个迁移:
| 文件 | 作用 |
|---|---|
f1fa035d3afe_initial_schema.py |
初始 schema |
6c2a57f2b1e9_add_asset_log_tables.py |
增加资产日志表 |
f4f0c9c9426e_add_asset_state_nodes.py |
增加状态节点表 |
8bbf69ea2013_add_retired_flag_to_assets.py |
增加资产退役标记 |
0f1b9bb2156c_add_detail_to_asset_state_nodes.py |
状态节点增加 detail 字段 |
83be4d38636d_expand_communication_range_precision.py |
扩展通信距离精度 |
常用命令:
python -m flask --app main:app db upgrade
创建新迁移:
python -m flask --app main:app db migrate -m "message"
python -m flask --app main:app db upgrade
如果是首次初始化且没有 migrations/,才需要:
python -m flask --app main:app db init
8. Web 后台功能
Web 路由在 app/routes/web.py,蓝图名称为 web_bp。
8.1 Dashboard 与工具
| 路径 | 用途 |
|---|---|
/ |
Dashboard,展示项目模块与数据冲突统计 |
/fuel-converter |
燃料体积/质量换算页面 |
Dashboard 当前展示的冲突数固定为:
duplicate_conflicts=48duplicate_conflicts_with_fuel=19
8.2 Engine Catalog
| 路径 | 用途 |
|---|---|
/engines |
发动机列表、搜索、筛选、排序、分页 |
/engines/new |
新建发动机及初始配置 |
/engines/<uuid> |
发动机详情 |
/engines/<uuid>/edit |
编辑发动机家族和配置项 |
/engines/<uuid>/variants/add |
添加配置项 |
/engines/<uuid>/variants/<uuid>/delete |
删除配置项 |
/engines/<uuid>/delete |
删除发动机家族 |
相关模板:
engine_list.htmlengine_create.htmlengine_detail.htmlengine_edit.html
8.3 Communication / Tank / Vehicle
这三类资源使用类似 CRUD 模式:
| 资源 | 列表 | 新建 | 编辑 | 删除 |
|---|---|---|---|---|
| Communication | /communications |
/communications/new |
/communications/<uuid>/edit |
/communications/<uuid>/delete |
| Tank | /tanks |
/tanks/new |
/tanks/<uuid>/edit |
/tanks/<uuid>/delete |
| Vehicle | /vehicles |
/vehicles/new |
/vehicles/<uuid>/edit |
/vehicles/<uuid>/delete |
这些页面共用 resource_edit.html 做新增/编辑表单。
8.4 Mission Assets
| 路径 | 用途 |
|---|---|
/assets |
任务资产目录,支持模拟时间、搜索、筛选、排序、分页 |
/assets/new |
新建任务资产 |
/assets/<uuid> |
资产详情、日志列表、未来事件 |
/assets/<uuid>/edit |
编辑资产 |
/assets/<uuid>/delete |
删除资产及日志 |
/assets/import-log-book |
从 log_book.xlsx 导入资产日志 |
/assets/<uuid>/entries/new |
新增资产日志条目 |
/assets/<uuid>/entries/<uuid>/edit |
编辑资产日志条目与 State Nodes |
/assets/<uuid>/entries/<uuid>/delete |
删除资产日志条目 |
任务日志支持两类记录:
event:单点事件。state:状态区间,可带多个AssetStateNode。
资产详情页会根据模拟时间计算:
- 当前状态。
- 当前地点。
- 活跃/计划/历史状态。
- 未来事件,包括未来日志事件和未来 State Nodes。
8.5 Mission Ops 页面
Mission Ops 页面基于数据库中的 Asset/AssetLogEntry/AssetStateNode 实时构建,而不是静态原型。
| 路径 | 用途 |
|---|---|
/missions |
按 mission label 分组的任务列表 |
/mission-preview |
重定向到状态板 |
/mission-preview/status-board |
状态板,按运行状态分组 |
/mission-preview/location-board |
地点板,按地区/地点分组 |
/mission-preview/asset-log |
重定向到资产列表 |
/mission-preview/timeline |
时间线视图,支持 scale、范围、资产筛选 |
核心构建函数包括:
_load_assets_with_logs()_build_asset_snapshot()_build_mission_board_rows()_build_status_board_groups()_build_location_board_groups()_build_timeline_rows()
时间线支持自动或手动范围、按 day/month/year 等 scale 展示,并计算 state segments 与 event nodes。
9. API
API 路由在 app/routes/api.py,蓝图路径前缀为 /api/v1。
| 路径 | 方法 | 用途 |
|---|---|---|
/api/v1/health |
GET | 健康检查,返回 status=ok |
/api/v1/fuel-converter/fuels |
GET | 返回燃料密度因子 |
/api/v1/fuel-converter/convert |
GET/POST | 燃料体积/质量换算 |
Fuel Converter 的业务逻辑在 app/services/fuel_conversion.py。
10. 服务层与导入脚本
10.1 Fuel conversion
文件:app/services/fuel_conversion.py
主要能力:
list_fuel_factors():列出燃料密度因子。convert_value(mode, raw_value):在体积与质量之间换算。
实现使用 Decimal,避免浮点误差。
10.2 Workbook importer
文件:app/services/workbook_importer.py
导入对象:
- Engine Database。
- Communication。
- Tank Chart。
- KSP Vehicle Cost。
入口脚本:
python scripts/import_workbook.py
python scripts/import_workbook.py --replace
python scripts/import_workbook.py --path "path/to/workbook.xlsx"
--replace 会清空导入相关表并重新导入。对真实数据库执行前应确认备份。
10.3 Workbook inspector
文件:app/services/workbook_inspector.py
入口脚本:
python scripts/inspect_workbook.py
python scripts/inspect_workbook.py --path "path/to/workbook.xlsx"
用途:
- 列出工作表和行数。
- 检查 Engine Database 表头。
- 汇总 Work Env 枚举。
- 统计自然键冲突。
- 分析字段稳定性。
10.4 Log book importer
文件:app/services/log_book_importer.py
入口脚本:
python scripts/import_log_book.py
python scripts/import_log_book.py --path "path/to/log_book.xlsx"
导入逻辑:
- 默认读取
log_book.xlsx。 - 忽略
Overview和Modelsheet。 - 每个 sheet 对应一个 Asset。
- 按日期行解析事件与状态。
- 创建或更新
Asset、AssetLogEntry。 - 通过
LOG_BOOK_ASSET_SPECS补充已知资产类型和初始信息。
当前 LOG_BOOK_ASSET_SPECS 仍有硬编码,需要随新资产扩展。
11. 模板与前端
模板目录:app/templates/
主要模板:
base.html:页面外壳。dashboard.html:首页。fuel_converter.html:燃料换算工具。engine_*.html:发动机 CRUD。communication_list.html、tank_list.html、vehicle_list.html:基础资源列表。asset_list.html、asset_detail.html、asset_entry_form.html:任务资产与日志。mission_list.html:任务标签列表。mission_status_board_preview.html:状态板。mission_location_board_preview.html:地点板。mission_timeline_preview.html:时间线。
常用 partial:
_datetime_picker_field.html_mission_ops_tabs.html_mission_preview_controls.html_mission_preview_header.html_mission_upcoming_events.html
静态样式:app/static/styles.css。
当前前端为后台工具风格,未引入大型前端框架。
12. Docker 与部署
12.1 Dockerfile
Dockerfile 使用 python:3.12-slim,安装 requirements.txt,复制项目文件,默认运行:
gunicorn --bind 0.0.0.0:8000 main:app
12.2 docker-compose
docker-compose.yml 定义 web 服务:
env_file: .env- 宿主机端口:
${APP_PORT:-8000} - 容器端口:
8000 - restart policy:
unless-stopped
启动:
docker compose up --build
13. 当前已完成内容
- Flask app factory 与配置系统。
- PostgreSQL/SQLite 数据库连接。
- Alembic/Flask-Migrate 迁移体系。
- Engine/Communication/Tank/Vehicle 基础数据模型与 CRUD。
- Workbook 巡检和导入。
- Fuel Converter 页面与 API。
- Asset/AssetLogEntry/AssetStateNode 任务资产模型。
- Log Book 导入。
- Asset 详情页、日志编辑、State Nodes 编辑。
- Mission list、状态板、地点板、时间线页面。
- 未来事件展示与可跳转编辑。
- 表单验证错误弹窗和提交值保留。
- Dockerfile 与 docker-compose。
14. 已知问题与后续 TODO
14.1 数据和导入
- Engine 自然键冲突仍需人工理解和治理。
LOG_BOOK_ASSET_SPECS是硬编码,新增资产时需要扩展或改为配置化。- Workbook 导入缺少自动化测试和导入报告导出。
- 大规模重导入前需要备份,尤其是
--replace。
14.2 后台功能
- 缺少用户登录、权限控制和审计日志。
- CRUD 操作没有软删除和恢复机制。
- Mission Ops 当前以读取资产日志为主,缺少更完整的任务计划/排程实体。
- Mission labels、state labels 等多值字段仍是文本拆分,未来可规范化成表。
- 资产关系、母舰/随舰载具关系仍未建成结构化模型。
14.3 前端体验
- 样式仍集中在单一 CSS 文件。
- 前端表单校验较少,主要依赖后端验证。
- Mission Ops 时间线在数据量很大时可能需要性能优化。
- 原型目录中的静态页面应定期与正式 Flask 页面同步或归档。
14.4 工程质量
- 缺少 pytest 或其他自动化测试。
- 缺少 CI。
- 缺少 lint/format 固定流程。
- 缺少导入脚本的 dry-run 模式。
- 缺少数据库备份/恢复文档。
15. 新人接手建议
- 先阅读
app/config.py、app/__init__.py、app/models.py,理解配置、初始化和数据模型。 - 本地创建
.env,只使用示例键名,不提交真实凭据。 - 执行
python -m flask --app main:app db upgrade,确认 schema 到最新。 - 用
python scripts/inspect_workbook.py了解 Excel 源数据质量。 - 用
python scripts/import_workbook.py导入基础数据。 - 用
python scripts/import_log_book.py导入任务资产日志。 - 打开
/assets、/missions、/mission-preview/timeline,确认任务运营页面能从数据库生成内容。 - 开发新功能时优先复用
web.py里的表单解析、分页、时间处理和 Mission Ops 构建函数。
16. 安全注意事项
- 不要提交
.env。 - 不要在日志或终端输出真实数据库密码。
- 写路径验证前优先使用临时记录,避免污染真实任务数据。
- 使用
--replace导入前先确认数据库备份。 - Docker 生产部署前应更换
APP_SECRET_KEY,并补齐鉴权机制。