From 7f84471aca81324285d00142227ec2ca05835f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Sat, 4 Jul 2026 09:57:18 +0800 Subject: [PATCH] docs: development standards + test plan --- docs/DEVELOPMENT_STANDARDS.md | 196 ++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 docs/DEVELOPMENT_STANDARDS.md diff --git a/docs/DEVELOPMENT_STANDARDS.md b/docs/DEVELOPMENT_STANDARDS.md new file mode 100644 index 0000000..9f273bc --- /dev/null +++ b/docs/DEVELOPMENT_STANDARDS.md @@ -0,0 +1,196 @@ +# MoFin 开发规范 + +> 版本:1.0 | 日期:2026-07-03 | 维护:Sisyphus + Zhiwei + +--- + +## 一、代码结构 + +### 1.1 无重复代码 + +- **一个功能一个文件**。禁止出现两份同名/同功能的 `.py` 文件。 +- 公共逻辑抽取到 `mo_models.py` / `mo_data.py` / `mofin_db.py`,各脚本只调不写。 +- 每次新增功能前,先搜索是否已有类似实现。 + +### 1.2 文件职责 + +| 文件 | 职责 | 允许做的事 | +|------|------|-----------| +| `mo_models.py` | 统一数据模型 | `calc_total_assets`, `is_hk_stock`, `to_cny`, `get_hk_rate` | +| `mo_data.py` | 统一读取层 | `read_portfolio`, `read_decisions`, `read_watchlist` — 只读 DB | +| `mofin_db.py` | DB 层 | 建表、写函数、查询函数 — 所有 SQL 集中在这里 | +| `price_monitor.py` | 价格更新 | 从 API 拉价格,写入 holdings + portfolio_summary | +| `strategy_lifecycle.py` | 策略生命周期 | `regenerate_all` + quality gates | +| `scripts/` | 工具/一次性脚本 | 不通过 cron 调用的辅助工具 | + +### 1.3 禁止事项 + +- ❌ 在业务脚本里直接写 SQL(必须通过 `mofin_db.py`) +- ❌ 在业务脚本里直接 `json.load(open(...))` 读数据(必须通过 `mo_data.py`) +- ❌ 自己实现 `calc_total_assets` / `is_hk_stock`(必须用 `mo_models.py`) +- ❌ 自己实现 `read_portfolio` / `read_decisions` / `read_watchlist`(必须用 `mo_data.py`) +- ❌ 新增 JSON 数据文件(所有持久化数据必须走 DB) + +--- + +## 二、数据规范 + +### 2.1 币种 + +| 场景 | 港股 | A股 | +|------|------|-----| +| 个股 price/cost/stop_loss | HKD | CNY | +| `currency` 字段 | `'HKD'` | `'CNY'` | +| 总资产/总市值 | CNY(汇总时 × 汇率) | CNY | +| 个股 P&L 计算 | 同币种 `(price-cost)/cost` | 同币种 | +| API/报告输出 | 标注 `(HKD)` | 无标注 | + +**铁律**:禁止跨币种比较或加减。`calc_total_assets` / `calc_total_mv` 是唯一可以做币种转换的地方。 + +### 2.2 汇率 + +- 汇率必须通过 `get_hk_rate()` 获取(实时 API + 缓存) +- 禁止硬编码 `0.87` / `0.866` 等值(仅 `hk_rate.py` 内部兜底例外) +- 汇率 API 不可达时自动使用上次缓存值 + +### 2.3 数据源 + +- **唯一写入源**:`price_monitor.py` 是唯一的价格写入者 +- **DB 优先读取**:所有数据读取走 `mo_data.py` → DB +- **API 兜底**:DB 无数据时,`price_monitor` 从外部 API 拉取 +- **禁止各脚本各自拉 API** 写数据 + +--- + +## 三、DB 规范 + +### 3.1 表设计 + +- 新增表必须在 `mofin_db.py` 的 `init_all_tables()` 中定义 +- 新表必须有对应的 `write_*()` 函数和 `query_*()` 函数 +- 涉及币种的列必须有 `CHECK(currency IN ('CNY','HKD'))` 约束 +- `code` 列建议加 UNIQUE INDEX + +### 3.2 迁移 + +- 加列用 `ALTER TABLE ADD COLUMN`,幂等(`IF NOT EXISTS` 或 try/except) +- 不直接改线上 DB 结构,通过 `mofin_db.py` 的 init 函数执行 +- 数据修正脚本放到 `scripts/` 目录 + +--- + +## 四、LLM Prompt 规范 + +### 4.1 强制要求 + +| # | 规则 | 检查方法 | +|---|------|---------| +| S1 | 不引用 JSON 文件名 | grep `\.json` | +| S2 | 港股价格标注 `(HKD)` | 检查 prompt 模板 | +| S3 | 不指示跨币种直接比较 | 人工审查 | +| S4 | 数据源标注为 DB 表名 | `strategy_evaluations` 不是 `evaluation.json` | +| S5 | 不在 prompt 里硬编码路径 | grep `/home/hmo/` | + +### 4.2 新增/修改 Prompt + +- 在 `prompt_manager/init_registry.py` 注册新版本 +- 旧版本标记 `status="deprecated"`,保留历史记录 +- 更新后运行测试脚本验证无 JSON 引用 + +--- + +## 五、Cron 规范 + +### 5.1 调度 + +- Cron 脚本必须能独立运行(`python3 xxx.py` 不报错) +- 处理异常,不因单个 API 失败而崩溃 +- 关键步骤加 try/except + `print(..., file=sys.stderr)` 日志 + +### 5.2 幂等性 + +- `price_monitor` 价格不变时不写入 DB +- `regenerate_all` 可重复运行不产生副作用 +- 所有写操作支持重复执行 + +--- + +## 六、开发流程 + +### 6.1 日常开发步骤 + +``` +1. 理解需求 → 检查现有代码 → 确定改动范围 +2. 本地修改代码 +3. 运行 scripts/run_all_tests.py(必须全部通过) +4. 如有新增功能,补充 TEST_PLAN.md 测试用例 +5. scp 部署到服务器 +6. 在服务器上再次运行 run_all_tests.py +7. git commit + push +8. 如涉及 server.py 修改,重启 Flask +9. 更新 CHANGELOG.md +``` + +### 6.2 测试要求 + +**每次代码变更后必须:** + +```bash +# 在服务器上运行全面测试 +cd /home/hmo/MoFin +python3 scripts/run_all_tests.py +``` + +**输出必须满足:** +- 0 个 `❌` +- 最多 1-2 个 `⚠️`(已知问题,已记录在案) + +**如测试不通过:** +1. 修复问题 +2. 重新测试 +3. 不通过不提交 + +### 6.3 文档同步 + +**哪些文档需要同步更新:** + +| 改动内容 | 需更新的文档 | +|---------|------------| +| 新增/修改表 | `docs/DATABASE_ARCHITECTURE.md` | +| 新增/修改 API | `docs/SYSTEM_ARCHITECTURE.md` | +| 架构变更 | `docs/SYSTEM_ARCHITECTURE.md` | +| 数据模型变更 | `docs/portfolio-data-model.md` | +| 任何功能变更 | `CHANGELOG.md`(追加顶部) | +| 新增测试用例 | `docs/TEST_PLAN.md` | + +### 6.4 提交规范 + +- Commit message 格式:`type: 简短描述` +- 类型:`fix:` / `feat:` / `refactor:` / `docs:` / `test:` / `migrate:` +- 一次 commit 一个逻辑变更,不要混搭 + +--- + +## 七、快速检查清单 + +**每次提交前自检:** + +``` +□ run_all_tests.py 全部通过 +□ 无新增 json.load / json.dump 数据文件 +□ 港股 currency='HKD'、A股 currency='CNY' +□ 无硬编码汇率 +□ 无重复代码 +□ CHANGELOG.md 已更新 +□ 无残留 print 调试语句 +□ git status 确认只改了应改的文件 +``` + +--- + +## 八、紧急联系人 + +| 角色 | 负责 | +|------|------| +| 小小莫 | 架构、DB、重构、price_monitor | +| 知微 | 策略、LLM prompt、cron、日常运营 |