diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index e175875c5..8d473926f 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -2710,3 +2710,10 @@ - 决策:`startWechatLogin()` 先调用 `openHostExternalUrl()`,在 `native_app` 且宿主声明 `app.openExternalUrl` 时把微信授权 URL 交给宿主系统浏览器;宿主未声明、拒绝或失败时才回退原浏览器跳转。该流程只收口外链打开方式,不改变后端微信 OAuth 回调、绑定手机号或登录态刷新事实。 - 影响范围:`src/services/authService.ts`、`src/services/authService.test.ts`、宿主壳能力统一协议文档。 - 验证方式:`npm run test -- src/services/authService.test.ts -t "wechat login"`、`npm run typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。 + +## 2026-06-19 登录与支付外链纳入 HostBridge 必扫调用链 + +- 背景:`check:native-shells` 已能自动发现直接导入 HostBridge facade 的 H5 生产文件,但登录授权和 H5 支付跳转属于敏感外部跳转路径,后续如果被重构到薄包装层或兼容导出,单纯自动发现可能让它们脱离临时替身词扫描和调用链漂移门禁。 +- 决策:`scripts/check-native-shells.mjs` 的 H5 HostBridge 真实调用链必扫清单固定包含 `src/services/authService.ts` 和 `src/services/payment/paymentRedirect.ts`。这两个文件必须持续通过 `openHostExternalUrl()` 承接原生壳外链打开,不得绕回未受控的登录 / 支付伪实现。 +- 影响范围:`scripts/check-native-shells.mjs`、Expo / Tauri HostBridge 方案文档、共享开发流程记忆。 +- 验证方式:`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。 diff --git a/docs/project-memory/shared-memory/development-workflow.md b/docs/project-memory/shared-memory/development-workflow.md index 7dc907565..c40ad2977 100644 --- a/docs/project-memory/shared-memory/development-workflow.md +++ b/docs/project-memory/shared-memory/development-workflow.md @@ -216,7 +216,7 @@ npm run build npm run check:native-shells ``` -该命令会覆盖 H5 HostBridge 关键测试、微信 / Expo / Tauri 三端桥接层文件结构门禁、完整相对路径文档反查、H5 HostBridge 事件订阅双能力门控反查、H5 `navigation.canGoBack` 消费 hook 与直达二级页返回锚点测试、移动端和桌面端单端源码清单门禁、Expo 壳 typecheck / test / config smoke / Metro export smoke、Tauri 壳 typecheck / cargo test、桌面壳 release `--no-bundle` 构建烟测,以及可分发壳与 H5 HostBridge 真实调用链的临时替身词扫描,确认 Expo managed config、移动端 iOS / Android production bundle、打包 H5 资产、Tauri release 入口、H5 页面内导航保留完整原生宿主上下文和 H5 HostBridge 真实调用链没有漂移;扫描范围包含微信小程序壳生产 `.js`、共享 HostBridge 契约、H5 native transport,并自动覆盖已接入真实宿主能力 facade 的 H5 生产调用链文件。壳源码和配置继续严格禁止 mock / fake / placeholder / stub / TODO / FIXME / 占位 / 模拟 / 伪造;H5 业务调用链允许正常表单 `placeholder` 属性和业务占位图文案,但仍禁止 mock / fake / stub / TODO / FIXME / 模拟 / 伪造等替身痕迹。 +该命令会覆盖 H5 HostBridge 关键测试、微信 / Expo / Tauri 三端桥接层文件结构门禁、完整相对路径文档反查、H5 HostBridge 事件订阅双能力门控反查、H5 `navigation.canGoBack` 消费 hook 与直达二级页返回锚点测试、移动端和桌面端单端源码清单门禁、Expo 壳 typecheck / test / config smoke / Metro export smoke、Tauri 壳 typecheck / cargo test、桌面壳 release `--no-bundle` 构建烟测,以及可分发壳与 H5 HostBridge 真实调用链的临时替身词扫描,确认 Expo managed config、移动端 iOS / Android production bundle、打包 H5 资产、Tauri release 入口、H5 页面内导航保留完整原生宿主上下文和 H5 HostBridge 真实调用链没有漂移;扫描范围包含微信小程序壳生产 `.js`、共享 HostBridge 契约、H5 native transport,并自动覆盖已接入真实宿主能力 facade 的 H5 生产调用链文件。登录与支付外链跳转必须保持在该调用链扫描内,`src/services/authService.ts` 和 `src/services/payment/paymentRedirect.ts` 是必扫文件。壳源码和配置继续严格禁止 mock / fake / placeholder / stub / TODO / FIXME / 占位 / 模拟 / 伪造;H5 业务调用链允许正常表单 `placeholder` 属性和业务占位图文案,但仍禁止 mock / fake / stub / TODO / FIXME / 模拟 / 伪造等替身痕迹。 创作 Agent 原生壳文档导入优先走 `file.importDocument`,旧壳只声明 `file.importText` 时才回退文本导入;相关变更必须让根级和单端门禁覆盖共享 method、capability profile、文档 MIME / 5 MiB 上限、读取前 size 校验,以及 H5 base64 转 `File` 后继续走后端文档解析的链路。 创作 Agent 参考图上传在原生壳声明 `file.importImage` 时必须优先走宿主图片导入,并把 H5 base64 转 `File` 后继续交给既有 `onReferenceImageChange` 校验链路;用户取消原生选择不应再连带弹出浏览器文件输入,普通浏览器、小程序和未声明能力的裁剪壳才使用原隐藏文件输入。 创作 Agent 轻输入 composer 的参考图按钮在原生壳声明 `file.importImage` 时必须优先走宿主图片导入;移动壳声明 `file.captureImage` 时才显示拍摄参考图入口,并把宿主图片同样转为 `File` 后复用 `readPuzzleReferenceImageAsDataUrl` 的类型、大小、压缩和预览链路。 diff --git a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md index c92c9771d..62a8439e6 100644 --- a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md +++ b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md @@ -475,7 +475,7 @@ GameBridge 禁止: 2026-06-18 追加:微信 / Expo / Tauri 三端壳的生产源码和配置禁止出现 mock / fake / placeholder / stub / TODO / FIXME 以及对应中文脚手架词;测试文件仍可使用 `vi.mock` 或等价测试替身。`apps/mobile-shell/scripts/check-config.mjs` 与 `apps/desktop-shell/scripts/check-config.mjs` 会扫描各自生产入口、配置和壳实现;根级 `npm run check:native-shells` 会统一扫描 `miniprogram`、`apps/mobile-shell`、`apps/desktop-shell`、H5 HostBridge transport 和共享 HostBridge 契约生产源码,防止把临时替身或占位文案带进可分发壳。 -2026-06-19 追加:H5 HostBridge 真实调用链扫描改为自动发现。根级 `npm run check:native-shells` 会从 `src/` 生产文件里收集直接导入并调用真实宿主能力 facade 的文件,以及 `useHostLifecycleActive`、`useHostNetworkOnline`、`platformProfileHostClipboard` 等薄 wrapper 的消费者;新增 `reloadHostWebView`、`showHostLocalNotification`、`setHostAppBadgeCount`、`importHostTextFile`、`importHostImageFile`、`captureHostImageFile`、`subscribeHostImageDrop`、`readHostClipboardText`、`openHostExternalUrl` 等 H5 调用点时,不再手工维护单个扫描文件清单。H5 业务文件允许正常表单 `placeholder` 属性和业务占位图文案,但仍会拒绝 mock / fake / stub / TODO / FIXME / 模拟 / 伪造等替身痕迹。 +2026-06-19 追加:H5 HostBridge 真实调用链扫描改为自动发现。根级 `npm run check:native-shells` 会从 `src/` 生产文件里收集直接导入并调用真实宿主能力 facade 的文件,以及 `useHostLifecycleActive`、`useHostNetworkOnline`、`platformProfileHostClipboard` 等薄 wrapper 的消费者;新增 `reloadHostWebView`、`showHostLocalNotification`、`setHostAppBadgeCount`、`importHostTextFile`、`importHostImageFile`、`captureHostImageFile`、`subscribeHostImageDrop`、`readHostClipboardText`、`openHostExternalUrl` 等 H5 调用点时,不再手工维护单个扫描文件清单。登录与支付外链属于敏感跳转路径,`src/services/authService.ts` 和 `src/services/payment/paymentRedirect.ts` 额外列入必扫清单,防止后续绕回裸浏览器跳转却脱离 HostBridge 调用链门禁。H5 业务文件允许正常表单 `placeholder` 属性和业务占位图文案,但仍会拒绝 mock / fake / stub / TODO / FIXME / 模拟 / 伪造等替身痕迹。 2026-06-18 追加:微信壳行为测试进入原生壳统一验收。`npm run check:native-shells` 会运行 `miniprogram/host-bridge/`、`miniprogram/shell/`、`pages/web-view` 样式和 `scripts/miniprogram-web-view-auth.test.ts` 测试,覆盖微信 WebView 入口、登录触发、分享目标、支付结果、订阅消息结果和九宫切图桥接行为;三端桥接层文件结构检查只锁定职责边界,真实行为回归必须由同一门禁中的微信壳测试证明。 diff --git a/scripts/check-native-shells.mjs b/scripts/check-native-shells.mjs index f9580aea3..3b8953402 100644 --- a/scripts/check-native-shells.mjs +++ b/scripts/check-native-shells.mjs @@ -91,7 +91,9 @@ const h5HostBridgeRequiredCallChainFiles = [ 'src/hooks/useHostNetworkOnline.ts', 'src/main.tsx', 'src/services/appTitle.ts', + 'src/services/authService.ts', 'src/services/clipboard.ts', + 'src/services/payment/paymentRedirect.ts', 'src/services/runtimeAudioFeedback.ts', 'src/services/wechatMiniProgramShareTarget.ts', 'src/services/wechatMiniProgramSubscribe.ts',