# 项目问题报告 > 生成时间:2026-03-03 > 基于 commit `0d9dffa` 的代码分析 --- ## 🔴 高危问题(可能导致实盘出错) ### P1:数据库从未真正迁移到云端 **现象**:你以为整个系统已经跑在 Cloud SQL 上,实际上只有 `agg_trades` 原始成交数据在双写。其他核心数据全在**本地 PG(127.0.0.1)**。 | 数据表 | 本地 PG | Cloud SQL | |-------|---------|-----------| | `agg_trades`(原始成交) | ✅ | ✅ 双写 | | `signal_indicators`(信号输出) | ✅ | ❌ 没有 | | `paper_trades`(模拟盘) | ✅ | ❌ 没有 | | `rate_snapshots`(费率快照) | ✅ | ❌ 没有 | | `market_indicators`(市场数据) | ✅ | ❌ 没有 | | `live_trades`(实盘交易) | ❌ | ✅ 只在云端 | | `live_config` / `live_events` | ❌ | ✅ 只在云端 | **最致命的问题**:`live_executor.py` 和 `risk_guard.py` 默认连 Cloud SQL(`DB_HOST=10.106.0.3`),但 `signal_engine.py` 只把信号写到本地 PG。这意味着: - 实盘执行器读取的 `signal_indicators` 表在 Cloud SQL 里**可能是空的** - 风控模块监控的 `live_trades` 和信号引擎写的数据完全在两个不同的数据库里 **影响**:实盘交易链路存在断裂风险,需立即核查服务器上各进程实际连接的数据库地址。 **修复方向**:统一所有进程连接到 Cloud SQL,或统一连接到本地 PG(通过 Cloud SQL Auth Proxy)。 --- ### P2:`users` 表双定义字段不一致 `db.py` 和 `auth.py` 各自定义了一个 `users` 表,字段不同: | 字段 | db.py 版本 | auth.py 版本 | |------|-----------|-------------| | `email` | ✅ | ✅ | | `password_hash` | ✅ | ✅ | | `role` | ✅ | ✅ | | `created_at` | ✅ | ✅ | | `discord_id` | ❌ | ✅ | | `banned` | ❌ | ✅ | FastAPI 启动时先跑 `init_schema()`(db.py 版),再跑 `ensure_auth_tables()`(auth.py 版),因为 `CREATE TABLE IF NOT EXISTS` 第一次成功后就不再执行,**实际创建的是缺少 `discord_id` 和 `banned` 字段的旧版本**。 **影响**:封禁用户功能(`banned` 字段)在新装环境下可能失效。 --- ### P3:`signal_indicators` 表 INSERT 包含 `strategy` 字段但 schema 没有 `save_indicator()` 函数向 `signal_indicators` 插入数据时包含 `strategy` 字段(`signal_engine.py:697`),但 `SCHEMA_SQL` 里的建表语句没有这个字段(`db.py:205-224`)。 **影响**:在全新环境初始化后,信号引擎写入会报列不存在的错误。 --- ## 🟡 中危问题(影响稳定性和维护) ### P4:`requirements.txt` 严重不完整 文件只列了 5 个包,实际运行还需要: | 缺失依赖 | 用于 | |---------|------| | `asyncpg` | FastAPI 异步数据库 | | `psycopg2-binary` | 同步数据库(signal_engine 等) | | `aiohttp` | live_executor、risk_guard | | `websockets` 或 `httpx` | agg_trades_collector WS 连接 | | `psutil` | 已在文件里,但版本未锁定 | **影响**:新机器部署直接失败。 --- ### P5:`market_indicators` 和 `liquidations` 表不在主 schema 中 这两张表由各自的 collector 进程单独创建,不在 `init_schema()` 里。如果 collector 没跑过,signal_engine 查这两张表时会报错(会降级为默认中间分,不会崩溃,但数据不准)。 --- ### P6:没有 CI/CD,没有自动化测试 - 代码变更完全靠人工验证 - 策略逻辑(`evaluate_signal`)没有任何单元测试,重构风险极高 - 部署流程:手动 ssh + git pull + pm2 restart --- ## 🟠 安全风险 ### P7:测试网密码硬编码在源代码里 三个文件里都有: ```python os.getenv("PG_PASS", "arb_engine_2026") # db.py:19 os.getenv("DB_PASSWORD", "arb_engine_2026") # live_executor.py:44 os.getenv("DB_PASSWORD", "arb_engine_2026") # risk_guard.py:42 ``` 代码一旦泄露(GitHub public、截图等),测试网数据库直接裸奔。 ### P8:JWT Secret 有测试网默认值 ```python _jwt_default = "arb-engine-jwt-secret-v2-2026" if _TRADE_ENV == "testnet" else None ``` 如果生产环境 `TRADE_ENV` 没有正确设置,会静默使用这个已知 secret,所有 JWT 都可伪造。 --- ## 🔵 架构债务(长期) ### P9:三套数据库连接配置并存,极易混淆 | 配置方式 | 使用的进程 | 默认连哪 | |---------|----------|---------| | `db.py` 的 `PG_HOST` | main.py、signal_engine、collectors | `127.0.0.1`(本地) | | 进程内 `DB_HOST` | live_executor、risk_guard、position_sync | `10.106.0.3`(Cloud SQL) | | `market_data_collector.py` 内 `PG_HOST` | market_data_collector | `127.0.0.1`(本地) | 没有统一的连接配置入口,每个进程各自读各自的环境变量,迁移时极容易漏改。 ### P10:前端轮询压力 `/api/rates` 每 2 秒轮询一次,用户多了服务器压力线性增长。目前 3 秒缓存有一定缓冲,但没有限流保护。 --- ## 📋 建议优先级 | 优先级 | 任务 | |-------|------| | 🔴 立即 | 登服务器确认各进程实际连的数据库地址,核查实盘链路是否完整 | | 🔴 立即 | 补全 `signal_indicators` 表的 `strategy` 字段 | | 🔴 本周 | 统一数据库连接配置,所有进程用同一套环境变量 | | 🟡 本周 | 修复 `users` 表双定义问题,合并到 auth.py 版本 | | 🟡 本周 | 补全 `requirements.txt` | | 🟠 本月 | 把硬编码密码移到 `.env` 文件,不进代码仓库 | | 🔵 长期 | 添加 signal_engine 核心逻辑的单元测试 | | 🔵 长期 | 配置 GitHub Actions 做基础 lint 和安全扫描 |