构建 Dataverse / Dynamics 365 集成
指南位于 docs/integrations-dynamics.md:请先阅读;此技能是工作顺序。将其规划为一个阶段(waves-and-agents.md);一旦合约(表、连接器接口、设置名称)编写完成,引擎、连接器、模拟和管理界面可以作为并行代理处理。
1. 询问所有者(一条消息,编号,每条带有建议)
- 什么流程,哪个方向: 哪些产品记录映射到哪些 Dataverse 行(联系人、潜在客户、时间线上的备注、Customer Insights - Journeys 事件表、自定义触发器),以及是否读回任何内容(静态营销列表、退出选择)。默认:单向,从产品到 Dynamics,加上如果被要求则读取静态列表。
- 登录模型: 推荐产品自己的多租户应用,带有管理员同意和一个具有自定义最低权限角色的应用程序用户;保留每个客户的应用程序注册(首选证书)作为备选方案。询问服务是否可以使用托管标识作为联合凭证(无密钥)或是否需要证书。
- 哪个 Entra 租户托管多租户应用,谁注册它,谁完成发布者验证。(由所有者完成;你准备步骤。)
- 匹配规则: 联系人通过电子邮件匹配(所有三个列,活跃的优先);除非映射为“替换”,否则从不覆盖非空的 CRM 字段;仅在唯一精确名称上链接账户;从不创建账户。确认或调整。
- 同意: 在同步任何内容之前,客户确认其隐私声明;是否在同意问题上设闸;除非产品是给出同意的地方,并且所有者决定写入联系人接触点同意记录,否则从不写入营销同意。
- 旅程: 是否需要自定义触发器,用于哪些信号(已注册、已取消、已签到、已捕获线索等),或者同步记录上的现成业务触发器是否足够?
- 用于测试的真实环境: 哪个(首选专用沙盒/试用版),范围(记录上限,一个测试触发器),以及确认未经单独许可不得进行任何架构、解决方案、安全角色或应用程序注册的更改。
将决定记录在 STATE.md 中,将阶段记录在 ROADMAP.md 中。
2. 合约与数据模型
- 表:连接(每个工作区/租户和环境:URL、租户 ID、登录类型、保管库密钥名称、提示和过期时间、状态、暂停至、探测结果 JSON、设置/映射 JSON、隐私确认人/时间)、同步项(每个记录一行:类型、源 ID、CRM 表和 ID、版本、声明版本、尝试次数、下次尝试、最后错误、最后信号)、每个事件/范围链接(包含、链接的 CRM 事件、活动、同意问题、选定的赞助商或来源)、反向游标、同步日志(30 天)。
- 连接器接口(CRM 中立):
Probe、Write(rows) -> results (Synced | Retry | Throttled(RetryAfter) | Refused)、Lookup(事件、活动、列表)、RecordLink、默认映射、自有列。对于 CRM 给出的答案绝不抛出异常。 - 设置:登录基础 URL(笔记本电脑上的模拟器)、平台客户端 ID、保管库密钥名称。将它们添加到设置合约中(contracts.md)。
3. 按此顺序构建
- 无需网络连接的领域规则: 环境 URL 验证(包括主权云在内的 Dataverse 主机、https、无路径)、Web API 根路径(
/api/data/v9.2/)、令牌范围(https://<ENV>/.default)、OData 字面量转义、错误解析(代码、消息)、$batch写入器和读取器(含变更集读取)、确定性 ID(工作区、主机、类型、源 ID 的 UUID v5)、记录深度链接(main.aspx?appid=...&pagetype=entityrecord&etn=...&id=...)。单元测试。 - 令牌: 客户端凭据(密钥、使用
x5t#S256的证书断言、平台应用、仅开发环境中的开发者az令牌)、按哈希缓存直到过期前 5 分钟、遇到 401 时忘记并重试一次、Entra 的第一行错误信息显示到 UI。 - 探测:
WhoAmI、RetrieveVersion()、实体集、带有可写性和最大长度的属性、多对一导航属性名称、就绪的自定义触发器及其参数;仅当其表存在时才提供模式。 - 写入: 联系人匹配然后 upsert,启用重复检测,唯一时链接账户,通过
PATCH写入确定性 ID 的备注和自有记录,仅创建潜在客户(If-None-Match: *),使用If-Match: *进行更新(或在有人编辑相同字段时使用 ETag),statecode 与 statuscode,自定义触发器作为未绑定操作,并填写所有属性。 - 引擎: 钩子加上扫描,跨副本声明(一个人的行序列化,依赖优先)、带有死信的重试计划,429 暂停连接直到
Retry-After、每个连接的最大并发数,$batch中的反向填充(独立请求、Prefer: odata.continue-on-error、小批量)、断开连接。 - 每个配置语言的管理界面: 连接向导(环境、使用平台应用的管理员同意链接登录、测试显示找到的模式、同步内容、根据真实列验证的映射、哪些事件/范围、隐私确认)、连接页面(状态、日志、重试失败项、替换凭据、证书过期)、每条记录行带有“在 Dynamics 中打开”和“再次同步”以及“如何连接”帮助抽屉,列出精确的角色权限和 Power Platform 管理中心步骤。
- 告警: 当 CRM 在续订后拒绝登录时,通过电子邮件通知工作区管理员一次。
4. 测试
- 先使用模拟环境: 将
templates/project/tests/standins/dataverse.mjs及其测试复制到tests/standins/,用你的表扩展它(模式见 testing.md):令牌端点、元数据、支持 upsert 和条件头的 CRUD、未绑定操作、$batch、类似 Dataverse 的验证、节流、失败、令牌过期和状态的控制。用于单元测试的假 HTTP 处理程序孪生。 - 来自指南列表的单元和数据库测试。在桌面和手机宽度、浅色和深色模式下,以两种语言对向导和连接页面进行浏览器检查。
- 报告为**“仅针对模拟环境验证”**,直到真实环境运行过。
- 仅在所有者为该环境和范围明确许可后使用真实沙盒: 通过
az account get-access-token --resource https://<ENV>.crm4.dynamics.com --subscription <SUBSCRIPTION_ID>获取令牌(从不切换默认账户或pac配置文件),标记记录带有运行 ID 和硬上限,记录每个创建的 ID,按指南顺序检查,按记录 ID 清理,之后计数为零,并提供所创建和删除内容的简短报告。
5. 所有者检查清单(提供给他们,不要替他们做)
- 注册多租户应用(或决定不注册),添加其凭据(联合托管标识或证书)并将任何密钥放入约定的名称下的保管库;设置客户端 ID 设置。
- 发布者验证。
- 将最低权限角色打包为适用于客户的托管解决方案(可选但推荐)。
- 对于每个客户:管理员同意链接、具有该角色的应用程序用户、环境 URL 和租户 ID 输入到产品中,然后测试。
6. 记录
STATE.md:已构建的内容、模式、在何处运行的内容以及未经验证的表(真实环境、导航属性名称、可选模块中必需的列、重复检测的真实响应、带变更集的 $batch、真实的自定义触发器、节流、管理员同意以及客户租户中的证书)。当它们得到验证时,更新指南中的 (confirm) 标记。每个语言版本中每个发布的新内容条目。
规则
- 未经所有者明确许可执行该确切操作,不得进行真实环境调用、架构/解决方案/角色/应用注册/同意更改或删除你未创建的记录。
- 不将秘密写入代码、日志、聊天、提交或报告中;仅使用保管库。记录主机、状态、错误代码。
- 在共享的任何内容中使用占位符:
<ENV>.crm4.dynamics.com、<TENANT_ID>、<CLIENT_ID>。 - 不添加任何 AI 归因。