Files
ai_site/联调后修改意见-宇恒松离线.md
whm 069168df21 docs: refresh sync checklist after Yuheng Z10/Z13 land
Mark client work done, keep production ops as the remaining智建 blockers, and align the Yuheng usage doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 16:19:08 +08:00

43 KiB
Raw Blame History

联调后修改意见 · 宇恒松离线(形态 B

初稿2026-08-01 · 持续修订至 2026-08-05
本次整理:宇恒 Z10c/Z13 客户端已接回写;§0.2 拆成「已完成 / 仍待」;生产阻塞仅智建运维(部署/配号/Secret
来源:宇恒客户端 yuhengyihao_client ↔ 智建 gateway/platform本机 8180/8888 或生产 aisite.yuxindazhineng.com
依据:松离线-dbsync方案-最终版.md宇恒-松离线数据同步使用文档.md


0. 当前结论

级别 状态 说明
硬改(阻塞接口上线) Z1Z13 API/技能大体齐;生产联调仍取决于 §0.2 B 智建运维
原建议项 2.12.5 智建侧基本已落实 见 §2 对照表;接口请保持兼容
用户自助 Z1Z7 已落实 Z2 宇恒复测通过Z7 可读名:宇恒 ensure 宜带 database_name(见 §0.2 A
Z8 模块↔本机库+智能体库 已落实 Z8ag见 §5.5 / §5.5.2
Z9 模块导入默认能力(方案 A 已落实(含存量) Z9af见 §5.6
Z10 空表双侧建齐 双方已接 智建 schema/ensure;宇恒 sync_schema.ensure_before_drain§5.7
Z11 蓝图↔库列一致 智建已落实 发布自动 ADD COLUMN IF NOT EXISTS;见 §5.8
Z12 开通落点 双方已接 智建自动默认同步通道;宇恒换票/唯一通道/过渡 env§5.9
Z13 绑定 UX 双方代码已接;生产待运维 智建 API+凭票+policy宇恒技能/本机 bind API见 §5.10、§0.2 B
仍建议关注 性能/运维 SQLite remote 高并发 push 易锁agent 宜单库串行 drain

0.1 绑定产品冻结摘要Z13 · 试运行)

约定 内容
联调号 生产「宇信达」用 13531041944禁止超管号 13531041945
换票 凭票免登录:宇恒签 ticket-exchangeYXD_YUHENG_TICKET_SECRET + YXD_HOST_KEY + 手机号);不要手写 YXD_SYNC_LOGIN_PASSWORD
短信 试运行关闭SMS.RequireForBind=falseGET /api/v1/auth/bind/policytrial_mode=true。接入短信后改 true
宇恒未绑手机 仍可直接输入手机号绑定(试运行免短信;正式须短信)
同号 输入号 = 宇恒已绑号 → 正式可免短信 / 凭票;命中智建成员 → 必须弹「已有账号是否绑定」,不得静默
确认 无论试运行与否,绑到已有账号都须用户 确认confirm=true
当前阻塞 智建生产运维§0.2 B部署含公开路径的 gateway、成员绑号、凭票 Secret 对齐

0.2 待改清单(按负责方)

明细仍见 §5.7 / §5.95.10。智建 Z12/Z13 API 已合入 d195aa4(凭票、bind/policy、试运行关短信);生产须 ./restart.sh --pull 后才生效。

A. 宇恒 · 已完成2026-08-05

编号 内容 落地
Z10c 空表双侧建齐调用 sync_schema.ensure_before_drain选「同步」force ensuredrain 前 TTL 节流
Z13b 绑定码兑换 表单「绑定码」+ /database/sync/bind/redeem
Z13c-1 同号弹窗确认 技能 bind_sync + /database/sync/bind/phone-confirm(须 confirm
Z13c-2 policy + 凭票 GET /database/sync/bind/policy;试运行免短信;ticket_exchange(需 Secret
Z13d 未绑定检测 宿主启动 ensure_sync_bound_interactive
Z13e 选「同步」即用 POST /database/sync/mode → Binding + ensure + agent + full_push

A. 宇恒 · 仍建议(非阻塞)

优先级 编号 待改内容 验收要点
P1 Z12e 过渡通道缓存 仅 1 条默认通道可写 env终态以换票 channel_id 为准,勿当产品必填
P1 Z7 Binding 可读名 ensure / 登记 Binding 时带 database_name / display_name
P1 §2.6 agent 按库串行 drain 同一 SQLite remote 多线程齐推;加重试消化锁冲突

推荐调用顺序(未绑定)

GET /auth/bind/policy
  → sync_bound=false换票 / agents/me
  → 有手机phone-lookup → 弹窗 → phone-confirm 或 ticket-exchange
  → 无手机 / 取消:绑定码 redeem
  → 成功后库选「同步」→ Binding + drainZ13e

B. 智建 · 仍待办(运维 / 配置 · 当前生产阻塞

优先级 说明
P0 生产成员手机 「宇信达」成员管理绑定 13531041944绑超管 13531041945
P0 生产部署含凭票的 gateway ./restart.sh --pull 到含公开路径的版本:GET /auth/bind/policyPOST /auth/yuheng/ticket-exchange(旧 gateway 会 401 missing bearer token
P0 生产通道表白名单 形态 B 生产通道 用「填入测试默认」带 article 等演示表白名单;可空(整库 Binding
P1 默认同步 DSN 生产填 DBSync.DefaultRemoteDSNPostgres空则仍为 sqlite 联调文件
P1 宇恒凭票 Secret 生产 Agent.YuhengTicket.Enabled=true + Secret与宇恒 YXD_YUHENG_TICKET_SECRET 同一值
P2 正式短信 接短信平台后:SMS.ProvideroffRequireForBind=true

C. 双方已否决 / 不改

说明
终端冲突处理台 冲突仅平台超管侧
智建代改宇恒仓库 分工冻结,见 §3
平台 push 租约 正确性靠 version 幂等;并发由宇恒串行 drain

宇恒对照脚本:

  • yxd/app_fastapi/smoke_zhijian_e2e.py
  • yxd/app_fastapi/smoke_offline_concurrent.py
  • yxd/app_fastapi/smoke_zhijian_gateway_burst.py(连续 push / stats
  • yxd/app_fastapi/smoke_stress_sync.py(高并发 + gateway 压测)

复测摘要改后gateway 串行 60/60、eof502=0;同 version → skippedpushed_applied / pushed_skipped 有值;并发 push 加重试可压满(锁冲突靠重试消化)。


1. 已验证可用(请保持兼容)

勿破坏下列契约(宇恒 agent 已按此对接):

  1. GET /api/v1/agent/sync/channels/{id}/whitelist
    • 返回含 tablespk_columnsconflict_policy
  2. POST /api/v1/agent/sync/channels/{id}/push
    • Bodytable, op, row_pk, row/rows, version, client_outbox_id(用户自助另加 online_db_id
    • opinsert|update|update_by_id|delete(平台侧 insert/update 归一为 upsert 可接受)
    • 成功:{ success: true, result: { ok, applied, skipped, conflict, applied_version, message } }
    • (table,row_pk,version) 已落地 → skipped=true 且 HTTP 2xx
  3. POST .../pullPOST .../bootstrap
    • 下行灌库;响应含 columns(空表也返回列,便于本机建表)
  4. POST .../schemaPOST .../schema/ensureZ10
    • 拉线上表结构 / 本机空表结构推到线上(CREATE IF NOT EXISTS,无需 outbox 行)
  5. 鉴权:管理员 JWT含「数据同步」、智能体 Token登录用户 JWT(须本人 Binding + online_db_id)均可调 agent API
  6. 错误体优先带可读 message;忙/上游失败宜带 retryable: true502/503

联调账号(写入约定,勿再用错租户 / 勿用超管号)

环境 用途 登录 说明
本机 / 演示公司 租户 1 演示 13800000001 / demo123 仅本机联调;不要拿去推生产「宇信达」通道
生产 · 宇信达 公司管理 / 同号绑定联调 13531041944(密码由开通时设定) 专用联调号;智建须在「宇信达」成员/管理员中写入此手机;宇恒 YXD_SYNC_LOGIN_PHONE 与 Z13 同号确认均以此号为准
平台超管(禁止联调) 控制台「填入超管手机」 13531041945 / ljk_admin 最顶级管理员seed ensureDevPhone(ljk_admin)禁止用作同步登录 / 绑定联调,会与公司账号冲突

智建待办(运维):见 §0.2 B(成员手机 13531041944./restart.sh --pull、凭票 Secret、通道勿用测试表白名单


2. 原建议项落实对照2026-08-03

编号 原建议 智建现状 是否还要改
2.1 P1 gateway 偶发 502 EOF超时与可重试 JSON ProxyTimeoutSec 已生效sync 路径加长超时502 体含 retryableSQLite DSN 规范化 + busy_timeoutremote IO → 503+retryable见方案 changelog 2026-08-01 否(已落实)。若生产仍偶发 EOF按运维排障不升格为接口变更
2.2 P2 文档写明多 agent / version 幂等 docs/数据同步-中间件.md 已写「允许重复 push / 客户端 drain 锁优化」
2.3 P3 pushed_applied / pushed_skipped ChannelStats 已有burst 联调可见 。OpenAPI 已标注 applied/skipped示例可再补一句即可非必须
2.4 P4 Windows file: DSN 示例 开通/同步表约定已补正斜杠示例;平台规范化反斜杠
2.5 P5 503/502 + retryable 已按表落实

2.6 【新增·知会】高并发 push 与 SQLite remote

现象(宇恒 smoke_stress_sync):对同一通道 remote本机 SQLite并行 push 时,大量 database is locked / 失败,串行则稳定;加重试后可最终成功,但 p95 延迟明显升高。

边界

  • 正确性仍靠 version 幂等,不要求平台做 push 租约。
  • 推荐用法:宇恒 agent 按库串行 drain(勿多线程齐推同一 SQLite A
  • 若线上 A 为 MySQL/Postgres并发能力通常好于 SQLite文档可一句带过「SQLite remote 不适合高并发多 writer」。

智建是否必须改。可选更低优remote 打开时统一更长 busy_timeout、或文档强调 SQLite 并发限制(已有 busy_timeout 则足够)。


3. 明确不需要智建改的部分

负责方 说明
本机 drain 互斥锁 / 串行 drain 宇恒 减重复 HTTP 与 SQLite 锁风暴
写网关 / outbox / UUID 补齐 宇恒 未开通零感;仅白名单表同步
「agent 停仍可保存」 宇恒 H3
终端冲突处理台 双方已否决 冲突只在平台超管侧
改宇恒仓库代码 禁止由智建代改 分工已冻结

4. 联调回归清单(改后复测)

宇恒侧结果
whitelist 与通道一致
push insert → A 同 UUID
push update / delete
同 version → skippedA 不增行
gateway 连续 push ≥20 无 EOF burst 25、stress 串行 60
stats pushed_applied / pushed_skipped
并发 pushSQLite ⚠️ 需重试;建议客户端串行

未在每次脚本覆盖:无「数据同步」权限 → 403旧 version + lww_source 全矩阵——以平台单测/文档为准即可。


5. 宇恒侧说明(知会)

  • 测试已收紧mock 对齐 skipped、双 drain 断言 applied==N、update/delete 保序、压测脚本带锁重试。
  • 开通仍是可选YXD_SYNC_MODE=local_dbsync;用户自助以 Binding 为准(Z4:不按通道表白名单拒收)。
  • 空表sync 周期须调 Z10 schema/ensure(见 §5.7),否则本机空表不会出现在线上。
  • 原「若采纳 2.1 则稳定性提升」:已验证提升;本意见可归档为「历史建议 + 落实对照」,无需再开一轮同名改造。

5.1 【新增·2026-08-03】用户自助库级三态宇恒已开做

产品目标:用户登录智能体后,用自己的全部权限管理名下数据库/网页;可对每个库选择:

产品态 含义 宇恒引擎映射
仅本地 local_only 只写本机 local_only
仅线上 online_only 以线上为主 online_primary
同步 sync 本机落库 + outbox 上云 local_dbsync

宇恒已落地(本机):

  • POST/GET /database/sync/modeGET /database/sync/policies
  • 策略键:(tenant_id, user_id, local_database_id, database_name)
  • 写网关按命名库策略覆盖全局 YXD_SYNC_MODE(默认仍不静默升 sync
  • 数据库区卡片「同步设置」可视化三态;鉴权优先登录用户 JWTapp.client.access_token
  • 选「同步」后可拉起本机 agentpush 带头里的用户 Bearer

5.2 【请智建配合改 / 兼容】用户态同步

不破坏现有管理员通道 + agent Token 联调路径;以下为用户自助开通所需平台能力。

编号 优先级 诉求 说明 智建现状2026-08-04
Z1 P0 登录用户 JWT 可调 agent sync API whitelist / push / batch 允许已登录普通用户(本人资源范围)。 已落实
Z2 P0 权限范围 = 用户自己的库 online_db_id 时一律校验本人 Binding异库 → 403含有「数据同步」的人类 已落实
Z3 P1 Binding 支持用户自助登记 POST/GET .../bindings 认用户 JWT强制本人 user_id 已落实
Z4 P1 用户选 sync 时白名单策略 冻结②不按通道表白名单拒收Binding 库内任意表可 push可自动建表。 已落实
Z5 P2 仅线上 / 下行补齐 A→B / pull / bootstrap。 已落实
Z6 P2 控制台文案 Binding 即权限;管理员不负责维护表白名单。 已落实
Z7 P1 SyncPage / Binding 展示「可读库名 + 映射」 通道「线上」列优先可读名;副文案 online_db_id / 落库路径;统计标注为 push 次数Binding 列表「本地库名 ↔ 线上库名」。 已落实2026-08-04Binding 增 database_name/display_nameSyncPage 主标题优先本地 database_name,↑ 标注「推送次数 / 非表数」。宇恒 ensure 须带可读名,否则仍会回退到通道名或 driver
Z8 P0 模块数据:本机库可管理 + 按智能体上云 见 §5.5:本机 B 管理模块表push 到智能体绑定的 A废弃默认双轨 已落实(含 Z8g 展示)
Z9 P0 模块默认 import + 存量扫库 见 §5.6 已落实 Z9af
Z10 P0 空表两侧建齐 见 §5.7:仅靠 outbox 不会建空表 双方已接:智建 API + 宇恒 Z10csync_schema
Z11 P1 蓝图增字段迁库 见 §5.8 智建已落实 ALTER + 导入提示

建议验收(智建改后)

  1. 演示账号登录拿用户 JWT单独「数据同步」管理员权)→ GET .../channels/{id}/whitelist → 2xx。
  2. 同 JWT → POST .../push 写入本人 Binding 库 → A 出现同 UUID。
  3. 同 JWT 推他人 online_db_id → 403。
  4. 原管理员 / 智能体 Token 路径回归仍通过(不破坏联调结论)。

宇恒 ↔ 智建分工(本项)

负责
宇恒 库级三态 UI/API、写路径分流、outbox、用登录态调 push默认不按通道表白名单过滤Z10c 已接 schema/ensure
智建 用户 JWT 鉴权、Binding 校验、任意表 pushSyncPage/Binding 按可读名展示Z7Z10a/b 空表 API

5.3 【复测·2026-08-03 下午】智建改后 × 宇恒库级策略

环境:127.0.0.1:8180 + :8888;演示账号 13800000001 / demo123
脚本:yuhengyihao_client/yxd/app_fastapi/smoke_zhijian_e2e.pysmoke_user_jwt_policy.py
说明:直连智建验收(当时本机 8080 未起push 遇 gateway 502 EOF / 503 时按 retryable 重试后成功。

对照表

编号 结果 备注
登录拿用户 JWT token_len=225/api/v1/auth/me 可读
经典 e2eB→outbox→push→A 同 UUID PASSED 首次 push 常 502/503约 24 次重试后成功;二次 insert 同行数≥2
Z1 用户 JWT 拉 whitelist HTTP 200tables=['orders']
Z1 用户 JWT 直推本人库 online_db_idA 可见同 UUID重试后 200或同 version → skipped
Z3 用户 JWT 自助 Binding POST .../admin/sync/bindings → 200返回 user_id/local/online/channel_id
库级策略 sync → 写网关 local_dbsync 全局未强制 YXD_SYNC_MODE=local_dbsync 时,命名库策略仍进 outbox
登录态 agent drain 上云 drain 重试后 pushed=1A 行 title=policy-sync
Z2 推他人 online_db_id → 403 宇恒复测通过2026-08-04 403 无权访问该 online_db_id非本人 Bindingsmoke_user_jwt_policy.py PASSED
Z4Z6 白名单 / 下行 / 文案 Z4 冻结②已落实(任意表+自动建表Z5 pullZ6 SyncPage

现象与建议(运维)

  1. Gateway 偶发 502 EOF / 503 Request Timeout,体带 retryable: true;正确性仍靠 version 幂等(重试后常见 skipped=already applied)。
  2. 推荐:宇恒 agent / 联调脚本对 push 串行 + 按 retryable 重试(已在上述 smoke 加重试与 error→pending 恢复)。
  3. Z22026-08-04 宇恒复测通过——异库返回 403 无权访问该 online_db_id非本人 Binding
  4. 前端「数据库区 → 同步设置」需本机服务起来后人工点验;本次后端契约已通。

再测摘要2026-08-03 17:53

脚本 结果
smoke_zhijian_e2e.py PASSED首推即成功无 502
smoke_user_jwt_policy.py 主路径 PASSED当时 Z2 WARN 异库仍 applied

再测摘要2026-08-04 · 智建 Z2/Z4/Z6 重启后 · 宇恒确认)

脚本 结果
smoke_user_jwt_policy.py PASSEDZ2 OK(异库 403直推 + 库级 sync drain 上云均通过

结论

  • 用户自助主路径Z1 + Z2 + Z3 + 宇恒库级 sync已打通
  • Z22026-08-04:异库 online_db_id403(智建已修,宇恒已确认)。
  • Z4 已冻结并落地push 不按通道表白名单拒收Binding + 用户 JWT 即权限;可自动建表。

宇恒澄清2026-08-04 · 对照截图)

现象 说明 责任方
SyncPage ↑37 不是表数,是通道 pushed_okpush 成功次数);与线上 orders 行数巧合接近 智建 Z7 已改列名为「推送次数」并加副文案
显示 ai_site_….db 而非「AI建站智能体API」 SyncPage 曾用落库 DSN 当主展示应对齐本地库名id/路径作副文案 智建 Z7(主标题优先 Binding.database_name);宇恒 ensure 带 database_name/display_name
Binding local_*online_*「名字对不上」 id 本就可不同(映射);烟雾联调造的占位 id。真实库 6a3df5… 已补可读名「AI建站智能体API」默认隐藏 smoke Binding 智建已清烟雾数据 + UI 过滤;宇恒正式 ensure 带可读名
本地多表 vs 线上曾只有 orders 当时 remote 仅 ordersaccounts / 填土高度 尚未 push不是映射错库 后续 填土高度 已 push 对齐;空表仍需 Z10 ensure(见 §5.7
弹窗 4 表「0 条记录 / 0 字段」 卡片统计不准;库内仍有数据 宇恒前端(智建 SyncPage 无此卡片);可用数据预览或打开 remote db
要看线上表内容验同步 SyncPage 原先只显示通道名/推送次数 智建已加:「查看线上表」→ 表名/行数/字段 + 行预览;可「删表」(仅当前侧,需确认;不同步 DDL
图1「线上表」≠ 图2 宇恒「数据表」 见 §5.4:一边是线上 A一边是本机 B 不是串库;未 push / 未 ensure 的表不会出现在线上
模块数据按智能体进库 模块与 dbsync 原无关联 §5.5 Z8 已通;空表 Z10c 宇恒已接

同步链路本身可用;展示层勿把「通道文件名 + 推送次数」当成「本地库名 + 表行数」。

5.4 图1 vs 图2表名「对不上」说明2026-08-04 · 现状已回写)

图1 智建「查看线上表」 图2 宇恒「数据库管理 · 数据表」
看的是哪边 通道 线上 A(例:ai_site_1785779755.db 本机正式库 B「AI建站智能体API」
联调当时(早) orders(约 37 行)+ _ajz_* accountsorders填土高度…
回写后(已 push orders1+ 填土高度(6标一工区)96outbox 全 done 同行数对齐;accounts 仍 0 行
仍可能不一致 空表(如 accounts)未 ensure → 线上无此表 本机有空表;须走 Z10 schema/ensure,单靠 outbox 不会建空表
如何验同步 「查看线上表」预览行;或对照 _ajz_sync_meta 宇恒「数据预览」看本机真实行

结论:表名集合不同 = 本机有、线上尚未 push/ensure,不是 Binding/通道指错库。有行的表走 drain push空表必须走 Z10 ensure

_ajz_sync_* 是中间件系统表(版本/outbox不是业务模块表控制台「查看线上表」默认隐藏Z8e

5.5 【进展 Z8】模块数据 ↔ 本机库 + 智能体库

产品原则2026-08-04 确认)

  1. 模块数据也要能在本机库 B 里管理(宇恒数据库区:建表/增删改查/导入),与普通业务表同一套体验,不是只能在聊天「模块操作」或线上 Postgres 里改。
  2. 本机改完后,经松离线 push → 该智能体绑定的线上库 A;换机/仅线上可用 pull/bootstrap 灌回本机。
  3. 哪个智能体的模块 → 进哪个智能体的库(通道/online_db_id 绑定)。
    进展Z8ag 已通本机镜像、绑库、SyncPage 模块展示);空表 Z10c 宇恒已接sync_schema)。

目标数据流

宇恒本机库 B含模块表可本地管理
    │  sync / agent drain push
    ▼
智能体绑定的线上库 A与通道 remote 一致)
    │  智能体 / 控制台「查看线上表」核对
    ▼
(可选)模块页 CRUD 读同一 A或本机 B 为唯一写入口 + 同步
编号 优先级 诉求 说明 现状
Z8f P0 模块表可在本机库管理 模块实体表出现在宇恒「AI建站智能体API」类本机库中数据预览/录入/导入与业务表一致;开通 sync 后进 outbox 宇恒已通2026-08-04local_module_db 镜像;表名 模块·{模块名}·{资源}无下划线列含「所属模块」「模块slug」写网关 → outbox → push
Z8a P0 统一「一份表」叙事 废弃「模块一套库、松离线又一套」双轨并存为默认;默认:本机 B 为模块数据管理面A 为同步副本(或同库) 已补开通说明docs/数据同步-开通说明.md
Z8b P0 智能体选库 / 选通道 该智能体绑定 channel_id + online_db_id;宇恒可选「同步到哪个智能体库」 智建已落实:用户管理可绑通道/线上库/落库名SyncPage 按智能体筛通道。宇恒开通 sync 时会 PUT 通道 agent_id/app_slug(读 YXD_SYNC_*
Z8c P1 线上与本机对齐 智能体读模块数据时优先本机 B离线或已同步的 A发布蓝图在本机建表UUID PK再 sync避免只在平台 schema 建一份 部分:智能体新建发布若设 database_namedatabase_per_app 落该库;本机建表靠宇恒 Z8f
Z8d P1 本地上传 / 编辑 → 上云 本机模块表变更经 Binding + push 进该智能体 A「查看线上表」可核对 路径已通:本机改 模块·… 表 → drain → 「查看线上表」应见同表;若仍缺行 = 未 push / 未 drain
Z8e P2 查看线上表默认藏 _ajz_* 减少「表名不对」误解 智建已做默认隐藏2026-08-04
Z8g P1 本机可见 = 线上可见(展示闭环) SyncPage「智能体/模块」勿长期「未绑模块」;「查看线上表」列出本机已有业务表(含 模块·…);模块列优先展示名 智建已落实2026-08-05:模块展示名 + slug 副文案;策略表标「参考/整库同步」

分工建议

负责
智建 Z8a 文案Z8b 智能体↔通道/库绑定;Z8g SyncPage 模块展示名Z10a/b API开通说明
宇恒 本机库管理模块表Z8f 已通);开通/全量推送时挂通道 agent_id/app_slugZ10c 已接 sync 周期 schema/ensure

验收Z8 完成后)

  1. 在宇恒本机库能看到并编辑模块相关表Z8f
  2. 本机改模块行 → sync 后智建「查看线上表」出现同表同行(有数据路径;空表见 Z10
  3. 智能体 X 只落到绑定库管理员可按智能体筛通道验数Z8b
  4. 文档写明:本机有、线上无 = 尚未 push/ensure不是串库。
  5. SyncPage「智能体/模块」显示智能体名 + 模块展示名Z8gslug 作副文案)。

5.5.1 【联调补丁·2026-08-04】编辑发布撞 page id

现象:编辑模块 mode=add_pages 时报
page id already exists: record_list(模型复用了已有页 id实为要改 API import)。

智建已改platform/internal/blueprint/merge.go — 同 page id 合并 actions(不再 400同 path resource 并集 operations;仅有 API/按钮更新也视为可发布(UpdatedResources/UpdatedPages)。需重启 platform 后生效。

与 Z9Z9 默认带 import 后,此类「仅为开导入而编辑」会减少;本补丁仍保留给「改已有页能力」用。

5.5.2 【已落实 Z8g】本机可见 ↔ 线上可见(展示增强 · 2026-08-05

联调现象(对照两图)

  • 宇恒「数据表」已有:orders填土高度(6标一工区)模块·测·Sheet1(及业务表)。
  • 智建 SyncPageapp_slug 时解析已发布模块展示名slug 作副文案;仅缺绑定才「未绑模块」。
  • 通道表白名单 UI 标为「策略表(参考)」/「整库同步中」,避免误读为只能 sync 名单内表。
编号 优先级 诉求 说明 负责
Z8g-1 P1 SyncPage 模块列可读 展示名 + slug 副文案 智建已落实
Z8g-2 P1 通道绑定可被宇恒写入 PUT 可写 agent_id/app_slug 智建保持契约;宇恒已接
Z8g-3 P1 查看线上表 = 本机业务表子集 inspect + 默认藏 _ajz_*;缺表文案 智建已具备
Z8g-4 P2 白名单列勿误导 「策略表(参考)」/「整库同步中」 智建已落实

验收

  1. 通道已挂 agent_id=1app_slug=mismatch_test2 → SyncPage 不再显示「未绑模块」,模块列可见「测」或至少 slug。
  2. 本机 模块·测·Sheet1 全量 push 后,「查看线上表」出现同名表且行数对齐(幂等 upsert
  3. 本机 填土高度(6标一工区) / orders 与线上一致。

5.6 【已落实 Z9】模块导入默认能力方案 A · 2026-08-04

联调现象
宇恒绑定账号已具备 row.import(导入数据),智能体调用
POST /api/v1/apps/{slug}/{resource}/import 仍返回
HTTP 400: operation import not allowed
根因(已修):平台在角色权限之外,还校验蓝图 apis.resources[].operations 是否含 import
旧生成默认只有 list/get/create/update/delete。现已默认带 import且 publish 兜底补全Z9
编辑补丁时模型仍可能只改部分表;再发布或依赖 Z9d/EnsureDefaultImportExport 即可。
另:同 page id 编辑曾 400见 §5.5.1merge 已改)。

产品结论:采用方案 A

绑定宇恒账号解决「谁可以调导入接口」;方案 A 解决「业务表是否声明允许导入」,避免「有权限仍 400」。

不采用「仅有 row.import 就跳过 hasOp」(方案 B作主路径以免列表页无导入入口、前后端能力不一致。

编号 优先级 诉求 说明 现状
Z9a P0 生成默认带 import 业务 apis.resources[].operations 默认含 list,get,create,update,delete,**import**,**export**(除非需求明确禁止) 已落实generation_rules + prompt-contract.md
Z9b P0 列表 actions 对齐 list 页 actions 默认含 import(及可选 export 已落实:发布兜底补 list actions
Z9c P0 改 prompt / 文档 prompt-contract.md:由「提到导入再加」改为「默认加;明确不要再去掉」 已落实
Z9d P0 publish/merge 兜底 发布或编辑合并时:业务 resource 缺 import 则自动补上(可配置,默认开) 已落实EnsureDefaultImportExport;但只在 publish 路径触发
Z9e P0升格 存量模块一次性扫库补齐 平台启动扫库 + 管理接口;不依赖用户再发布 已落实2026-08-05:启动 RunBackfill…POST /api/v1/admin/apps/ensure-import;模块管理「一键开启导入」;超管 …/platform/apps/ensure-import
Z9f P1 读路径也兜底(双保险) Import/Export 入口内存补齐后再校验;可读错误文案 已落实ensureImportOpInMemory + 区分蓝图缺 import vs 权限

存量复现(必须消灭)

POST /api/v1/apps/coerce_fields/items/import
→ HTTP 400: operation import not allowed
蓝图 ops 实为list, create, get, update, delete   ← 无 import
Z9d 已合入后新建模块正常;未再发布的旧模块仍坏)

智建交付标准Z9e 验收)

  1. 不手工编辑、不触发「编辑模块」的情况下,对租户内全部已发布可写业务 resource 执行扫库后:hasOp("import")==true
  2. 回归:任取 3 个「合入 Z9 之前发布」的旧 slug直接 POST .../import 不再出现 operation import not allowed
  3. 控制台可选:「数据同步 / 模块管理 → 一键开启全部业务表导入」按钮,调用同一扫库逻辑。
  4. 文档写明Z9d≠存量修复上线 Z9 后必须跑一次 Z9e,否则用户会反复以为「绑定/权限坏了」。

分工

负责
智建 Z9e/Z9f 已落实;保持 Z9ad错误文案区分「蓝图未开 import」vs「账号无 row.import」
宇恒 / 智能体 导入前尽力自动补齐(已做);表单选对 slug/resource重启 platform 或点「一键开启导入」后旧模块即可 import

验收(含存量)

  1. 新建模块需求不提「导入」→ 发布后 POST .../import 不再因 operation import not allowed 失败。
  2. 旧模块Z9 合入前发布、之后未再发布)在跑完 Z9e 后同样不再 400。
  3. 用户明确写「禁止导入」的表可不含 importdisable_default_import 或表级标记)。
  4. 400 文案可读:指出是蓝图 operations 缺 import而不是笼统「操作失败」。

5.7 【双方已接 Z10】空表也要两侧建齐2026-08-04 / 宇恒接 2026-08-05

现象
本机有空表(如 accounts 0 行)时,线上「查看线上表」没有该表;
仅靠 outbox 行 push 时,没有行就没有建表事件。同理,线上空表下行时本机若缺表,旧 pull 只给空 items、不给列,本机无法建表。

编号 优先级 诉求 现状
Z10a P0 本机空表 → 线上建空表 智建已落实 POST /api/v1/agent/sync/channels/{id}/schema/ensure
Z10b P0 线上空表 → 本机建空表 智建已落实 POST .../schemapull/bootstrap 响应带 columns
Z10c P0 宇恒 sync 周期调用上述 API 宇恒已接2026-08-05sync_schema.ensure_before_drain选「同步」force ensuredrain 前 TTL 节流

契约摘要

POST .../schema/ensure
{ "online_db_id": "...", "tables": [{ "table": "accounts", "pk_column": "id", "columns": ["id","username",...] }] }

POST .../schema
{ "online_db_id": "..." }
→ result.tables[].name / columns / row_count

列一律按 TEXT + 指定 PK 建空表;已存在幂等跳过。详例见 宇恒-松离线数据同步使用文档.md「表结构同步」。

验收

  1. 本机空表 ensure 后,智建「查看线上表」可见同名 0 行表。
  2. 换机 / 仅线上schema → 本机建空表 → bootstrap 灌行。
  3. 有数据的表仍走原 pushensure 不替代 outbox 行同步。

5.8 【已落实 Z11】蓝图增字段须迁 Postgres2026-08-05

联调现象
模块 record 蓝图后来带了 title/content/status,但 Postgres 表仍只有 col_0/col_1/col_2
导入 Excel 若含「标题/内容/状态」→ pq: 关系 "record" 的 "title" 字段不存在 (42703),整批 skipped。
反过来蓝图把这些标成非空、Excel 又没有时,会先报 missing required field: title

编号 优先级 诉求 负责
Z11a P1 编辑/发布增字段后 自动 ALTER 业务表补列 智建已落实BuildPostgresAlterDDL + publish 合并执行;字段-only merge 可发布
Z11b P2 导入时Excel 列映射到蓝图有、库无的字段 → 明确提示迁库 智建已落实42703 行错误附加「请重新发布以自动补列」

说明:存量表补列一律可空,避免 NOT NULL 迁库失败。已有库需再发布一次(或编辑发布增字段)才会 ALTER之后新字段随发布自动补。

5.9 【智建已落实 Z12】生产账号绑定即落点禁止手填通道 / 手建通道2026-08-05

产品约定(生产 · 冻结意向)

  1. 一个登录账号 / 一个智能体 ↔ 本公司同步落点:绑定后,该账号的本机库只进自己的(或公司共享的)线上库,不会接到别人账号的库。
  2. 用户不应:手抄 channel_id、也不应先去「数据同步」里点「新建通道」才能用。
  3. 通道对用户隐藏或自动生成:公司开通 / 智能体启用时,平台自动准备本公司默认同步通道Postgres 线上 A并写到智能体/账号绑定上;控制台「数据同步」留给运维改 DSN不作为开通必经 UI。
  4. 共享库:仅「公司共享数据库」可被多名成员同步到同一 online_db_id;个人库默认隔离。
  5. 方向默认 local_to_remote(松离线 agent push「双向」不是用户必选项。
  6. SyncPage 列表须展示可复制 通道 ID(运维用;普通开通流程不依赖)。
编号 优先级 诉求 说明 负责
Z12a P0 换票带回绑定 POST /api/v1/auth/token(及登录)响应含 channel_id / online_db_id / database_name / sync_bound 智建已落实
Z12b P0 智能体自查绑定 GET /api/v1/agents/me:智能体 Bearer 可读自己的通道/线上库/状态 智建已落实
Z12c P0 启用即自动绑通道 创建/启用智能体 → EnsureSystemDefaultChannelIsSystemDefault,表白名单可空);写回 channel_id+online_db_idDSN 见 DBSync.DefaultRemoteDSN(空则 sqlite 联调文件) 智建已落实
Z12c-1 P0 账号级隔离 Binding / push 校验:用户 JWT 只能写本人 online_db_id 智建已有(自助 Binding
Z12c-2 P1 公司共享库 Binding shared=true:同租户成员可访问该 online_db_id;仅管理员可设 智建已落实
Z12d P1 SyncPage 展示通道 ID 运维可见 + copyable 智建已落实
Z12e P1 唯一默认通道 每公司至多 1 条 is_system_default;复用已有默认 智建已落实 + 宇恒「仅 1 条则写入 env」
Z12f P1 开通 UX 启用智能体即可DSN 用公司级默认 智建已落实(控制台引导文案可再收)

宇恒已做2026-08-05

  1. 当前生产通道 691575c0-… 已写入 env过渡缓存Z12c 落地后应由换票/唯一通道自动获得)。
  2. resolve_sync_channel_id()env → Binding → 租户仅 1 通道自动选用。
  3. 不把「手建通道 + 手抄 ID」当作产品终态。

验收

  1. 新公司:只「启用智能体」,点新建通道,换票已带 channel_id,宇恒可 drain。
  2. 账号 A 的本机库 push 不会出现在账号 B 的线上库;共享库仅在显式共享时可见。
  3. 用户全程无需 F12、无需手填 YXD_SYNC_CHANNEL_ID

5.10 【双方代码已接 Z13】绑定流程简化绑定码 / 手机号2026-08-05

端到端体验(生产目标)

  1. 后台已绑定(或用户用绑定码/手机号完成绑定)→ 宇恒本机库选 「同步」直接可用(自动通道、自动 Binding、agent drain无第二套配置。
  2. 绑定流程必须比「登记智能体 + 抄通道 ID + 填 env」简单。
  3. 生产·宇信达联调账号13531041944(公司侧专用;禁止用超管号 13531041945)。
  4. 试运行:未接短信平台 → 关闭短信验证;正式接入后再开(见下)。

推荐交互

公司管理员(智建后台)
  → 生成「绑定码」→ 发给终端用户

宇恒 · AI建站智能体
  → 检测绑定状态
       ├─ 已绑定 → 静默换票;本机库选「同步」即可用
       └─ 未绑定
            ├─ 宇恒已有手机,且智建同号有成员
            │     → 弹「已有账号是否绑定?」→ 确认 / 取消
            ├─ 表单:【绑定码】或【手机号】
            │     · 宇恒未绑手机 → 仍可直接填手机号
            │     · 试运行:不校验短信,仅确认绑定
            │     · 正式:同号可免短信/凭票;异号须短信
            └─ 无成员 / 无码 → 提示联系管理员
  → 绑定成功 → 选「同步」→ drain零通道配置

试运行 vs 正式

试运行(当前) 正式(接短信后)
配置 SMS.RequireForBind=false(或 Provider=off RequireForBind=true
探测 GET /api/v1/auth/bind/policytrial_mode=truesms_required_unless_attested=false trial_mode=false
填手机号 可绑;不校验短信 异号 / 宇恒未绑号须 sms_code
同号免验 可不传 sms_code;确认即可 同号 attested 或走 ticket-exchange
必保留 「已有账号是否绑定」确认confirm=true 同左

同号 / 验证规则

场景 行为
试运行 / 短信未接入 不校验短信;填号 + 确认即可
宇恒未绑手机 仍可直接输入手机号;正式环境须短信
宇恒已绑且输入 = 已绑号 正式可免短信 / 凭票;命中成员仍弹确认
宇恒已绑且输入 ≠ 已绑号 正式必须短信
命中公司成员 必须询问「已有账号是否绑定」;不得静默
用户确认 绑定该账号 + 公司默认同步落点
用户取消 不绑;可改绑定码 / 换号
公司无此号 提示用绑定码
联调样例 13531041944;勿用 13531041945
编号 优先级 诉求 说明 负责
Z13a P0 后台生成绑定码 POST/GET/DELETE /api/v1/admin/bind-codesSyncPage「绑定码」区 智建已落实
Z13b P0 绑定码兑换 POST /api/v1/auth/bind-code/redeemhost_key + code 双方已接(智建 API + 宇恒表单)
Z13c P0 手机号探测 POST /api/v1/auth/bind/phone-lookup(不直接绑定) 智建已落实
Z13c-1 P0 确认绑定 POST /api/v1/auth/bind/phone-confirmconfirm=true 双方已接(宇恒弹窗 + 本机 API
Z13c-2 P0 验证策略 / 凭票 / policy 试运行关短信;GET /auth/bind/policy;正式异号短信;凭票 ticket-exchange 双方已接(生产须对齐 Secret + 部署 gateway
Z13d P0 未绑定检测与提示 sync_bound=false → lookup / 表单 宇恒已接 ensure_sync_bound_interactive
Z13e P0 选同步即用 库选「同步」→ Binding + drain零手填通道 宇恒已接 POST /database/sync/mode
Z13f P1 安全 试运行关短信;正式强制异号短信;审计 智建开关已落实

验收

  1. 绑定码 → 填码 → 绑定成功 → 库选「同步」→ 数据进公司线上库。
  2. 同号 13531041944 → 弹「已有账号是否绑定」;确认绑、取消不绑;禁用 13531041945
  3. 宇恒未绑手机 → 仍可直接填号;试运行免短信,正式须短信。
  4. 试运行:无 sms_code 也可 confirmGET /auth/bind/policytrial_mode=true
  5. 未绑定用户只见绑定码/手机表单,不见 DSN/通道 ID。
  6. 未确认 / 他人绑定码,不能绑进别的公司或别人账号。
  7. 正式且启凭票:同号走 ticket-exchange,不再依赖明文 attested_same_phone

6. 联系与附件

  • 待改清单(优先看)§0.2(宇恒已完成 A / 仍建议 A / 智建运维阻塞 B
  • 方案:松离线-dbsync方案-最终版.md(含 2026-08-01 联调建议落地记录)
  • 宇恒使用说明:宇恒-松离线数据同步使用文档.md(含 Z10 schema/ensure、Z13 绑定)
  • 开通说明:docs/数据同步-开通说明.md
  • 绑定策略探测:GET /api/v1/auth/bind/policytrial_mode / require_for_bind
  • 本意见如与冻结方案冲突,以冻结方案为准§5.15.10 为产品增量与复测记录,不推翻 H1H6 默认无感约束。