GPU_GUARD_MONOREPO/docs/superpowers/followups/2026-05-12-weixin-db-e2e-report.md
2026-05-20 21:39:12 +08:00

9.6 KiB

weixin-db E2E 验证报告(架构 C, 2026-05-12)

执行方式:subagent-driven-development。 本文档记录 plan docs/superpowers/plans/2026-05-12-weixin-db-channel.md 的完成情况、自动化验证结果、剩余手工 E2E 清单。

完成状态总览

阶段 Tasks 状态
Phase C-0 · session.db schema PoC C0-1 DONE
Phase C-1 · 清理作废代码 Task 1-5 DONE
Phase C-2 · runtime/weixin_db/ 纯函数模块 Task 6-15 DONE
Phase C-3 · weixin_db.ts 主服务装配 Task 16 DONE
Phase C-4 · agent_channel 集成 Task 17, 18 DONE
Phase C-5 · agent_channel_group 改用户主动添加 Task 19, 20 DONE
Phase C-6 · 前端 UX Task 21, 22, 23 DONE
Phase C-7 · 安装包 + Tray Task 24, 25, 26 DONE
Phase C-8 · 端到端手工验证 Task 27 待用户跑
Phase C-9 · 回复路径 5.7 占位 (独立 spec)

自动化验证结果

1. session.db / contact.db schema RE (Phase C-0)

脚本: packages/backend/poc/weixin-4x/poc-13-session-schema.mjs + poc-14-contact-schema.mjs 结果文档: packages/backend/poc/weixin-4x/README-session-schema.md

关键发现:

  • Msg 表名算法确认: tableName = 'Msg_' + md5(username) (100/100 命中)
  • session.db 主表: SessionTable.username(列出所有会话)
  • 群显示名来源: contact.db 的 contact 表 (remark > nick_name > username)
  • 依此真实 schema 回填room_resolver.ts(Task 12),不再是假设。

2. key 抽取 PowerShell 脚本冒烟(Task 10)

powershell.exe -ExecutionPolicy Bypass -NoProfile -File packages/backend/tools/win32/extract-weixin-key.ps1

实际输出(2026-05-12 测试):

{"seedDir":"C:\\Users\\lixin\\Documents\\xwechat_files\\shin_seed_7861",
 "wxid":"shin","wechatVersion":"4.1.8.107","pid":39916,
 "dbKeys":{"message_0.db":"374c4e1a...","session.db":"e43bd85c...","contact.db":"bd93ce66...",...}}

17 个 DB 的 key 全部成功抽取。

3. 后端单测 (与 weixin-db 相关的 suite)

pnpm --filter @neta/backend test -- netaclaw/runtime/weixin_db netaclaw/service/weixin_db netaclaw/service/agent_channel netaclaw/service/agent_channel_group

Test Suites: 13 passed, 13 total
Tests:       92 passed, 92 total
Time:        7.954 s

覆盖:

  • runtime/weixin_db/ 全部模块(wcdb_codec / zstd_decode / db_paths / key_extractor / message_repo / room_resolver / wal_watcher / build_pseudo) — 均 TDD 通过
  • service/weixin_db.ts — 5 个 case (replyToGroup 占位 throw、bindChannel 在/非 Windows、refreshWhitelistunbindChannel 幂等)
  • service/agent_channel.ts — 含 17+9+6 测试:page enrichment 切换为 weixin-db、group 路由经 findByKey + replyToGroup、delete 走 unbindChannel、toggle 刷新 whitelist
  • service/agent_channel_group.ts — 27 个测试:addByName 新语义、toggle 不再接受 -1、updatePolicy 拒绝 prefix 等

4. Tray .NET 单测(Task 26)

dotnet test packages/windows-tray/Neta.Tray.Tests
已通过! - 失败: 0,通过: 5,已跳过: 0,总计: 5

删除 BridgeProcessManager / BridgeHealthPoller / BridgeProcessManagerTests.cs 后,Neta.Tray 仅管理 backend.exe,5 个剩余测试全通。

