# 开发 Session 环境使用指南 > 面向**所有开发 session**(前端 / 后端 / 策略 / 数据):开发完成后如何 **部署 → 验证 → 同步 → 冒烟**。 > 环境/部署/数据同步由**专属运维 session**负责;本手册让你能**自助**完成部署验证,不用等运维。 > > 晋升/rollback/数据铁律的完整细节见 [`three-env-code-promote.md`](./three-env-code-promote.md),本文不重复(DRY),只给「开发 session 照着做」的总入口。 ## 0. 一句话流程 ``` Mac 改代码 → pytest(本地 fixture) → promote.sh → NAS 冒烟 → VPS 冒烟 ``` --- ## 1. 职责边界 | 角色 | 负责 | 工作机器 | |------|------|----------| | **各开发 session** | 你自己的模块代码 + 本地单测 | Mac | | **运维 session** | 环境、部署脚本、CI/CD、数据同步、定时任务 | Mac + NAS + VPS | **边界**:你改代码 + 本地测;部署用 `promote.sh`(或 CI/CD 自动);**环境/数据层问题**(库连不上、数据缺失/重复、路径错)报运维 session 根治,**不在 provider/业务代码里兜底**(兜底会掩盖数据层真 bug)。 --- ## 2. 三机总览 | 机器 | 角色 | 代码路径 | 关键特征 | |------|------|----------|----------| | **Mac** | dev 开发 | `~/.openclaw/sanguo_projects/sanguo_vnpy_v2` | arm64 / `venv310` / **用 fixture,不拉真实数据**(42GB 放不进) | | **NAS** | test 验证 | `/volume1/stock/sanguo_vnpy_v2` | amd64 / Docker / 数据**只读副本** | | **VPS** | prod 生产 | `C:\sanguo_vnpy_v2` | Windows / **无 git·docker·rsync**(只有 scp)/ 权威 DB **唯一写源** | **数据流单向**:VPS 采集(权威)→ NAS 只读副本 → Mac 按需。**NAS/Mac 永不写回 VPS**。 --- ## 3. 标准流程(开发完照着走) ### Step 1 — Mac 本地单测(fixture) ```bash cd ~/.openclaw/sanguo_projects/sanguo_vnpy_v2 source venv310/bin/activate pytest tests/<你的模块>/ -q ``` **预期**:全绿。Mac 用 fixture,不需要真实数据。 ### Step 2 — 部署 NAS test(CI/CD 自动 / 手动应急) > **默认走 CI/CD 自动**:`git push origin master` → 自动 `test → nas-deploy(推 NAS 后端+前端 dist) → nas-verify(秒级 gate)`。nas-verify 绿 = NAS test 已部署验证。**VPS 不在这里推**(见 Step 4)。详见 §8。 手动(应急 / CI 没跑 / Mac 睡眠): ```bash bash scripts/nas_sync/promote.sh --target nas --module sanguo_<你的模块> # 单模块只推 NAS bash scripts/nas_sync/promote.sh --target nas # 全量只推 NAS ``` - promote.sh 支持 `--target nas|vps|all`(默认 all)。NAS 走 rsync(LAN 快),VPS 走 scp。**数据铁律双防护**,绝不推 `data/`。 - 前端 dist 不在 promote.sh(gitignore);CI 自动 `npm build` + rsync dist。手动推前端见运维。 ### Step 3 — NAS 冒烟(数据层/读取层改动必跑) ```bash ssh sanguo-nas 'cd /volume1/stock/sanguo_vnpy_v2 && \ /var/packages/Docker/target/usr/bin/docker run --rm \ -v /volume1/stock:/volume1/stock -v $(pwd):/app \ sanguo_vnpy_v2:with-sqlite python /app/scripts/smoke_e2e.py' ``` **预期**:`RESULT: 读取 N 条 BarData`(N>0)。验证 `read_db_daily` 能读 NAS `quant_trading.db`。 ### Step 4 — VPS 落盘验证(确认新代码到 prod) ```bash ssh 49.232.102.198 'powershell -NoProfile -Command "Get-ChildItem C:\sanguo_vnpy_v2\sanguo_<模块> -Filter *.py | Select Name,LastWriteTime | Format-Table -Auto"' ``` **预期**:文件 `LastWriteTime` 是刚推送的时间。 > 教训:**commit ≠ 部署 VPS**。git commit 后必须 promote,否则 VPS 跑旧代码。 ### Step 5 — VPS 冒烟(provider/数据层改动必跑) ```bash ssh 49.232.102.198 'cd C:\sanguo_vnpy_v2 && C:\Python310\python.exe -X utf8 scripts/data_platform/verify_unified_e2e.py' ``` **预期**:末尾 `E2E DONE — LocalUnifiedProvider VPS 真数据验证通过`。验证 get_price / get_index_stocks / get_fundamentals 三大接口在 VPS 真数据上正确。 --- ## 4. 数据访问铁律 - **provider 读 VPS 本地数据**(`C:\sanguo_vnpy_v2\data\`),**不调 online**(baostock/akshare 在线)。 - **NAS 副本只读**,永不写回 VPS(VPS 是唯一写源)。 - **Mac 用 fixture**,不拉真实数据(放不进,且 Phase1 已决策 Mac 只做 fixture 开发)。 - **数据层瑕疵**(重复行/格式不一/缺失)→ 报运维/数据 session 根治,**不在 provider 适配兜底**。 --- ## 5. 角色速查表 | 角色 | 模块 | 改完怎么推 | 必跑验证 | |------|------|-----------|----------| | **前端** | `sanguo_web` | `--module sanguo_web` | Mac `pytest tests/`(无 web 子目录则全量)+ 浏览器看渲染 | | **后端** | `sanguo_api` | `--module sanguo_api` | Mac `pytest tests/api/` | | **策略** | `sanguo_portfolio` `sanguo_backtest` | **全量**(多模块) | Mac `pytest tests/portfolio/ tests/backtest/` + NAS 冒烟(Step 3) | | **数据** | `sanguo_data` `sanguo_common` | `--module sanguo_data` | NAS 冒烟(Step 3)+ **VPS 冒烟(Step 5)** | > 策略/数据层改动影响 provider 数据读取,**NAS + VPS 双冒烟必跑**。 --- ## 6. Reload 机制(VPS 无常驻 web) VPS 是**一次性任务**模型(回测 runner + 采集 schtask),**没有常驻 web 服务**。 - 代码部署后 **下次启动自动加载**,不用 hot reload、不用重启服务。 - **立即让采集生效**: ```bash ssh 49.232.102.198 'schtasks /end sanguo-bs-eod && schtasks /run sanguo-bs-eod' ``` --- ## 7. 常见坑(完整版见 [`three-env-code-promote.md` §8](./three-env-code-promote.md)) | 坑 | 解法 | |----|------| | `ssh vps` 连不上(fake-ip 198.18.1.254) | 用 `ssh 49.232.102.198`(本机 config 无 vps 别名) | | scp 路径报错 | VPS 目标用**正斜杠**:`49.232.102.198:"C:/sanguo_vnpy_v2/"` | | PowerShell 中文乱码 | `-NoProfile` + `Get-ChildItem`/`Select-String`,避中文路径 | | 长任务挂 ssh 被杀 | NAS 用 `setsid`(脱离会话进程组),VPS 用 `schtasks` | | 光猫挡 VPS 入站 | VPS 不能 git pull / rsync push,只能 Mac/NAS **主动 scp 推** | | 改完 VPS 行为没变 | commit≠部署;代码下次启动才加载,采集要 `/end && /run` 立即生效 | --- ## 8. CI/CD(已建成,分层:NAS 自动 + VPS dispatch) Gitea 不支持 environment approval gate,故用**双 workflow** 隔离 NAS test / VPS prod: ``` push master → ci-cd.yml 自动: test(pytest) → nas-deploy(推NAS后端+前端dist+restart容器) → nas-verify(login+strategy/list+dbbardata 秒级 gate) ↓ nas-verify 全绿 = NAS test 已部署+验证 ⏸️ VPS 不自动推,停下等触发 推 VPS(nas-verify 绿后,触发 vps-deploy.yml,两种 approve): 人工 = Gitea UI → Actions → vps-deploy.yml → Run workflow(填 sha) agent = curl -H "Authorization: token $PAT" POST .../dispatches body {"ref":"master","inputs":{"sha":""}} ↓ checkout 你传的 SHA(= NAS 验证过的) → promote --target vps → verify_unified_e2e ``` - **NAS 自动**:push 即触发 ci-cd.yml;nas-verify 是秒级 gate(API 健康 + 数据可读)。runner 是 Mac(睡眠时 CI 不跑,手动 `promote --target nas` 应急)。 - **VPS 严格版本**:vps-deploy.yml 接收 `sha` input,checkout 该 commit(= nas-verify 验证过的),绝不部署未验证代码。 - **agent approve 的 PAT**:osxkeychain 存了 `sanguo-gitea-ci`(scoped `write:repository`)。取用:`token=$(security find-generic-password -s sanguo-gitea-ci -a agent -w)`,再 `curl -H "Authorization: token $token" ...`。⚠️ MCP claude_dev token 无 write 权限(dispatch 会 403)。 - **前端 dist**:ci-cd.yml 的 nas-deploy 自动 `npm ci + build + rsync dist`(不 commit dist、不进 promote.sh)。 - workflow 文件:`.gitea/workflows/ci-cd.yml`(push→NAS) + `vps-deploy.yml`(dispatch→VPS)。 --- ## 参考 - [三机代码晋升 Runbook](./three-env-code-promote.md) — 晋升命令 / rollback / 数据铁律 / 常见坑(完整版) - [三机环境设计 spec](./design/dev-test-prod-env-design.md) — dev/test/prod 权威设计 - [NAS 部署目录约定](../CLAUDE.md) — `/app` 与 `/volume1/stock` 挂载、rsync 部署流程