关于 integrate-webapi
integrate-webapi 是通过 Web API 将 Power Pages 站点连接到 Dataverse 的技能。它识别站点所需的数据表、生成集成代码,并可指导配置表权限和站点设置。
主要功能
- 01识别需要集成的数据表
- 02生成适配框架的 API 代码
- 03支持 AI 只读调用模式
- 04指导配置权限与站点设置
- 05验证生成文件和构建结果
适用场景
- 01用 Dataverse 数据替换模拟数据
- 02为站点添加表 API 操作
- 03为 AI 摘要准备只读访问
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill integrate-webapi安装后在 Claude Code 中输入/integrate-webapi确认已加载。
附带文件references/non-spa-site-workflow.mdscripts/validate-webapi-integration.js
详细介绍
插件检查:运行
node "${PLUGIN_ROOT}/scripts/check-version.js"— 如果输出消息,请在继续前展示给用户。
集成 Web API
将 Power Pages 站点与 Dataverse 集成。SPA 站点保留特定框架的客户端、服务和 Hook 工作流。非 SPA 站点优先使用原生 Forms、Lists 和 Liquid;仅当所请求的客户端交互需要时,才添加 Web API JavaScript。
站点类型路由
阅读或执行以下工作流之前,先执行现有的 SPA 项目查找:
-
使用现有文件搜索模式,在当前目录或其直接子目录中查找
powerpages.config.json。 -
如果找到,则继续执行下方现有的 SPA 工作流。不要运行任何非 SPA 站点检测,也不要更改 SPA 阶段、提示、门控条件、生成的文件或部署行为。
-
只有当现有的 SPA 查找未找到
powerpages.config.json时,才运行:node "${PLUGIN_ROOT}/scripts/lib/detect-project-context.js" -
如果返回
siteType: "non-spa",则阅读并遵循${PLUGIN_ROOT}/skills/integrate-webapi/references/non-spa-site-workflow.md中完整的七阶段工作流。不要执行下方任何 SPA 工作流。 -
否则,继续执行阶段 1,并保留现有的未找到处理方式。
非 SPA 路由支持其工作流参考文档中定义的请求导向和发现式调用。SPA 调用语义仍按下方现有工作流定义执行。当 $ARGUMENTS 包含 [CALLED-BY-PARENT-SKILL] 时,将该标记及其可选的 caller=<skill-name> 令牌传递给非 SPA 工作流。它仅抑制提交和部署交接;不会绕过非 SPA 范围审批或安全规划。
核心原则
- 先串行处理第一张表,再并行处理:必须单独处理第一张表,因为它会创建共享的
powerPagesApi.ts客户端。完成后,其余表可以并行处理,因为每张表都会创建彼此独立的文件(类型、服务、Hook)。 - 并行调用相互独立的 Agent:
table-permissions-architect和webapi-settings-architectAgent 相互独立,应并行调用,而非顺序调用。 - 权限配置需要部署:必须先存在
.powerpages-site文件夹,才能配置表权限和站点设置。可以先编写集成代码,但不能配置权限。 - AI 专用只读模式为可选:当其他技能(例如
/add-ai-webapi)在$ARGUMENTS中传入[AI-READ-ONLY]标记时,此流程会生成只读代码,并强化设置和权限,以支持 AI 摘要读取。参见阶段 1.6 中的约定。人工调用不会触发此模式。 - 使用 TaskCreate/TaskUpdate:在所有阶段持续跟踪进度 — 开始任何工作前,先创建包含所有阶段的待办事项列表。
- 保持站点完整性:在 Agent 更改由 Mock 支持或由数据驱动的 UI 之前,请阅读
${PLUGIN_ROOT}/references/site-modification-integrity.md;如果存在清单,需为每个新增的可见状态添加本地化,并确保组件支持双向更新且可安全扩展。
先决条件:
- 一个通过
/create-site创建的现有 Power Pages SPA 站点- 已通过
/setup-datamodel设置好 Dataverse 数据模型(表/列),或已手动创建该模型- 站点至少部署过一次(必须存在
.powerpages-site文件夹)才能设置权限
初始请求: $ARGUMENTS
工作流
- 验证站点是否存在 — 定位 Power Pages 项目并验证前置条件
- 探索集成点 — 分析站点代码和数据模型,找出需要集成 Web API 的表
- 审核集成计划 — 向用户展示调查结果,并确认要集成哪些表
- 实施集成 — 对每个表使用
webapi-integrationAgent - 验证集成 — 确认所有预期文件均存在,且项目可以成功构建
- 设置权限和配置 — 选择权限来源(上传图表,或让架构师进行分析),然后配置表权限和 Web API 站点设置,并使用经过验证、区分大小写的列名
- 审核并部署 — 请用户部署站点;若用户确认,则调用
/deploy-site
第 1 阶段:验证站点是否存在
目标:定位 Power Pages 项目根目录,并确认已满足前置条件
操作:
1.1 定位项目
在当前目录或其直接子目录中查找 powerpages.config.json,以定位项目根目录。请使用文件搜索工具(例如使用 powerpages.config.json 和 */powerpages.config.json 模式的 Glob),而不要使用特定于 Shell 的命令。
如果未找到:告知用户先使用 /create-site 创建站点。
1.2 读取现有配置
读取 powerpages.config.json 以获取站点名称。
1.3 检测框架
读取 package.json 以确定框架(React、Vue、Angular 或 Astro)。完整的框架检测映射请参阅 ${PLUGIN_ROOT}/references/framework-conventions.md。
1.4 检查数据模型
查找 .datamodel-manifest.json 以发现可用的表:
**/.datamodel-manifest.json
如果找到,请读取该文件——它是发现表的主要来源。
1.5 检查部署状态
查找 .powerpages-site 文件夹:
**/.powerpages-site
如果未找到:提醒用户,权限阶段(第 6 阶段)需要先部署。集成代码仍可继续实施(第 2 至第 5 阶段)。
1.6 检测 AI 专用只读模式(技能间调用)
检查 $ARGUMENTS。如果文本以哨兵标记 [AI-READ-ONLY] 开头,则调用方是另一个技能(通常是 /add-ai-webapi),该技能已分析过网站,并确定了 AI 摘要读取所需的 Layer 1/2 前置条件涉及哪些表。解析 $ARGUMENTS 中以下结构化标记:
| 标记 | 必需 | 含义 |
|---|---|---|
mode=ai-read-only | 是 | 确认执行模式;任何其他值都会被拒绝并报错。 |
primary=<logical_name> | 是 | 正在生成摘要的主表。缺失时 → 停止并向调用方报告契约违规。 |
tables=<csv> | 是 | 范围内所有表的逗号分隔列表(主表 + 每个 $expand 目标)。 |
expand-targets=<csv> | 否 | tables 中作为 $expand 目标的子列表;默认为空。 |
caller=<skill-name> | 否 | 仅供参考 — 用于提交消息和最终摘要。 |
存在哨兵标记时:
- 设置内部标志 AI 专用只读模式 = true,供所有后续阶段检查。
- 跳过第 3 阶段的交互式表确认,按原样使用提供的
tables列表(用户已在调用方确认)。 - 第 4.1 阶段的
webapi-integration提示词将操作限制为只读(列表 + 按 ID 获取)。 - 第 6 阶段路径 B 的 Agent 提示词采用各 Agent“AI 专用只读模式”部分中记载的强化 AI 专用执行模式。
- 第 6 阶段路径 A 的脚本调用仅对表权限使用
--read,并从Webapi/<table>/fields中省略主键 / 关系 Navigation Properties。 - 第 3 阶段或第 6.2 阶段均不发出
AskUserQuestion提示;这些决策由调用方负责。 - 将所有 git 提交推迟给调用方。 完全跳过第 4.4 阶段(
git add -A && git commit)和第 6.5 阶段(权限 / 设置提交)。调用方会在编排方定义的里程碑处将更改合并为一到两次提交;此处未提示就提交,会把一个逻辑更改拆成三次提交。打印本应提交的文件列表,以便调用方据此操作。 - 抑制技能结束时的部署提示。 跳过第 6.1 阶段(缺少
.powerpages-site时询问是否立即部署)、第 7.3 阶段(最终部署询问)和第 7.4 阶段(部署后说明)。由调用方统一决定整个编排流程是否部署;在委派过程中嵌套部署提示,会让用户每次运行都收到 2–3 次重复询问。返回集成摘要(第 7.2 阶段),末尾不附加部署提示或说明。
不存在哨兵标记时:完全按当前方式继续(完整 CRUD、完整交互流程、自动提交、部署提示)。这是回归保护机制 — 任何人工调用的行为都不会改变。
输出:确认的项目根目录、框架、数据模型可用性、部署状态,以及(若存在哨兵标记)解析出的 AI 只读契约。
Phase 2: 探索集成点
目标:分析网站代码和数据模型,找出所有需要 Web API 集成的表
操作:
使用 Explore Agent(通过 Task 工具并设置 agent_type: "explore")分析网站代码和数据模型。Explore Agent 应回答以下问题:
2.1 发现表
让 Explore Agent 通过检查以下内容,确定所有需要集成 Web API 的 Dataverse 表:
.datamodel-manifest.json— 表及其列的列表src/**/*.{ts,tsx,js,jsx,vue,astro}— 引用了表数据、模拟数据或占位 API 调用的源代码文件- 代码中现有的
/_api/fetch 模式 - 映射到 Dataverse 表架构的 TypeScript 接口或类型
- 显示或操作 Dataverse 表数据的组件文件
- 应替换为 API 调用的模拟数据文件或硬编码数组
- 提及 API 集成的
TODO或FIXME注释
给 Explore Agent 的提示词:
“分析这个 Power Pages SPA 站点,并确定所有需要集成 Web API 的 Dataverse 表。检查
.datamodel-manifest.json中的数据模型,然后搜索源代码,查找:模拟数据数组、硬编码数据、指向/_api/的占位 fetch 调用、匹配 Dataverse 列模式的 TypeScript 接口(如发布者前缀cr*_)、有关 API 集成的 TODO/FIXME 注释,以及显示表数据的组件。对于找到的每个表,请报告:表的逻辑名称、实体集名称(复数)、引用该表的源文件、所需操作(读取/创建/更新/删除),以及src/shared/或src/services/中是否已有 API 客户端或服务。另请检查src/shared/powerPagesApi.ts是否已存在。”
**当 AI 只读模式处于活动状态(已设置 Phase 1.6 标志)时:**在上述提示词后追加以下内容:
“调用方已为表
[tables from sentinel]指定 AI-READ-ONLY 模式(primary=[primary],expand-targets=[expand-targets])。该列表中每个表所需的操作 = 只读。不要报告创建/更新/删除调用位置或模拟数据替换候选项。对于每个$expand目标,还要报告主表代码在该扩展上使用$select选择的列(这些列将成为最小字段列表)。”
2.2 识别现有集成代码
Explore Agent 还应报告:
src/shared/powerPagesApi.ts(或等效 API 客户端)是否已存在src/shared/services/或src/services/中已有服务文件的表src/types/中已有类型定义的表- 已创建的任何特定于框架的 hooks/composables
这样可以避免重复已完成的工作。
2.3 编制集成清单
根据 Explore Agent 的调查结果,编制需要集成的表的列表:
| 表 | 逻辑名称 | 实体集 | 操作 | 引用文件 | 现有服务 |
|---|---|---|---|---|---|
| Products | cr4fc_product | cr4fc_products | CRUD | ProductList.tsx、ProductCard.tsx | 无 |
| Categories | cr4fc_category | cr4fc_categories | 读取 | CategoryFilter.tsx | 无 |
输出:完整的集成清单,列出所有表、所需操作、引用文件和现有服务状态
Phase 3:审查集成计划
目标:向用户展示集成清单,并确认要集成的表
操作:
3.1 展示调查结果
向用户展示:
- 已确定需要集成 Web API 的表
- 每个表:引用该表的文件及所需操作
- 是否已有共享 API 客户端,或者是否需要创建
- 已跳过的任何表(已有服务)
3.2 确认表
🚦 Gate(计划 · integrate-webapi:3.2.confirm-tables): 最终决定哪些表需要 Web API 集成代码(客户端、类型、服务、钩子)。
触发条件: Explore agent 在阶段 3.1 中列出了候选表。 询问原因: 自动选择所有表可能会为用户从未打算通过 Web API 公开的表生成无用的 TypeScript 文件。 取消后: 无任何内容——尚未写入服务、类型或钩子文件。
启用仅 AI 读取模式时(已设置阶段 1.6 标志): 完全跳过此步骤。原样使用从 sentinel 解析出的 tables 列表——调用方已与用户确认过选择。不要发出 AskUserQuestion。
否则,使用 AskUserQuestion 进行确认:
| 问题 | 选项 |
|---|---|
| 我发现以下表需要集成 Web API:[表列表]。应集成哪些表? | 全部集成(推荐)、让我选择特定表、我需要添加更多表 |
如果用户选择特定表或添加更多表,请相应更新集成清单。
输出:用户确认的待集成表列表(或仅 AI 读取模式下由 sentinel 提供的列表)
阶段 4:实现集成
目标:使用 webapi-integration agent 为每个已确认的表创建 Web API 集成代码
操作:
4.1 为每个表调用 Agent
对于每个表,使用 Task 工具调用 ${PLUGIN_ROOT}/agents/webapi-integration.md 中的 webapi-integration agent:
Agent 提示词模板:
“为 [表显示名称] 表集成 Power Pages Web API。
- 表逻辑名称:
[logical_name]- 实体集名称:
[entity_set_name]- 所需操作:[读取/创建/更新/删除]
- 框架:[React/Vue/Angular/Astro]
- 项目根目录:[路径]
- 引用此表的源文件:[文件列表]
- 数据模型清单路径:[如果有,则填写 .datamodel-manifest.json 的路径]
创建 TypeScript 类型、CRUD 服务层和特定于框架的钩子/组合式函数。将引用源文件中的任何模拟数据或占位 API 调用替换为新服务。”
启用仅 AI 读取模式时(已设置阶段 1.6 标志): 将“所需操作:[读取/创建/更新/删除]”替换为 所需操作:仅读取,并在提示词末尾附加:
“仅 AI 读取集成。 不要生成创建、更新或删除函数。仅在服务层中搭建
list<Table>(分页)和get<Table>ById。仅创建特定于框架的读取钩子(例如,包含items、isLoading、error、refetch的use<Table>();不要创建修改钩子)。除了 AI 摘要调用方所需的内容外,不要替换模拟数据——上游技能会在此基础上添加摘要服务。如果共享的src/shared/powerPagesApi.ts客户端尚不存在,仍需创建;调用方的 AI 集成读取路径依赖此客户端。”
4.2 先处理第一个表,再并行处理其余表
必须单独处理第一个表——它会创建所有其他表所依赖的共享 powerPagesApi.ts 客户端。在第一个表处理完成且共享客户端存在后:
- 验证共享 API 客户端已在
src/shared/powerPagesApi.ts创建 - 然后使用多个
Task调用并行处理所有其余表——每个表都会创建独立文件(其自身的src/types/类型、src/shared/services/服务以及钩子/组合式函数),因此不会发生冲突
如果只有一个表,则按顺序处理即可。
4.3 验证每项集成
每个 agent 完成后(或所有并行 agent 完成后),验证输出:
- 检查是否已创建预期文件(类型、服务、钩子/组合式函数)
- 确认第一个表处理完成后,共享 API 客户端已存在
- 记录 agent 报告的任何问题
4.4 Git 提交
当 AI 只读模式处于启用状态时跳过(Phase 1.6 标志已设置)——调用方会批量提交。 打印本阶段原本会暂存的文件列表,以便调用方重现,然后继续。
否则,在所有集成都完成后,暂存并提交:
git add -A
git commit -m "Add Web API integration for [table names]"
输出:为所有已确认的表创建集成代码,完成验证,并在正常模式下提交
Phase 5:验证集成
目标:验证所有预期的集成文件都已存在、导入正确,且项目可成功构建
操作:
5.1 验证文件清单
对于每个已集成的表,确认以下文件存在:
- 类型定义,位于
src/types/(例如,src/types/product.ts) - 服务文件,位于
src/shared/services/或src/services/(例如,productService.ts) - 框架专属的 Hook/组合式函数(例如,React 的
src/shared/hooks/useProducts.ts,Vue 的src/composables/useProducts.ts)
还需验证:
src/shared/powerPagesApi.ts中的共享 API 客户端存在- 每个服务文件都引用
/_api/端点 - 每个服务文件都从共享 API 客户端导入内容
5.2 验证构建
运行项目构建,检查是否存在导入错误、类型错误或缺失的依赖项:
npm run build
如果构建失败,请先修复问题再继续。常见问题:
- 生成的文件之间缺少导入
- 服务与类型定义之间的类型不匹配
- 框架专属的编译错误
5.3 展示验证结果
用下表总结验证结果:
| 表 | 类型 | 服务 | Hook/组合式函数 | API 引用 |
|---|---|---|---|---|
| Products | src/types/product.ts | src/shared/services/productService.ts | src/shared/hooks/useProducts.ts | /_api/cr4fc_products |
| ... | ... | ... | ... | ... |
构建状态:通过 / 失败(附详情)
输出:所有集成文件均已验证,项目可成功构建
Phase 6:设置权限和设置
目标:使用 table-permissions-architect 和 webapi-settings-architect Agent 为所有已集成的表配置表权限和 Web API 站点设置
操作:
6.1 检查部署前提条件
两个 Agent 都需要 .powerpages-site 文件夹。
当 AI 只读模式处于启用状态时(Phase 1.6 标志已设置):调用方已检查 .powerpages-site 是否存在——请再次检查以作防护;如果该文件夹确实不存在,则停止并向调用方报告违反约定的情况(调用方会将此情况告知用户)。
不要发出下方的部署提示——部署决定由调用方统一负责。
否则,如果 .powerpages-site 不存在:
🚦 **Gate(计划 · integrate-webapi:6.1.deploy-first):**缺少
.powerpages-site——两个架构 Agent 都需要此文件夹。请先部署,或跳过权限设置并在不配置权限的情况下完成。**触发条件:**Phase 6.1 未找到
.powerpages-site文件夹。 **询问原因:**自动跳过会导致集成无法正常工作(没有权限支持 Web API 调用);自动部署则可能选错环境。 **取消后保留:**无——Phase 4 中的服务、类型和 Hook 无论如何都会保留在磁盘上。
使用 AskUserQuestion:
| 问题 | 选项 |
|---|---|
未找到 .powerpages-site 文件夹。配置权限和站点设置前,需要先部署一次站点。是否现在部署? | 是,现在部署(推荐),暂时跳过权限——我稍后设置 |
如果选择“是,现在部署”:先调用 /deploy-site,然后继续本阶段。
如果选择“跳过”:跳至 Phase 7,并注明仍需配置权限和站点设置。
6.2 选择权限来源
🚦 关卡(plan · integrate-webapi:6.2.permissions-source): 在上传现有权限图(路径 A)和让架构师 Agent 推导权限(路径 B)之间做出选择。此选择将决定第 6 阶段后续流程。
触发条件: 满足部署前置条件后进入第 6.2 阶段。 询问原因: 路径 A 生成的表权限可能会匹配过时或错误的权限图;路径 B 查询 Dataverse 可能需要几分钟。 取消后状态: 无——尚未写入任何权限 YAML。
启用仅 AI 读取模式时(已设置第 1.6 阶段标记): 完全跳过权限来源问题,并默认选择路径 B(让架构师 Agent 推导)——直接继续第 6.3 节。根据第 1.6 阶段的约定,此处不会发出 AskUserQuestion;此决策由调用方(/add-ai-webapi)负责,且第 6.3 节中的仅 AI 架构师提示词已包含只读要求。路径 A(上传现有权限图)是需要人工交互的流程,不适用于委托运行。
否则,使用 AskUserQuestion 工具询问用户希望如何定义权限:
问题:“您希望如何定义网站的 Web API 权限和设置?”
| 选项 | 描述 |
|---|---|
| 上传现有权限图 | 提供现有权限结构的图片(PNG/JPG)或 Mermaid 图 |
| 让架构师 Agent 推导 | 表权限架构师和 Web API 设置架构师将分析网站代码、数据模型和 Dataverse 环境,然后自动提出权限和设置建议 |
根据选择转到相应路径:
路径 A:上传现有权限图
🚦 关卡(计划 · integrate-webapi:6.2.permissions-approval): 在写入任何 Web 角色/表权限/站点设置 YAML 之前,最终确认解析后的权限计划(来自上传的图表)。此关卡在以下路径 A 流程的第 6 步触发。
触发条件: 路径 A — 图表已解析并渲染为 Mermaid 流程图。 询问原因: 错误的范围/CRUD 标志会被提交到
.powerpages-site/table-permissions/——虽然可以修复,但会让 git 历史显得杂乱。 取消后: 无任何影响——尚未写入 YAML 文件。
如果用户选择上传现有图表:
-
请用户提供权限图。支持的格式:
- 图像文件(PNG、JPG)——使用
Read工具查看图像,并从中提取 Web 角色、表权限、CRUD 标志、范围和站点设置 - Mermaid 语法——用户可以直接在聊天中粘贴 Mermaid 流程图文本
- 文本描述——按结构化列表列出 Web 角色、表权限、范围和站点设置
- 图像文件(PNG、JPG)——使用
-
将图表解析为结构化格式:
- Web 角色:按名称与
.powerpages-site/web-roles/中的现有角色匹配,以获取其 UUID - 表权限:权限名称、表逻辑名称、Web 角色 UUID、范围、CRUD 标志(read/create/write/delete/append/appendto)、父权限和关系名称(如果范围为 Parent)
- 站点设置:
Webapi/<table>/enabled和Webapi/<table>/fields——重要:fields 必须明确列出每个必需列的 LogicalName,包括聚合 OData 查询中使用的列
- Web 角色:按名称与
-
根据 Dataverse 验证列名称——即使使用用户提供的图表,也要查询 Dataverse 中每个表的列 LogicalName,并确认
Webapi/<table>/fields值中的每一列都使用准确的 Dataverse LogicalName(区分大小写)。创建文件前,修正任何不匹配项。 -
与
.powerpages-site/中的现有配置交叉核对,确定哪些权限和站点设置是新增的,哪些已存在。 -
根据解析的数据生成 Mermaid 流程图(如果用户提供的是图像或文本),供用户直观确认。
-
使用
AskUserQuestion向用户展示解析后的权限计划并征求批准:问题 选项 此权限计划看起来正确吗? 批准并创建文件(推荐)、请求修改、取消 -
直接转到第 6.4 节:创建权限和设置文件,并使用解析后的数据。
路径 B:让架构师来决定
如果用户选择让架构师来决定,请转到第 6.3 节:调用表权限 Agent。
6.3 并行调用表权限和 Web API 设置 Agent
这两个 Agent 相互独立——同时使用两个 Task 调用并行启动:
表权限 Agent
使用 Task 工具,在 ${PLUGIN_ROOT}/agents/table-permissions-architect.md 调用 table-permissions-architect Agent:
提示词(默认 — 完整 CRUD):
“分析此 Power Pages SPA 站点并提出表权限方案。以下表已在 Web API 中集成:[第 4 阶段集成的表列表]。检查现有 Web 角色和表权限。针对所有已集成的表提出完整的表权限方案。待我批准方案后,使用确定性脚本创建 Web 角色和表权限 YAML 文件。”
**提示词(启用仅限 AI 读取模式时):**在默认提示词后追加:
“仅限 AI 读取集成。 调用方是
/add-ai-webapi,这些表将由/_api/summarization/data/v1.0/汇总——此端点在语义上是读取操作,绝不会修改 Dataverse。因此:
- 仅设置
read: true。即使默认约定会包含这些权限,也不要提出create、write或delete。- 对于集合值
$expand目标(主表=[primary],展开目标=[expand-targets]),使用 Parent 范围并设置read: true,同时在父表权限上添加appendTo: true,以允许关系遍历。- 如果没有合适的 Web 角色,请将此情况反馈给调用方——
/add-ai-webapi会预先调用/create-webroles;此处不要因创建角色而阻塞。”
该 Agent 将:
- 分析站点并提出方案(附 Mermaid 图)
- 通过计划模式展示方案,供用户批准
- 获得批准后,使用
create-web-role.js创建所需的 Web 角色 - 使用
create-table-permission.js创建所有表权限文件 - 返回已创建文件的摘要
Web API 设置 Agent
使用 Task 工具,在 ${PLUGIN_ROOT}/agents/webapi-settings-architect.md 调用 webapi-settings-architect Agent:
提示词(默认 — 完整 CRUD):
“分析此 Power Pages SPA 站点并提出 Web API 站点设置。以下表已在 Web API 中集成:[第 4 阶段集成的表列表]。检查现有站点设置,并查询 Dataverse 以获取准确的列 LogicalName。提出站点设置,并使用区分大小写且经过验证的列名。待我批准方案后,使用确定性脚本创建站点设置 YAML 文件。”
**提示词(启用仅限 AI 读取模式时):**在默认提示词后追加:
“仅限 AI 读取集成。 这些表将由
/_api/summarization/data/v1.0/汇总。字段列表规则比默认 CRUD 配置更严格:
Webapi/<table>/fields必须恰好包含站点对该表的所有调用所需的列。从主表的$select/$expand开始;如果该表也用于聚合查询,则添加其分组键、聚合输入、筛选列和排序列。- 不要包含主键列。汇总端点会在 URL 路径中携带记录 ID;Microsoft 随附的案例预设设置
Webapi/incident/fields = description,title,不包含incidentid。- 对于查找列,仅包含
_\<col\>_valueOData 读取形式。只有在非 AI 代码于@odata.bind之前使用关系 Navigation Property 时,才添加它。- 仍须查询 Dataverse 以获取准确的 LogicalName(区分大小写)——大小写不匹配会导致 403。”
该 Agent 将:
- 分析站点,并查询 Dataverse 以获取准确的列 LogicalName
- 交叉验证列名(区分大小写)
- 通过计划模式展示方案,供用户批准
- 获得批准后,使用
create-site-setting.js创建所有站点设置文件 - 返回已创建文件的摘要
等待两个 Agent 均完成后,再继续执行 6.4。
6.4 创建权限和设置文件(仅限路径 A)
本节仅适用于路径 A(用户提供权限图)。 对于路径 B,架构师 Agent 会在第 6.3 节中直接创建文件。
解析用户提供的图后,使用以下确定性脚本创建 YAML 文件。请勿手动编写 YAML 文件——务必使用这些脚本,它们会自动处理 UUID 生成、字段排序、格式设置和文件命名。
6.4.1 创建 Web 角色(如有需要)
如果计划要求创建尚不存在的新 Web 角色,请先创建它们(创建表权限时需要其 UUID):
node "${PLUGIN_ROOT}/skills/create-webroles/scripts/create-web-role.js" --projectRoot "<PROJECT_ROOT>" --name "<Role Name>" [--anonymous] [--authenticated]
保存 JSON 输出({ "id": "<uuid>", "filePath": "<path>" })——创建表权限时,将 id 用作 --webRoleIds 的值。
6.4.2 创建表权限
为计划中的每项表权限执行此操作。先处理父权限,再处理子权限——创建子权限时需要父权限的 UUID,该 UUID 来自 JSON 输出。
启用仅限 AI 的读取模式时(已设置 Phase 1.6 标志): 默认仅设置 --read 标志。对于范围内的任何权限,请勿传入 --create、--write 或 --delete——AI 摘要读取不会修改数据。对于 Parent 范围的子权限,仍需传入 --parentPermissionId 和 --parentRelationshipName;对于父权限,添加 --appendto,以便 AI 端点遍历关系。
适用于 Global/Contact/Account/Self 范围:
node "${PLUGIN_ROOT}/scripts/create-table-permission.js" --projectRoot "<PROJECT_ROOT>" --permissionName "<Permission Name>" --tableName "<table_logical_name>" --webRoleIds "<uuid1,uuid2>" --scope "Global" [--read] [--create] [--write] [--delete] [--append] [--appendto]
node "${PLUGIN_ROOT}/scripts/create-table-permission.js" --projectRoot "<PROJECT_ROOT>" --permissionName "<Permission Name>" --tableName "<table_logical_name>" --webRoleIds "<uuid1,uuid2>" --scope "Contact" --contactRelationshipName "<lookup_to_contact>" [--read] [--create] [--write] [--delete] [--append] [--appendto]
node "${PLUGIN_ROOT}/scripts/create-table-permission.js" --projectRoot "<PROJECT_ROOT>" --permissionName "<Permission Name>" --tableName "<table_logical_name>" --webRoleIds "<uuid1,uuid2>" --scope "Account" --accountRelationshipName "<lookup_to_account>" [--read] [--create] [--write] [--delete] [--append] [--appendto]
node "${PLUGIN_ROOT}/scripts/create-table-permission.js" --projectRoot "<PROJECT_ROOT>" --permissionName "<Permission Name>" --tableName "<table_logical_name>" --webRoleIds "<uuid1,uuid2>" --scope "Self" [--read] [--create] [--write] [--delete] [--append] [--appendto]
适用于 Parent 范围(需要父权限 UUID 和关系名称):
node "${PLUGIN_ROOT}/scripts/create-table-permission.js" --projectRoot "<PROJECT_ROOT>" --permissionName "<Permission Name>" --tableName "<table_logical_name>" --webRoleIds "<uuid1>" --scope "Parent" --parentPermissionId "<parent-uuid>" --parentRelationshipName "<relationship_name>" [--read] [--create] [--write] [--delete] [--append] [--appendto]
每次调用都会输出 { "id": "<uuid>", "filePath": "<path>" }。为子权限的 --parentPermissionId 使用 id。
6.4.3 创建站点设置
为计划中的每项站点设置执行此操作:
启用设置(布尔值):
node "${PLUGIN_ROOT}/scripts/create-site-setting.js" --projectRoot "<PROJECT_ROOT>" --name "Webapi/<table>/enabled" --value "true" --description "Enable Web API access for <table> table" --type "boolean"
字段设置(字符串——使用图中已验证的列名):
node "${PLUGIN_ROOT}/scripts/create-site-setting.js" --projectRoot "<PROJECT_ROOT>" --name "Webapi/<table>/fields" --value "<comma-separated-validated-columns>" --description "Allowed fields for <table> Web API access"
内部错误设置(布尔值,可选,用于调试):
node "${PLUGIN_ROOT}/scripts/create-site-setting.js" --projectRoot "<PROJECT_ROOT>" --name "Webapi/error/innererror" --value "true" --description "Enable detailed error messages for debugging" --type "boolean"
重要:每项字段设置的 --value 都必须遵循 ${PLUGIN_ROOT}/references/webapi-field-allowlist.md。普通列使用准确的 LogicalName,查找读取使用 _<LogicalName>_value,查找写入使用 @odata.bind 前的准确 Navigation Property。从 2026 年 9 月 14 日起,不再支持通配符字段访问。
聚合查询:在显式字段列表中,包含 $apply 引用的每个分组键、聚合输入、筛选列和排序列。
查找列:读取时包含 _<LogicalName>_value。如果 POST/PATCH 使用 [email protected] 设置关系,则还要在字段值中包含该准确、区分大小写的 Navigation Property。
仅限 AI 的读取模式(已设置 Phase 1.6 标志):字段值规则更为严格:
- 包含针对该表的每个站点调用所需的准确列。先从主查询的
$select/$expand开始;如果该表还用于聚合查询,则添加其分组键、聚合输入、筛选列和排序列。 - 请勿包含主键。摘要端点会在 URL 路径中携带记录 ID;Microsoft 随附的案例预设将
Webapi/incident/fields设为description,title,不包含incidentid。 - 对于查找列,仅包含
_<col>_value读取形式。省略关系 Navigation Properties,因为 AI 模式不会使用@odata.bind写入。 - 明确列出 File/Image 和聚合查询所用的列,仅添加站点实际使用的列。
6.5 Git 提交
启用仅限 AI 的读取模式时(已设置 Phase 1.6 标志),请跳过此步骤——调用方会批量提交。 输出本阶段原本会暂存的文件列表,以便调用方重现,然后继续。
否则,暂存并提交权限和设置文件:
git add -A
git commit -m "Add table permissions and Web API site settings for [table names]"
输出:已创建并验证表权限和站点设置;(正常模式下)已提交
6.6 最终站点完整性检查
完成所有集成源代码更改、权限/设置工作和构建验证后,运行:
node "${PLUGIN_ROOT}/scripts/validate-site-integrity.js" --projectRoot "<PROJECT_ROOT>"
在汇报完成情况或请求部署前,修复所有阻塞性错误。检查并以扩展内容报告两个方向的审查发现。之后每次修改源代码,都要重新运行此检查。
阶段 7:审查与部署
目标:汇总已完成的所有工作,并提供部署选项
操作:
7.1 记录技能使用情况
参考:
${PLUGIN_ROOT}/references/skill-tracking-reference.md
按照该参考中的技能跟踪说明,记录此技能的使用情况。使用 --skillName "IntegrateWebApi"。
7.2 提交摘要
汇总已完成的所有工作:
| 步骤 | 状态 | 详情 |
|---|---|---|
| API 客户端 | 已创建/已存在 | src/shared/powerPagesApi.ts |
| 类型 | 已创建 | src/types/product.ts、src/types/category.ts |
| 服务 | 已创建 | src/shared/services/productService.ts 等 |
| Hook | 已创建 | src/shared/hooks/useProducts.ts 等 |
| 已更新的组件 | X 个文件 | 已将模拟数据替换为 API 调用 |
| 表权限 | 已创建 | X 个权限文件 |
| 站点设置 | 已创建 | X 个设置文件 |
7.3 询问是否部署
🚦 关卡(计划 · integrate-webapi:7.3.deploy): 集成后的部署提示 — 部署权限和站点设置之前,Web API 调用将无法正常工作。
触发条件: 所有集成代码和权限 YAML 均已提交。 询问原因: 自动部署会使用 PAC CLI 当前指向的任意环境。 取消后: 无影响 — 集成产物保留在磁盘上;不会触发部署。
AI 只读模式处于启用状态时跳过(已设置阶段 1.6 标记)— 调用方负责在编排结束时做出唯一的部署决定。返回阶段 7.2 的摘要并停止。
否则,使用 AskUserQuestion:
| 问题 | 选项 |
|---|---|
| Web API 集成和权限已准备就绪。要让一切正式生效,需要部署站点。现在要部署吗? | 是,现在部署(推荐);不,我稍后部署 |
如果选择“是,现在部署”:调用 /deploy-site 技能部署站点。
如果选择“不,我稍后部署”:确认并提醒:
“没问题!准备就绪后,记得使用
/deploy-site部署站点。在部署包含新权限的站点之前,Web API 调用将无法正常工作。”
7.4 部署后说明
AI 只读模式处于启用状态时跳过 — 调用方会提供自己的部署后指南,其中涵盖 AI 特定注意事项(治理层级、运行时版本、Bing 依赖)。
否则,在部署之后(或跳过部署时)提醒用户:
- 测试 API:打开已部署的站点,并在浏览器的 Network(网络)标签页中验证 Web API 调用是否正常
- 检查权限:如果任何 API 调用返回 403,请确认表权限和站点设置正确。最常见的原因是请求中的某个列未包含在
Webapi/<table>/fields中,或与元数据返回的 Dataverse LogicalName 大小写不完全一致。对于聚合 OData($apply、aggregate、grouped totals),请确认已明确列出所有分组键、聚合输入、筛选列和排序列。 - 在生产环境中禁用 innererror:如果为调试启用了
Webapi/error/innererror,上线前请将其禁用 - Web 角色:用户必须分配有相应的 Web 角色,才能访问受保护的 API
输出:已提交摘要;部署已完成或延期(普通模式),或已返回给调用方(AI 只读模式)。
重要说明
所有阶段通用
- 使用 TaskCreate/TaskUpdate 在每个阶段跟踪进度
- 在关键决策点征求用户确认(见下方列表)
- 先顺序处理第一个表,再并行处理其余表——第一个表会创建共享 API 客户端;之后可以并行处理其余表,因为每个表都会创建独立文件
- 在里程碑处提交——集成代码完成后,以及权限文件完成后
关键决策点(等待用户确认)
- 第 2 阶段后:确认要集成哪些表
- 第 3 阶段后:批准集成计划
- 第 6.1 阶段:如果缺少
.powerpages-site,选择立即部署还是跳过权限设置 - 第 6.2 阶段:选择权限来源(上传关系图,或让架构师进行分析)
- 第 6.3 阶段:批准表权限计划和 Web API 站点设置计划(路径 B 中两个 Agent 并行运行,每个 Agent 都会各自提交计划供审批)
- 第 7.2 阶段:选择立即部署还是稍后部署
进度跟踪
开始第 1 阶段前,使用 TaskCreate 创建包含所有阶段的任务列表:
| 任务主题 | activeForm | 说明 |
|---|---|---|
| 验证站点是否存在 | 正在验证站点前置条件 | 定位项目根目录,检测框架,检查数据模型和部署状态 |
| 探索集成点 | 正在分析代码中的集成点 | 使用 Explore Agent 发现表和现有服务,并编制集成清单 |
| 审查集成计划 | 正在与用户审查集成计划 | 展示调查结果,并确认要集成哪些表 |
| 实现集成 | 正在实现 Web API 集成 | 为第一个表调用 webapi-integration Agent(创建共享客户端),然后并行处理其余表,验证输出并执行 git commit |
| 验证集成 | 正在验证集成 | 验证所有预期文件是否存在,检查导入和 API 引用,并运行项目构建 |
| 设置权限和站点设置 | 正在配置权限和站点设置 | 选择权限来源(上传关系图或由架构师分析),并行调用 table-permissions-architect 和 webapi-settings-architect Agent,使用经过大小写验证的列名称创建 YAML 文件,并执行 git commit |
| 审查并部署 | 正在审查摘要并部署 | 展示摘要,询问是否部署,并提供部署后指导 |
通过 TaskUpdate,在开始每项任务时将其标记为 in_progress,完成后标记为 completed。这样用户可以了解进度,并确保工作流按确定的顺序执行。
从第 1 阶段开始:验证站点是否存在