Просмотр исходного кода

docs: clarify cloud action counts

彭峰 1 месяц назад
Родитель
Сommit
48ffce7214

+ 1 - 1
docs/migration/admin-migration-status.md

@@ -15,7 +15,7 @@
 - 云函数网关强制校验管理员身份、`company` 帐套、类白名单、字段白名单和敏感字段过滤。
 - `_Session` 不开放,`Function` 源码不开放通用查询或编辑;用户密码只允许专用重置操作。
 - 8 个管理/CMS 函数均验证未认证请求返回 401;临时帐套管理员完成真实只读冒烟测试后已删除。
-- 第 9 个 `xiaoshu.app.gateway` 已覆盖旧 H5 源码的全部 91 个 action:29 个已映射,62 个显式返回 501 阻塞原因。课程词库进度、学习次数/生词状态、预约学习记录双表写入及旧版课次/时长/佣金统计公式均已完成;预约结束还涉及课时账本与抗遗忘批量创建,继续显式阻塞,避免半写。详见 `wxapp-cloud-action-matrix.md`。
+- 第 9 个 `xiaoshu.app.gateway` 已覆盖旧 H5 源码的全部 91 个 action:29 个已映射,源码清单内 62 个显式返回 501 阻塞原因;网关还保留 `content_add_zt`、`product_add`、`product_upd` 3 个后端兼容阻塞项,因此线上 `blocked` 对象共 65 项。课程词库进度、学习次数/生词状态、预约学习记录双表写入及旧版课次/时长/佣金统计公式均已完成;预约结束还涉及课时账本与抗遗忘批量创建,继续显式阻塞,避免半写。详见 `wxapp-cloud-action-matrix.md`。
 - 旧数据的 `isDeleted` 在部分物理表与 Parse Schema 不一致,把它放入 Parse 查询条件会返回 500;网关改为公司条件查询后在结果侧兼容过滤。
 - Angular H5 已开始按页回归切换:账号密码登录、版本、栏目、公开内容、8 类 addon 联表,以及学习记录详情、预约详情、生词本、21 天抗遗忘列表可走云函数;私有读取只在真实 Parse 会话下切换,其余 action 仍由显式迁移路由保留旧端点。
 

+ 1 - 1
docs/migration/wxapp-cloud-action-matrix.md

@@ -5,7 +5,7 @@
 - 基线来自旧 uni-app 源码静态扫描生成的 `SOURCE_API_ACTIONS`,共 91 个唯一 action。
 - 统一新入口为 `POST /api/functions/xiaoshu/app/gateway`。
 - 请求体统一使用 `{ "token": "<sessionToken>", "params": { "action": "...", ... } }`;执行器会占用顶层 `id`,业务参数不得放在顶层。公开接口可省略 `token`,但仍必须保留 `params`。
-- 已有云函数映射 29 个,另有 62 个以 HTTP 501 和 `migration_blocked: <原因>` 显式拒绝。矩阵不存在未知 action。
+- 已有云函数映射 29 个,源码清单内另有 62 个以 HTTP 501 和 `migration_blocked: <原因>` 显式拒绝。网关额外保留 `content_add_zt`、`product_add`、`product_upd` 3 个后端兼容阻塞项,因此线上 `blocked` 对象共 65 项;矩阵不存在未覆盖的源码 action。
 - “已映射”表示已有云函数代码与权限边界;完成 H5 切换前仍需逐页响应字段回归。
 
 ## 已映射的 29 个 action

+ 9 - 2
scripts/smoke-admin-functions.mjs

@@ -141,9 +141,16 @@ try {
   if (!Array.isArray(guest.results)) throw new Error('互动社区投影校验失败');
 
   const migration = await callLegacyFunction('', { action: 'migration_status' });
-  const covered = new Set([...(migration.result?.implemented || []), ...Object.keys(migration.result?.blocked || {})]);
-  const missing = (await sourceActions()).filter((action) => !covered.has(action));
+  const sourceActionList = await sourceActions();
+  const implementedActions = migration.result?.implemented || [];
+  const blockedActions = Object.keys(migration.result?.blocked || {});
+  const covered = new Set([...implementedActions, ...blockedActions]);
+  const missing = sourceActionList.filter((action) => !covered.has(action));
   if (missing.length) throw new Error(`app gateway 迁移矩阵缺少:${missing.join(', ')}`);
+  const sourceBlocked = blockedActions.filter((action) => sourceActionList.includes(action));
+  const compatibilityActions = blockedActions.filter((action) => !sourceActionList.includes(action)).sort();
+  if (implementedActions.length !== 29 || sourceBlocked.length !== 62) throw new Error(`app gateway 源 action 计数异常:${implementedActions.length} 已映射 / ${sourceBlocked.length} 阻塞`);
+  if (compatibilityActions.join(',') !== 'content_add_zt,product_add,product_upd') throw new Error(`app gateway 兼容 action 计数异常:${compatibilityActions.join(',')}`);
 
   const content = await callLegacyFunction('', { action: 'content_list', page: 1, pageSize: 2 });
   if (!Array.isArray(content.result) || content.result.length !== 2 || Number(content.page?.itemCount) < 89000) throw new Error('公开内容分页校验失败');