- Generate full AI-consumable docs (docs/ai/): system overview, architecture, module cheatsheet, API contracts, data model, build guide, decision log, glossary, and open questions (deep tier coverage) - Add PROBLEM_REPORT.md: categorized bug/risk summary - Add DETAILED_CODE_REVIEW.md: full line-by-line review of all 15 backend files, documenting 4 fatal issues, 5 critical deployment bugs, 4 security vulnerabilities, and 6 architecture defects with prioritized fix plan
146 lines
5.5 KiB
Markdown
146 lines
5.5 KiB
Markdown
# 项目问题报告
|
||
|
||
> 生成时间: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 和安全扫描 |
|