5. Installer 脚本(Task 24, 25)

  • build-windows-installer.js: 删 bridge dotnet publish 步骤,加 tools/win32/*.ps1 拷贝步骤
  • setup.iss: 删 bridge-output\* / bridge.exe uninstall taskkill;加 tools-output\win32\*{app}\tools\win32

语法检查通过,实际 iscc 构建需在 Inno Setup 环境下执行,未包含在本次自动化验证中。

手工 E2E Checklist (Task 27)

以下需用户在真实 Windows + PC 微信环境手工跑:

  • E2E-1: 前端新建 channel type=微信本地代理(群聊),填 wxid shin → 保存成功
  • E2E-2: backend 启动时看日志 [weixin-db] channel X bound, wxid=shin ver=4.1.8.107 pid=XXXXX,无 error
  • E2E-3: 前端"群聊管理"打开,显示"已添加监管 0 个群" → 点 "+ 添加群" → 输入测试群完整名 → 提交
  • E2E-4: backend 日志 addByName created=true;netaclaw_agent_channel_group 多一行 status=1
  • E2E-5: 测试群里发"hello"(触发策略 at_mention) → backend 看到 [weixin-db] incremental read 但 agent 不回(at_mention 未命中)
  • E2E-6: 群里发 @机器人 你好 → routeInboundMessage 走 handleInboundMessage group 路径 → agentExecutor 执行 → replyToGroup throw 占位 → 日志 weixin-db reply 暂未实现, cid=X room=测试群 skipped
  • E2E-7: 切到"所有消息"策略 → 未加白名单的群发消息 → backend 完全没反应(白名单过滤生效)
  • E2E-8: 白名单群发消息 → backend 看到处理
  • E2E-9: 前端删除该群白名单 → DB row 消失 → 再发消息 backend 无反应
  • E2E-10: 关 Weixin → wal 不变,backend 平静;重开 Weixin → 健康探针触发 → 自动 rebind(60s 内)

关键技术决策记录

  1. 架构 C: 纯 Node + PowerShell(无独立 .NET bridge 进程)。ps1 脚本 spawn 一次抽 key,后续 Node 本进程处理。
  2. 零被动发现: 群必须用户主动添加,白名单在 DB 解密阶段即过滤,bot 物理上读不到非白名单群消息(隐私保护)。
  3. 回复路径占位: replyToGroup 当前 throw NotImplementedError,agent_channel.handleDbInbound try/catch 跳过,不阻塞读链路。spec 5.7 独立 plan 实施。
  4. 跨平台兜底: 非 Windows loginStatus='unsupported_platform',不 spawn powershell 不 crash。
  5. 重连机制: WeixinDbService 60s 健康探针,基于 process.kill(pid, 0) + fs.accessSync 判断 Weixin 进程 + DB 可读。

遗留 Follow-up

  1. Task 27 E2E: 待用户跑,目前仅自动化部分已验证。
  2. Phase C-9: replyToGroup 真实实现(5.7)需独立 spec(剪贴板/UIA/WCF 等方案待 brainstorm)。
  3. bigint 字面量: tsconfig.target=es2018 不支持 999n 字面量,实现处用 BigInt(...) 构造(已注意)。
  4. zstd API: @mongodb-js/zstd v2 只有 async,tryDecompressToString 已 async(plan Task 8.1 兜底方案)。
  5. better-sqlite3 + zstd native bindings: root package.json pnpm.onlyBuiltDependencies 已包含两者,prebuild-install 会在 pnpm install 时正确执行。

文件清单

新增

后端 runtime:

  • packages/backend/src/modules/netaclaw/runtime/weixin_db/wcdb_codec.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/zstd_decode.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/db_paths.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/key_extractor.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/message_repo.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/room_resolver.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/wal_watcher.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/incremental_reader.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/types.ts
  • packages/backend/src/modules/netaclaw/runtime/weixin_db/build_pseudo.ts
  • packages/backend/src/modules/netaclaw/service/weixin_db.ts

后端测试: 上述所有模块对应的 .test.ts,以及 test/modules/netaclaw/service/agent_channel.weixin_db.test.ts

工具脚本: packages/backend/tools/win32/extract-weixin-key.ps1

PoC:

  • packages/backend/poc/weixin-4x/poc-13-session-schema.mjs
  • packages/backend/poc/weixin-4x/poc-14-contact-schema.mjs
  • packages/backend/poc/weixin-4x/README-session-schema.md
  • packages/backend/poc/weixin-4x/session-schema-output.log
  • packages/backend/poc/weixin-4x/contact-schema-output.log (若写了)

修改

后端:

  • packages/backend/src/modules/netaclaw/service/agent_channel.ts(weixin-uia → weixin-db 全替换,-147 行净删)
  • packages/backend/src/modules/netaclaw/service/agent_channel_group.ts(upsertOnInbound → addByName)
  • packages/backend/src/modules/netaclaw/controller/admin/agent_channel_group.ts(加 /add)
  • packages/backend/src/comm/path.ts(删 pWechatUploadsPath)
  • packages/backend/src/config/config.default.ts(删 wechatUploads 静态映射)
  • packages/backend/scripts/build-windows-installer.js(删 bridge publish,加 tools/win32 拷贝)
  • packages/backend/installer/setup.iss(删 bridge 项,加 tools 项)
  • packages/backend/package.json(加 @mongodb-js/zstd)

前端:

  • packages/frontend/src/modules/agent/types/index.d.ts(类型切换)
  • packages/frontend/src/modules/agent/views/channel-management.vue(文案+字段)
  • packages/frontend/src/modules/agent/components/channel-group-panel.vue(大改 UX,用户主动添加)
  • packages/frontend/src/modules/agent/composables/useDbChannelValidation.ts(改名 from useUiaChannelValidation.ts)

:

  • package.json(加 pnpm.onlyBuiltDependencies)

Tray:

  • packages/windows-tray/Neta.Tray/TrayApplicationContext.cs(删 bridge 拉起逻辑,316→169 行)

删除

  • packages/backend/src/modules/netaclaw/service/weixin_uia.ts + wechat_archive.ts
  • packages/backend/src/modules/netaclaw/controller/open/weixin_uia.ts + admin/wechat_archive.ts
  • packages/backend/src/modules/netaclaw/runtime/wechat_uia_routing.ts + wechat_archive_schema.ts
  • 对应 test 文件 6 个
  • packages/windows-tray/Neta.WeChatBridge/ + Neta.WeChatBridge.Tests/ 整个目录
  • packages/windows-tray/Neta.Tray/BridgeProcessManager.cs + BridgeHealthPoller.cs
  • packages/windows-tray/Neta.Tray.Tests/BridgeProcessManagerTests.cs
  • packages/frontend/src/modules/agent/components/wechat-archive-panel.vue
  • packages/frontend/src/modules/agent/composables/useUiaChannelValidation.ts(被 useDbChannelValidation.ts 替代)