feat: Z34b restore-by-host + harden web nginx DNS race
Add HMAC restore-by-host for phone-less rebind; resolve gateway at request time and recreate web after stack up. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
128
联调后修改意见-宇恒松离线.md
128
联调后修改意见-宇恒松离线.md
@@ -1,6 +1,6 @@
|
||||
# 联调后修改意见 · 宇恒松离线(形态 B)
|
||||
|
||||
> 初稿:2026-08-01 · 修订至 **2026-08-06 22:30**(Z31 同步 host_key=宇恒账号 ID)(Z24 已绑定勿 force 清落点)
|
||||
> 初稿:2026-08-01 · 修订至 **2026-08-07**(Z34b 智建已落实:restore-by-host)
|
||||
> 焦点:**§0.2**(按负责方);**改代码前须先写入本意见**(见 §0.0)
|
||||
> 来源:宇恒 `yuhengyihao_client` ↔ 智建(生产 `aisite.yuxindazhineng.com`)
|
||||
> 依据:`松离线-dbsync方案-最终版.md`、`宇恒-松离线数据同步使用文档.md`
|
||||
@@ -29,6 +29,7 @@
|
||||
| **Z22 绑定表单失败可重试** | **宇恒已改完;智建无需** | prepare 只做非交互检测;`ask_fields`/`Expecting value` 不冒泡成「绑定引导失败」;必弹绑定表单(§5.20) |
|
||||
| **Z23 表单推送失败禁止空等** | **宇恒已改完;智建无需** | `ask_fields_via_chat` 推送失败立即抛错;进行中再选中会话给出提示;对齐 ty_host≥1.2.35(§5.21) |
|
||||
| **Z24 已绑定勿 force 清落点** | **宇恒已改完;智建无需** | 启动自动引导绑定时禁止 `force_rebind` 清 CHANNEL;仅用户点「换绑」才清(§5.22) |
|
||||
| **Z34 / Z34b 换机恢复** | **宇恒半程 + 智建已落实** | 有手机静默恢复(Z34);无手机 `POST …/restore-by-host`(Z34b · §5.32) |
|
||||
| **仍关注** | 用法 | 通道断了靠智建自愈;表数据靠宇恒双向指纹 / 数据恢复;不是「再点启动」 |
|
||||
|
||||
### 0.0 修改流程(冻结)
|
||||
@@ -70,6 +71,9 @@
|
||||
| **Z22** | **绑定表单失败可重试(2026-08-06 · 宇恒已改完)**:启动检测改为非交互;表单推送/JSON 解析失败不向用户暴露 `Expecting value`,捕获后重试弹表。**智建无需改** |
|
||||
| **Z23** | **表单推送失败禁止空等(2026-08-06 · 宇恒已改完)**:推送失败立即抛错触发重试;禁止「只发文字、表单卡死等待」。**智建无需改** |
|
||||
| **Z24** | **已绑定勿 force 清落点(2026-08-06 · 宇恒已改完)**:自动绑定时 `force_rebind=False`;换绑按钮才清。**智建无需改** |
|
||||
| **Z32** | **绑定表单按方式显隐字段(2026-08-06 · 宇恒已改完)**:`visible_when` + sendFrom 过滤;绑码/手机号/稍后切换下方表单项。**智建无需改** |
|
||||
| **Z33** | **仅数据同步时勿因缺 app.read 进换绑(2026-08-06 · 宇恒已改完)**:GET /apps 403 且已 sync_bound → apps=[] 继续模块菜单并提示开通读取模块。**智建无需改**(控制台给智能体开「读取模块」即可列模块) |
|
||||
| **Z34** | **换机按账号恢复(2026-08-06 · 宇恒半程已改完)**:有手机号时可静默 ticket/confirm。**完整「仅宇恒 ID」见智建 Z34b(已落实)** |
|
||||
|
||||
#### A′. 宇恒 · 配合注意(非阻塞新开发)
|
||||
|
||||
@@ -91,6 +95,7 @@
|
||||
| Podman DNS / 脚本可执行位 | compose aliases;`restart.sh` 100755 |
|
||||
| **Z12h / Z12h-1 / Z12h-2** | `HealTenantSyncBind`:Ensure 默认通道 + 重挂 Agent/Binding;默认同步**可删**,删后立即 Ensure+heal;列表/换票/`agents/me`/ensure Binding 触发;见 §5.9 |
|
||||
| **数据恢复(§5.13)** | 成功同步后线上库快照(latest+previous);SyncPage「数据恢复」;`GET …/checkpoint` + `POST …/restore` |
|
||||
| **Z34b** | `POST /api/v1/auth/yuheng/restore-by-host`:HMAC 凭票(phone 可空)按 `host_key` 恢复已 sync_bound 落点并轮换密钥;见 §5.32 |
|
||||
|
||||
> 产品一句:**账号已绑定 ⇒ 落点信息固定;通道没了平台自动补,终端无需手填 channel_id。**
|
||||
|
||||
@@ -98,7 +103,7 @@
|
||||
|
||||
| 优先级 | 编号 | 项 | 说明 |
|
||||
|--------|------|----|------|
|
||||
| — | — | **无阻塞开发项** | Z12h、数据恢复已合入;后续仅生产 pull 与运维配号 |
|
||||
| — | — | **无阻塞开发项** | Z34b 已合入;宇恒接入 restore-by-host 后联调;生产 pull 见 B′ |
|
||||
|
||||
#### B‴. 智建 · 本次明确不改(Z15)
|
||||
|
||||
@@ -114,7 +119,7 @@
|
||||
|
||||
| 优先级 | 项 | 说明 |
|
||||
|--------|----|------|
|
||||
| **P0** | **生产 pull 本批** | Z10d + fingerprint + Z14c + **Z12h** + **数据恢复**;`bash ./restart.sh --pull` |
|
||||
| **P0** | **生产 pull 本批** | Z10d + fingerprint + Z14c + **Z12h** + **数据恢复** + **Z34b**;`bash ./restart.sh --pull` |
|
||||
| **P0** | 成员手机 | 「宇信达」绑 **`13531041944`**;勿超管号 |
|
||||
| **P0** | 通道表白名单 | **勿**「填入测试默认」;形态 B 可空 |
|
||||
| **P1** | 凭票 Secret | `YuhengTicket.Secret` ≡ `YXD_YUHENG_TICKET_SECRET` |
|
||||
@@ -962,9 +967,124 @@ POST /api/v1/agent/sync/channels/{id}/pull
|
||||
|
||||
「智能体 host」在智建侧=绑定请求里的 `host_key` 字段。账号隔离后应等于宇恒用户 `_id`;电脑级 `YXD_HOST_KEY` 不再用于跨公司换绑。
|
||||
|
||||
### 5.30 【Z32 · 2026-08-06】绑定表单按方式显隐字段
|
||||
|
||||
**状态**:**宇恒已改完;智建无需**。依赖 `yxd_skill_ty_host≥1.2.36`(`visible_when`)+ 前端 `sendFrom.vue`。
|
||||
|
||||
#### 现象
|
||||
|
||||
选「绑定码 / 手机号 / 稍后绑定」后,下方绑定码、手机号、短信三项始终全显,体验像「又要选又不变」。
|
||||
|
||||
#### 改动
|
||||
|
||||
1. ty_host:`field_text`/`field_enum` 支持 `visible_when`,经 `field_spec_to_component` 下发。
|
||||
2. `sendFrom.vue`:按依赖字段当前值过滤 `visibleFormComponents`。
|
||||
3. `bind_sync`:绑定码仅「绑定码」可见;手机号+短信仅「手机号」可见;「稍后绑定」无输入项。
|
||||
|
||||
#### 验收
|
||||
|
||||
切换绑定方式时下方表单项随之切换;选「稍后绑定」仅剩方式选择与提交。
|
||||
|
||||
### 5.31 【Z33 · 2026-08-06】仅「数据同步」权限时 GET /apps 403 勿进换绑
|
||||
|
||||
**状态**:**宇恒已改完;智建无需**(产品上给智能体开「读取模块」即可;非接口缺陷)。
|
||||
|
||||
#### 现象
|
||||
|
||||
绑定+换票成功 `permissions=['数据同步'] sync_bound=True`,随后提示「拉取模块列表失败(需 app.read)」并进鉴权/换绑门闸,用户误以为绑定失败。
|
||||
|
||||
#### 根因
|
||||
|
||||
松离线智能体常只开「数据同步」;列模块 `GET /apps` 需要 `app.read`。旧逻辑把列模块失败当成登录失败。
|
||||
|
||||
#### 宇恒改
|
||||
|
||||
`host_bootstrap`:403/缺 app.read 且本机已有同步落点或换票含同步权 → `apps=[]`,提示管理员开「读取模块」,仍弹出模块操作(可换绑/新建等;无列表时新建受限按原逻辑)。
|
||||
|
||||
### 5.32 【Z34 / Z34b · 2026-08-06】换机:同宇恒账号自动恢复本地同步配置
|
||||
|
||||
**状态**:
|
||||
- **Z34 宇恒**:已改完(有手机号路径)
|
||||
- **Z34b 智建**:**已落实**(`POST /api/v1/auth/yuheng/restore-by-host`;gateway 公开;凭票 `scope=sync_restore` 时 phone 可空)
|
||||
|
||||
#### 诉求
|
||||
|
||||
同步绑定跟**宇恒账号**,不跟电脑。换机登录同一宇恒账号后:
|
||||
|
||||
1. 用**宇恒用户 `_id`(即绑定用的 `host_key`)向智建查询**是否已有同步绑定;
|
||||
2. 若有 → **直接回传**可落盘的配置(`channel_id` / `client_id` / `client_secret` / `online_db_id` 等),宇恒本机自动写 `yuheng_sync.env` + 技能 config;
|
||||
3. 若无 → 再走绑定码/手机号表单。
|
||||
|
||||
用户不应依赖本机是否记得手机号;**「账号绑的是哪个手机」也应能由智建按 host_key 查到**(可脱敏返回)。
|
||||
|
||||
#### 为何必须智建配合(Z34b)
|
||||
|
||||
| 现状 | 缺口 |
|
||||
|------|------|
|
||||
| `FindByHostKey` 仅平台内部 | 宇恒终端**没有**公开「按 host_key 查绑定」API |
|
||||
| `phone-lookup` / `phone-confirm` / `ticket-exchange` | **都要手机号**;票内 `phone` 必填 |
|
||||
| 宇恒 Z34 | 只能在本机能解析到手机时静默恢复;**无手机则仍弹表** |
|
||||
|
||||
结论:**仅用宇恒 ID 查绑定并生成配置 = 必须智建新接口(或扩展凭票)**;宇恒不能也不应穿透智建库。
|
||||
|
||||
#### 智建 Z34b(已落实)
|
||||
|
||||
**接口**:`POST /api/v1/auth/yuheng/restore-by-host`(gateway 公开,与 ticket-exchange 同级;须 HMAC)
|
||||
|
||||
请求:
|
||||
|
||||
```json
|
||||
{
|
||||
"ticket": "YHT1.<payload>.<sig>",
|
||||
"host_key": "<宇恒用户_id,须与票内一致>"
|
||||
}
|
||||
```
|
||||
|
||||
票内 claims(相对现有凭票):
|
||||
|
||||
| 字段 | 要求 |
|
||||
|------|------|
|
||||
| `iss`/`aud`/`exp`/`jti`/`scope` | 同现网;`scope` 可用 `sync_bind` 或 `sync_restore` |
|
||||
| `host_key` | **必填** = 宇恒 `_id` |
|
||||
| `yuheng_user_id` | 建议必填,且与 `host_key` 相同(防错绑) |
|
||||
| `phone` | **可空**(`sync_restore` / restore 验票路径) |
|
||||
|
||||
校验:`YuhengTicket.Secret` 验签 → `FindByHostKey(host_key)` → 须 `StatusActive` 且已有 `channel_id`(sync_bound)→ 轮换 secret;顺带自愈通道;可选签发智能体 JWT。
|
||||
|
||||
成功响应(与绑定成功对齐,便于宇恒 `apply_bind_success` 复用):含 `ok`/`sync_bound`/`client_id`/`client_secret`/`channel_id`/`online_db_id`/`tenant_id`/`agent_id`/`host_key`/`phone_masked`/`access_token` 等。
|
||||
|
||||
失败:
|
||||
|
||||
| 情况 | 建议 |
|
||||
|------|------|
|
||||
| 无此 host_key / 未 sync_bound | `404` + `need_bind=true`(宇恒弹绑定表) |
|
||||
| 签名无效 / 过期 | `401` |
|
||||
| host_key 与票不一致 / yuheng_user_id 不符 | `403` |
|
||||
|
||||
#### 宇恒 Z34(已改)
|
||||
|
||||
1. `try_restore_bind_for_account`:本机无 CHANNEL 时,`host_key=YXD_USER_ID` + 可解析手机 → 静默 ticket / phone-confirm → `apply_bind_success`。
|
||||
2. 登录写入 `YXD_USER_ID` / `YXD_USER_PHONE`(若有)。
|
||||
3. **待接入**:优先调 `restore-by-host`(无手机也可);失败再回落手机路径 / 绑定表。
|
||||
|
||||
#### 验收
|
||||
|
||||
1. 机 A 用账号 U 绑定成功。
|
||||
2. 机 B 登录同一 U,**本机无手机号缓存**。
|
||||
3. 进 AI建站技能 → 调 Z34b → 自动落盘 CHANNEL/client,**不弹绑定表**。
|
||||
4. `phone_masked` 可展示「已恢复(手机 135****1944)」类提示(可选)。
|
||||
5. 从未绑定的新账号 → `need_bind` → 仍走绑定表。
|
||||
|
||||
#### 分工
|
||||
|
||||
| 方 | 做什么 |
|
||||
|----|--------|
|
||||
| **智建** | ✅ Z34b + gateway 路由 + 文档;生产 pull |
|
||||
| **宇恒** | 接入 `restore-by-host`(优先于手机静默路径);联调 |
|
||||
|
||||
## 6. 联系与附件
|
||||
|
||||
- **待改清单(优先看)**:§0.2(**A′ 宇恒配合 · B′ 智建运维**;开发项已清空);**改代码前先写本意见**(§0.0);配合见 **§0.3**
|
||||
- **待改清单(优先看)**:§0.2(**A′ 宇恒接入 restore-by-host · B′ 运维 pull**);**改代码前先写本意见**(§0.0);配合见 **§0.3**
|
||||
- 方案:`松离线-dbsync方案-最终版.md`(含 2026-08-01 联调建议落地记录)
|
||||
- 宇恒使用说明:`宇恒-松离线数据同步使用文档.md`(含 Z10 schema/ensure、Z13 绑定)
|
||||
- 开通说明:`docs/数据同步-开通说明.md`(含 **数据恢复**)
|
||||
|
||||
Reference in New Issue
Block a user