# crypto_okx_hub 设计文档(第一期) > 状态:**第一期骨架已落地**(登录 / 实例 CRUD / 总览拉取 / 内嵌+新标签 SSO) > 仓库:[https://git.bz121.com/dekun/crypto_okx_hub.git](https://git.bz121.com/dekun/crypto_okx_hub.git) --- ## 1. 目标与边界 ### 1.1 第一期要做 | 能力 | 说明 | |------|------| | 中控登录 | 独立账号(与客户端账号分离) | | 客户端注册表 | 名称、公网 URL、Bridge Token、标签、启用状态 | | 多机持仓总览 | 定时拉取各客户端只读快照,卡片/表格展示持仓与浮盈 | | 一键打开 | **默认内嵌**中控(iframe / embed 壳);同时提供 **新标签打开** | | 在线探测 | 心跳/拉快照失败则标离线 | ### 1.2 第一期明确不做 - 中控代下单 / 代改 env / 统一密钥 - 跨机资金划转、策略编排引擎 - 把中控塞进每台 `crypto_okx` 同进程部署 ### 1.3 原则 - **中控 = 编排 + 只读聚合**;**客户端 = 唯一执行面**(密钥、下单、模拟盘均在客户端)。 - 浏览器「打开客户端」依赖用户能访问客户端 **公网域名**;中控拉快照依赖中控机器能访问同一公网 URL。 --- ## 2. 关联仓库 | 仓库 | 角色 | 地址 | |------|------|------| | **crypto_okx_hub** | 中控(本仓库) | https://git.bz121.com/dekun/crypto_okx_hub.git | | **crypto_okx** | 期权客户端 / 执行机 | https://git.bz121.com/dekun/crypto_okx.git | 客户端对外:**公网域名**(如 `https://okx-eth.example.com`)。 中控部署:**Ubuntu 云机 + PM2**(与客户端同一套一键部署方式,不部署 Windows)。 协议靠约定对齐,不强制 monorepo。客户端侧需提供(实现阶段在 `crypto_okx` 补): 1. 只读 Bridge API(Token 鉴权)— 持仓/资金/模式快照 2. Embed 入口 — 供中控 iframe 打开(可带短期 SSO / token) --- ## 3. 总体架构 ``` ┌─────────────────────┐ HTTPS 公网 ┌──────────────────────┐ │ 浏览器(操作员) │────────────────────────────▶│ crypto_okx Worker A │ │ │ iframe / 新标签打开 │ 公网域名 + 密钥/DB │ │ ┌───────────────┐ │ └──────────────────────┘ │ │ crypto_okx_hub│ │ 中控服务端拉快照 │ │ (Ubuntu/PM2) │──┼────────────────────────────▶┌──────────────────────┐ │ └───────────────┘ │ GET /api/hub/options/... │ crypto_okx Worker B │ └─────────────────────┘ Header: X-Hub-Token └──────────────────────┘ ``` - **中控 → 客户端**:服务端用 `base_url + bridge_token` 拉快照(不经过浏览器 CORS)。 - **浏览器 → 客户端**:内嵌 iframe 或新标签,走客户端公网域名(用户网络可达即可)。 --- ## 4. 中控信息架构(页面) | 页面 | 用途 | |------|------| | `/login` | 中控登录 | | `/` 或 `/dashboard` | **多机总览**:每台一卡片(在线、模式 sim/live、总浮盈、持仓笔数、简表) | | `/instances` | 客户端 CRUD(名称、URL、Token、标签、启用) | | `/desk?id=…` | **工作台**:左侧实例列表,右侧 **iframe 内嵌** 该客户端;工具条含「新标签打开」 | | (可选)`/desk` 无 id | 提示先选实例 | 总览卡片操作: - **打开(内嵌)** → `/desk?id=` - **新标签** → `window.open(public_url + embed路径)` - 显示最近拉取时间 / 错误信息 --- ## 5. 数据模型(中控本地 SQLite) ### 5.1 `hub_users`(可选极简:仅 env 账号也行) 第一期可用 `.env` 的 `HUB_USERNAME` / `HUB_PASSWORD`,表可后补。 ### 5.2 `hub_instances`(核心) | 字段 | 类型 | 说明 | |------|------|------| | id | INTEGER PK | | | name | TEXT | 展示名,如 `ETH-保守` | | base_url | TEXT | 公网根,`https://okx-eth.example.com`(无尾斜杠) | | bridge_token | TEXT | 与客户端 `HUB_BRIDGE_TOKEN` 一致 | | embed_path | TEXT | 默认 `/embed` 或 `/options`(以实现为准) | | tags | TEXT | JSON 或逗号标签 | | enabled | INTEGER | 1=参与拉取 | | sort_order | INTEGER | | | created_at / updated_at | TEXT | | 拉取结果可 **内存缓存**(第一期),不必落库;需要历史再加 `hub_snapshot_cache`。 --- ## 6. 客户端 Bridge 约定(crypto_okx 侧,实现期补齐) ### 6.1 鉴权 ``` GET {base_url}/api/hub/options/snapshot Header: X-Hub-Token: <与 HUB_BRIDGE_TOKEN 相同> ``` 或 `Authorization: Bearer `(二选一,实现时定一种)。 ### 6.2 响应草案(version 字段便于演进) ```json { "ok": true, "version": 1, "instance": { "label": "okx_sim", "mode": "sim", "options_enabled": true }, "funds": { "total_usdt": 0, "trading_usdt": 0 }, "pnl": { "unrealized_usdt": 0 }, "positions": [ { "inst_id": "ETH-USD-...", "opt_type": "C", "sheets": 1, "pnl_usdt": 12.3, "mark": 0.01 } ], "ts": "2026-10-01 10:00:00" } ``` 字段与现有 `lib/options/options_hub_lib.py` 的 `build_options_hub_snapshot` 对齐即可,减少客户端改动。 ### 6.3 Embed / 打开 - 内嵌 URL:`{base_url}{embed_path}`,建议客户端提供可嵌套的 `/embed`(已有壳可复用)。 - 新标签:同一 URL。 - SSO(实现期):中控签发短时 `hub_sso` query,客户端校验后建 session;第一期也可先要求用户在 iframe 内再登一次(体验较差,优先做短期 token)。 --- ## 7. 中控内部模块(建议目录) ``` crypto_okx_hub/ app.py # Flask 入口 requirements.txt .env.example ecosystem.config.cjs # 可选 PM2 lib/ auth_lib.py # 登录 session instances_lib.py # 注册表 CRUD bridge_client_lib.py # 拉取各机 snapshot(超时、并发) dashboard_lib.py # 聚合总览 templates/ # 登录、总览、实例管理、desk(iframe) static/ deploy/ # 安装脚本(第二期可细化) 使用说明.md 部署文档.md 设计文档.md ``` 技术选型(第一期): - Python + Flask(与客户端同栈,好维护) - SQLite 存注册表 - 服务端 `concurrent.futures` / 线程池并发拉多机 - 前端:总览轮询 5–15s;desk 页 iframe + 顶栏按钮 --- ## 8. 打开方式详细设计 | 方式 | 行为 | 默认 | |------|------|------| | 内嵌 | 进入 `/desk?id=`,右侧 iframe `src=客户端embed URL` | **是** | | 新标签 | `target=_blank` 打开同一 URL | 提供按钮 | 注意: - iframe 需客户端不设过于严格的 `X-Frame-Options: DENY`(或对中控 Origin 放行)。实现期在 `crypto_okx` 配置。 - 混合内容:中控若 HTTPS,客户端必须 HTTPS。局域网中控用 HTTP 时,客户端 HTTPS iframe 一般仍可用。 - Cookie:跨站 iframe 第三方 Cookie 受限 → **强烈建议短期 SSO token**,不要依赖第三方 Cookie。 --- ## 9. 安全 | 项 | 做法 | |----|------| | Bridge Token | 每客户端独立;中控库中加密或至少权限收紧;只服务端使用 | | 中控登录 | 强密码;仅局域网可再加 IP 限制 | | 客户端防火墙 | 可选:仅允许中控出口 IP 访问 `/api/hub/*` | | 密钥 | 永不到中控 | | SSO | 短时、一次性、绑定 instance_id | --- ## 10. 实现分期 | 阶段 | 内容 | 仓库 | |------|------|------| | **H1** | 中控骨架:登录、实例 CRUD、总览拉快照、desk 内嵌 + 新标签 | hub | | **C1** | 客户端:稳定 `/api/hub/options/snapshot` + Token;embed 允许被中控嵌;SSO | crypto_okx | | **H2** | 总览体验:离线红标、错误条、标签筛选 | hub | | 以后 | 告警汇总、代操作(慎重) | 双仓 | 建议顺序:**先 C1 最小快照可用 → 再 H1 总览能绿**;或 H1 用 mock 快照并行,联调时接真 API。 --- ## 11. 验收标准(第一期) 1. 中控能登记 ≥2 个公网客户端(URL + Token)。 2. 总览能显示各机在线状态、浮盈、持仓列表(或空仓)。 3. 「打开」进入内嵌工作台,iframe 内可见客户端期权页。 4. 「新标签打开」可独立打开同一客户端。 5. 关掉某客户端进程后,总览在一轮拉取后显示离线/错误,不拖垮整页。 6. 文档写明关联仓库与部署步骤(本仓库已具备设计/说明/部署文档)。 --- ## 12. 待实现时拍板的小项 - Bridge 路径最终用 `/api/hub/options/snapshot` 还是复用现有 hub 扩展点名。 - Embed 默认进 `/embed` 还是 `/options`。 - SSO 第一期是否必须(建议必须,否则 iframe 二次登录体验差)。 设计以上述默认为准;写代码时若有变,改本文件「变更记录」。 ### 变更记录 | 日期 | 说明 | |------|------| | 2026-10-01 | 初稿:双仓、公网客户端、内嵌+新标签、总览第一期 | | 2026-10-01 | 骨架实现:Flask 中控 + 客户端 Bridge/SSO |