Files
easy_tdx_max/docs/development.md
T
awayingsandClaude ae24c3a5f1 docs: 新增 architecture/development,重写 docs/index.md 全量索引
- architecture.md:七层架构图 + 源码树 + 分层要点(越层直调/协议层无 IO/
  e2e_mock 替身/__main__ 三形态/平台差异)
- development.md:环境初始化/测试三层分布/静态检查/开发流程四阶段
  (需求 Issue→开发测试→提交 CI→发布 release+CHANGELOG)/文档规范
- index.md:人类目录(分类+每文件一句描述+历史归档标注)+ 完整 toctree
  (38 个 md 全部入树,消除 ReadTheDocs orphan 页面)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-08 23:21:50 +08:00

5.5 KiB
Raw Blame History

开发环境与流程

本文档是开发者的完整工作流参考。命令速查亦见 CLAUDE.md

环境初始化

git clone git@github.com:awayings/easy_tdx.git && cd easy_tdx
uv sync --all-extras          # 建 .venv 并装全部 extras(普通 uv sync 只装基础依赖)

CI 不用 uv,走 pip install -e ".[dev]" + pip install -r requirements-dev.txt。改依赖时两套流程都要考虑:pyproject.toml 只写下界+上界,uv.lockrequirements-dev.txt 才是可复现锁(dev 工具链锁定版本必须兼容 Python 3.10CI 矩阵跑 3.10/3.12/3.13)。

前端:cd web-ui && npm ci && npm run buildbuild = vue-tsc 类型检查 + vite build)。pip install -e . 要求 web-ui/dist 存在hatchling force-include 把它打进 wheel 的 easy_tdx/web/dist/),所以改前端后、跑 Python 测试/安装前必须先构建。

测试

python -m pytest tests/unit/ -v                             # 单元测试(无需网络,全部 mock)
XMTDX_LIVE=1 python -m pytest tests/integration/ -v        # 集成测试(连真实通达信服务器,默认 skip)
python -m pytest tests/unit/ --cov src/easy_tdx --cov-fail-under=60   # 覆盖率门槛 60

三层测试分布:

位置 跑在哪 说明
单元 tests/unit/ CI6 格矩阵)+ 本地 全 mocktests/fixtures/ 真实协议 hex dump + JSON 对照,tests/golden/ 期望输出
集成 tests/integration/ 仅本地 XMTDX_LIVE=1 才执行,连真实 TDX 服务器 smoke test
前端 E2E web-ui/e2e/*.spec.ts CI frontend job + 本地 PlaywrightEASY_TDX_E2E_MOCK=1 后端合成行情,不连真实服务器
  • tests/conftest.py 默认设 EASY_TDX_NO_TASK_DB=1,防单测污染 ~/.easy_tdx/tasks.db;需要测试存储的用例用 EASY_TDX_CONFIG_DIR 指向 tmp_path 显式重开。
  • tests/unit/test_ai_llm.py 依赖 LLM API key 轮询,CI 用 --ignore 跳过,本地有 mock 可跑。
  • asyncio_mode = "auto"async 测试无需 @pytest.mark.asyncio

静态检查

mypy src/                            # strict 模式(pyproject 配置)
ruff check src/ tests/               # E/F/I/UP 规则
ruff format --check src/ tests/

mypy/ruff 均排除 src/easy_tdx/exchange_margin.pyMyTT.py 有手写 MyTT.pyi stub 保持 strict 检查。

本地一键门禁(等价 CI 三 job 的本地版):

bash scripts/verify_ci.sh            # ruff → format → mypy → pytest(排除 integration)→ 前端 build + E2E
bash scripts/verify_ci.sh --fast     # 只跑静态检查
# 可选:ln -s ../../scripts/verify_ci.sh .git/hooks/pre-push

开发流程

a. 需求(Issue

  • 功能/缺陷先在 GitHub Issues 提出;代码注释与提交说明中引用编号(如 #58审计 #9)。
  • 复杂功能先写设计文档再动手(历史范本:docs/board-overview-design.mddocs/hotspot-rolling-design.md,以及 docs/superpowers/ 下的 specs)。
  • 功能变更时同步评估文档更新(见「文档规范」)。

b. 开发与测试

  • 新功能/修复按 TDD 习惯先写红测试再实现;单元测试必须零网络、零真实服务器依赖。
  • 命令形态变更时 easy-tdx --help 自检;Web 路由变更时 /docs Swagger 自检。

c. 提交与 CI

  • 提交信息带前缀(feat: / fix: / test: / docs: / refactor:,可带作用域如 feat(web):),中文描述。push/PR 到 main 触发 ci.yml
    • test jobubuntu/windows × py3.10/3.12/3.13 六格矩阵跑单测(覆盖率 ≥60+ ruff + format
    • mypy jobstrict 模式(py3.13
    • frontend jobvue-tsc + Playwright mock E2E
  • 集成测试不进 CI(依赖真实 TDX 服务器),发布前本地 XMTDX_LIVE=1 手动跑一遍。

d. 发布版本

  1. 收敛时打一个聚合提交 release: vX.Y.Z — 中文一句话摘要,同一提交内包含:代码与测试改动 + pyproject.toml 版本号 bump + CHANGELOG.md 新增版本小节。
  2. CHANGELOG 遵循 Keep a Changelogzh-CN):## [X.Y.Z] — 日期 倒序最新在前,先一段加粗导语再按主题分 ### 小节,条目带文件链接,测试小节报数字验收(如「全量 1820 通过,ruff / mypy / vue-tsc 全绿」)。无 Unreleased 区,CHANGELOG 在 release 提交时写入
  3. 打 tag 推送即自动发布:git tag vX.Y.Z && git push origin vX.Y.Z,触发两个独立 workflow——publish.ymlPyPI trusted publishingOIDC 无 token)与 release.ymlWindows EXE via PyInstaller + GitHub Release,正文含 SHA256/SmartScreen 说明;GitHub release notes 自动生成,不读取 CHANGELOG.md)。
  4. 版本单一来源是 pyproject.toml(前端品牌区版本来自后端 GET /api/v1/meta);文档一律不写死版本号。

文档规范

  • 大小限制:每份文档约 500 行为上限,超限必须拆分,通过 index.md 与 README 文档导航串联。过大文件不可新增。
  • 类型两分:教程(how-to,代码示例)与参考(速查/字段/命令表)原则上分开成文。
  • 可达性标准:任何文档变更必须以「README.md + docs/index.md 可达的文件」为标准——新文件必须同时进 README 文档导航与 index.md;删除/改名必须同步修复全部链接。
  • 禁止硬编码版本横幅:版本信息以 pyproject.tomlCHANGELOG.md 为准;功能引入说明里的版本标注(如「v1.29.1」)除外。