mirror of
https://github.com/sinanyuntu/trade-message-center.git
synced 2026-09-17 13:22:11 +08:00
* feat: add OneTalk quote reply support * chore(task): archive 09-17-onetalk-quote-reply-protocol * chore: record journal * docs: format OneTalk DOM card collection plan * chore: release 0.8.29 * chore: release 0.8.30
5.2 KiB
5.2 KiB
OneTalk 文本引用回复实施计划
Preconditions
- 实施前在两个实际部署的 checkout 确认 Mind 和 Center 当前正在使用的 WebSocket protocol version。仓库快照显示常量不同,不能假定只改一侧即可兼容。
- 只改 OneTalk 文本发送;媒体/富卡引用不进入本计划。
- 在写任何 SDK raw 索引前,确认其生命周期仅限 MAIN world,且不会被现有
createOneTalkObservedPublisher、page bridge、日志或 IndexedDB 传播。
Workstream A — Shared contract and Center
- 在
packages/onetalk-contract/src/sending.ts为发送 payload 定义可选replyToMessageId;保留普通发送精确 shape,新增文本引用 shape,拒绝空字符串、非文本 content 和未知额外字段。 - 同步
isValidOneTalkSendingPayload、frame type exports、协议版本和packages/onetalk-contract/test/contract.test.ts。旧版本或只有一端携带新字段必须得到现有 protocol/invalid-message 失败,不作静默兼容。 - 验证
apps/server/src/websocket/pending-send-coordinator.ts仍仅按账号、scope、conversation 和sendRequestId授权/关联;它可透传验证过的replyToMessageId,但不解析引用源或存储 raw 数据。 - 更新
apps/server/test/websocket.test.ts:Mindsend.request到 pluginsend.command透传文本引用 ID;普通文本不带该字段;空/媒体/额外字段拒绝;失败/超时仍保持三态 payload。
Workstream B — Plugin MAIN-world resolution
- 在
apps/chrome-extension/src/onetalk/main-page/message-observer/新增私有文本引用源索引。它以channelAccountId + conversationId + normalizeOneTalkMessageId(messageId)为键,存储最小的 SDK quote 输入来源,写入仅来自已验证的 raw history/live OneTalk 文本消息。 - 历史和实时解析在发布白名单观察前,向该索引登记
messageIdForSdk、subType: 1、senderAliId、方向对应名称、originalData、文本和sendTime。若必要字段不完整,不登记;不得从已发布的OneTalkMessage反构originalData。 - 账号切换、页面重载、会话不一致时使索引不可用。lookup 要求 command 的 conversation、当前登录
channelAccountId和 canonical message ID 三者一致。 - 将
replyToMessageId以可选顶层字段从send.command路由至 page command;扩展handleOneTalkSendCommand与SendObservationCorrelator.execute的输入,使最终 SDK 输入为{ cid, conversationCode: cid, content, referMessage }。 - 只有 lookup 成功才调用
sendUIMessages。引用源缺失、跨账号/会话、非文本或 SDK 不可用时返回 canonicalrejected_before_send/invalid_request或send_not_supported;绝不降级为普通发送、DOM 点击或私有 EventBus。 - 保持
SendObservationCorrelator单一确认机制:SDK result 只补充候选 ID,最终确认仍由完整direction: sent旁路消息决定。 - 扩展
apps/chrome-extension/test/onetalk-send-page.test.js、onetalk-send-observation.test.js、onetalk-websocket-tap.test.js及新增 focused quote-index test,覆盖输入 shape、MAIN 隔离、.PNM恢复、预发送拒绝、SDK input 和非引用回归。
Workstream C — Mind text reply UX and WS client
- 在
trade-mind/apps/web/src/features/communication/communication-onetalk-bright-types.ts和communication-onetalk-bright-realtime-rules.ts为OneTalkBrightSendMessageRequest、frame builder 和 reader 增加可选replyToMessageId,并采用已协商的 protocol version。 - 在
alibaba-message-timeline.tsx添加只针对普通文本消息的回复按钮;该组件只将{ id, from, text }回调给 workspace,不暴露原始协议数据。 - 在
communication-workspace.tsx持有当前 OneTalk 文本引用目标,将它传入oneTalkBrightRealtime.sendMessage,并在取消、会话切换、成功与拒绝后清理。为 Alibaba composer 添加引用预览,不增加历史引用卡。 - 补 Mind focused tests:frame writer/parser 的可选字段与拒绝条件、文本行显示回复操作、非文本/系统/optimistic 行不显示、composer 取消和发送 payload、会话切换清理。
Verification gates
- Shared contract package tests和 server WebSocket tests(每个后端测试命令必须限制在 60 秒内)。
- Chrome extension focused tests:send handler、raw quote source index、WebSocket/history observer、page bridge flow;再运行对应 type/lint/build 检查。
- Mind focused unit/render tests和 TypeScript check;在 Mind checkout 验证 WS builder 与当前 Center protocol version 匹配。
- 真实 Chromium:在当前会话对一条已加载的入站文本发出引用;确认 SDK input 的
referMessage、OneTalk 引用 UI、WebSocket complete sent fact 和 Mindconfirmed_sent。再在未选中的目标会话测试cid路由。 - 回归普通文本、图片和文件发送,确认无
replyToMessageId时 payload 与确认语义不变。
Rollback
- 协议或 raw lookup 任一步不满足时,发布前不启用 Mind 回复入口;已有普通发送保持不带
replyToMessageId的精确 payload。 - 若上线后需回退,统一回退 Mind 与 Center/插件的协议版本;禁止仅回退一端后让新字段被静默吞掉。