mcpField
A
arch-cross-service-integration

arch-cross-service-integration

github.com/duc01226开发1247 次安装1 周前更新
代码仓库

关于 arch-cross-service-integration

用于设计和实现服务间通信与数据同步的仓库技能。它帮助梳理服务边界,优先采用实体事件总线,并提供实现、冲突处理、测试和排查清单。

主要功能

  1. 01规划服务归属与边界
  2. 02实体事件总线与 API 模式
  3. 03全量和增量同步
  4. 04依赖等待与消息排序处理
  5. 05集成测试与故障排查

适用场景

  1. 01设计服务间通信
  2. 02同步由其他服务拥有的数据
  3. 03排查延迟或不一致的消息

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/duc01226/easyplatform --skill arch-cross-service-integration

安装后在 Claude Code 中输入/arch-cross-service-integration确认已加载。

详细介绍

Codex 兼容性说明:

  • 在 Codex 中使用 $skill-name 调用仓库技能;此镜像副本会改写旧版 Claude /skill-name 引用。
  • 任务跟踪要求:在执行任何工作流或技能步骤之前,先为所有步骤创建/更新任务跟踪,并随着进度变化保持同步。
  • 用户问题提示意味着要在 Codex 中直接向用户提问。
  • 忽略出现的 Claude 专属模式切换说明。
  • 严格执行约定:用户明确调用技能时,必须按原样执行该技能协议。
  • 子代理授权:如果技能由用户调用或由 AI 检测到,且其协议要求使用子代理,则该技能的激活即授权为该任务使用所需的 spawn_agent 子代理。
  • 除非用户事先明确批准偏离,否则不得跳过、重排或合并协议步骤。
  • 对于工作流技能,须明确执行每个列出的子技能步骤,并逐步提供证据。
  • 如果此环境无法执行某个必需步骤/工具,请停止并先询问用户,再进行调整。

Codex 项目参考资料加载(无钩子)

Codex 不会通过基于 Claude 钩子的方式自动注入文档。 在编码、规划、调试、测试或审查时,请按以下路径明确打开项目文档。

始终阅读:

  • docs/project-config.json(项目专属路径、命令、模块及工作流/测试设置)
  • docs/project-reference/docs-index-reference.md(指向完整 docs/project-reference/* 目录的索引)
  • docs/project-reference/lessons.md(始终适用的守则和反模式)

按情况阅读的文档:

  • 后端/CQRS/API/领域/实体变更:backend-patterns-reference.md、domain-entities-reference.md、project-structure-reference.md
  • 前端/UI/样式/设计系统:frontend-patterns-reference.md、scss-styling-guide.md、design-system/README.md
  • 规格/测试用例规划或 TC 映射:feature-docs-reference.md
  • 集成测试实现/审查:integration-test-reference.md
  • E2E 测试实现/审查:e2e-test-reference.md
  • 代码审查/审计工作:code-review-rules.md,并根据变更文件阅读上述相关领域文档

不要不加区分地阅读所有文档。从 docs-index-reference.md 开始,然后只打开与任务相关的文件。

快速摘要

**目标:**设计并实现跨服务通信、数据同步和服务边界模式。

工作流:

  1. 预检 — 确定源服务/目标服务、数据所有权以及同步或异步方式
  2. 选择模式 — 实体事件总线(推荐)、直接 API,绝不共享数据库
  3. 实现 — 生产者 + 消费者,并处理依赖等待和竞态条件
  4. 测试 — 验证创建/更新/删除流程、乱序消息和强制同步

关键规则:

  • 通过消息总线或服务 API 读取其他服务的数据;绝不直接访问其数据库——原因:直接访问数据库会造成服务耦合并破坏数据所有权
  • 使用 LastMessageSyncDate 解决冲突(仅在新数据较新时更新)
  • 消费者必须使用 TryWaitUntilAsync 等待依赖项
  • 在共享项目中定义消息(搜索:共享消息定义、总线消息类)

保持怀疑,运用批判性思维和顺序思维。每项说法都需要可追溯的依据和置信度百分比(Idea 应高于 80%)。

强制重要注意事项 制定待办任务,阅读以下项目专属参考文档:

  • backend-patterns-reference.md — 后端 CQRS、实体事件总线和消息总线模式

如果找不到该文件,请搜索:跨服务消息定义、实体事件生产者、消息总线消费者。

跨服务集成工作流

何时使用此技能

  • 设计服务间通信
  • 实现数据同步
  • 分析服务边界
  • 排查跨服务问题

预检清单

  • 确定源服务和目标服务
  • 确定数据所有权
  • 选择通信模式(同步还是异步)
  • 梳理数据转换要求

服务边界

注意: 搜索 project-structure-reference.md 或项目的服务目录,查找平台的服务映射、数据所有权矩阵和共享基础设施组件。

通信模式

模式 1:实体事件总线(推荐)

适用情况:源服务拥有数据,目标服务需要副本。

Source Service                    Target Service
┌────────────┐                   ┌────────────┐
│  Employee  │──── Create ────▶ │ Repository │
│ Repository │                   └────────────┘
└────────────┘                          │
      │                                 │
      │ Auto-raise                      │
      ▼                                 ▼
┌────────────┐                   ┌────────────┐
│  Producer  │── MsgBus  ────▶ │  Consumer  │
└────────────┘                   └────────────┘

⚠️ 务必阅读: CLAUDE.md 中有关实体事件总线生产者和消息总线消费者的实现模式。

模式 2:直接 API 调用

适用情况:需要实时数据,且不需要本地副本。

// In Service A, calling Service B API
public class ServiceBApiClient
{
    private readonly HttpClient _client;

    public async Task<UserDto?> GetUserAsync(string userId)
    {
        var response = await _client.GetAsync($"/api/User/{userId}");
        if (!response.IsSuccessStatusCode) return null;
        return await response.Content.ReadFromJsonAsync<UserDto>();
    }
}

注意事项:

  • 添加熔断器以提高韧性
  • 尽可能缓存响应
  • 处理服务不可用的情况
模式 3:共享数据库视图(反模式!)

:x: 切勿使用:这会违反服务边界

// WRONG - Direct cross-service database access
var accountsData = await accountsDbContext.Users.ToListAsync();

数据所有权矩阵

注意: 搜索 project-structure-reference.md 或项目文档,查找实体所有权矩阵。每个实体应且只能由一个服务拥有;消费者通过消息总线接收同步副本。

同步模式

全量同步(初始同步/恢复)
// For initial data population or recovery
public class FullSyncJob : BackgroundJobExecutor // project background job base (see docs/project-reference/backend-patterns-reference.md)
{
    public override async Task ProcessAsync(object? param)
    {
        // Fetch all from source
        var allEmployees = await sourceApi.GetAllAsync();

        // Upsert to local
        foreach (var batch in allEmployees.Batch(100))
        {
            await localRepo.CreateOrUpdateManyAsync(
                batch.Select(MapToLocal),
                dismissSendEvent: true);
        }
    }
}
增量同步(事件驱动)
// Normal operation via message bus
internal sealed class EmployeeSyncConsumer : MessageBusConsumer<EmployeeEventBusMessage> // project message bus base (see docs/project-reference/backend-patterns-reference.md)
{
    public override async Task HandleLogicAsync(EmployeeEventBusMessage message, string routingKey)
    {
        // Check if newer than current (race condition prevention)
        if (existing?.LastMessageSyncDate > message.CreatedUtcDate)
            return;

        // Apply change
        await ApplyChange(message);
    }
}
冲突解决

使用 LastMessageSyncDate 排序——仅在消息较新时更新。完整实现请参阅 CLAUDE.md 中的消息总线消费者模式。

集成清单

集成前
  • 明确数据所有权
  • 记录需要同步的字段
  • 为缺失的依赖项制定计划
  • 定义冲突解决策略
实现
  • 在共享项目中定义消息
  • 生产者筛选适当的事件
  • 消费者等待依赖项就绪
  • 实现竞争条件处理
  • 处理软删除
测试
  • 创建事件正常流转
  • 更新事件正常流转
  • 删除事件正常流转
  • 处理乱序消息
  • 处理缺失的依赖项
  • 强制同步正常工作

故障排查

消息未到达
# Check message broker queues (search for: queue management commands)

# Check producer is publishing
grep -r "HandleWhen" --include="*Producer.cs" -A 5

# Check consumer is registered
grep -r "AddConsumer" --include="*.cs"
数据不匹配
# Compare source and target counts
# In source service DB
SELECT COUNT(*) FROM Employees WHERE IsActive = 1;

# In target service DB
SELECT COUNT(*) FROM SyncedEmployees;
消息卡住
// Check for waiting dependencies
Logger.LogWarning("Waiting for Company {CompanyId}", companyId);

// Force reprocess
await messageBus.PublishAsync(message.With(m => m.IsForceSync = true));

应避免的反模式

:x: 直接访问数据库

// WRONG
await otherServiceDbContext.Table.ToListAsync();

:x: 在事务中进行跨服务同步调用

// WRONG
using var transaction = await db.BeginTransactionAsync();
await externalService.NotifyAsync();  // If fails, transaction stuck
await transaction.CommitAsync();

:x: 不等待依赖项

// WRONG - FK violation if company not synced
await repo.CreateAsync(employee);  // Employee.CompanyId references Company

// CORRECT
await Util.TaskRunner.TryWaitUntilAsync(() => companyRepo.AnyAsync(...));

:x: 忽略消息顺序

// WRONG - older message overwrites newer
await repo.UpdateAsync(entity);

// CORRECT - check timestamp
if (existing.LastMessageSyncDate <= message.CreatedUtcDate)

验证清单

  • 明确定义数据所有权
  • 使用消息总线模式(而非直接访问数据库)
  • 消费者等待依赖项就绪
  • 使用时间戳处理竞争条件
  • 正确同步软删除
  • 提供强制同步机制
  • 设置监控/告警

相关内容

  • arch-security-review
  • api-design

[IMPORTANT] 使用任务跟踪将所有工作拆分为小任务,并在开始前完成——包括为每个待读取的文件创建任务。这样可以避免因文件过长而丢失上下文。对于简单任务,AI 务必询问用户是否跳过。

  • docs/project-reference/domain-entities-reference.md — 领域实体目录、关系、跨服务同步(任务涉及业务实体/模型时阅读)(相关时直接阅读;不要依赖钩子注入的对话文本)

后续步骤

强制要求,务必注意——不得例外:完成此技能后,必须通过直接提问向用户提供以下选项。即使任务看起来“简单”或“显而易见”,也不得跳过——由用户决定:

  • "$plan (Recommended)" — 根据跨服务集成设计创建实施计划
  • "$architecture-design" — 如果更广泛的架构问题仍需决策
  • "Skip, continue manually" — 由用户决定
始终提供的委员会升级选项(第二次提示)

在上方现有的 ## Next Steps 提示词处理完毕后,单独提出第二个、独立的直接用户问题(不要合并到第一个问题中):

  • “跳过 council — 继续进行集成设计(推荐)” — 按设计继续处理消息契约/消费者拓扑。推荐的默认选项。
  • “升级至 $llm-council” — 运行由 11 个子 Agent 组成的 council(5 位顾问 + 5 位评审员 + 1 位主席)。最适用于以下情况:集成引入了由 >=3 个服务消费的新消息契约、需要在同步 API 与异步事件之间为热路径做选择,或需要确定采用 saga/outbox/orchestration 模式。消费者部署后,跨服务契约很难撤销。更省力的替代方案:$why-review、$plan-validate(如果尚未运行,请先运行这些)。

防止 AI 出错 — 每项任务都应避免以下失败模式:

删除前检查下游引用。 删除组件会导致文档和代码连锁过时。移除前,先梳理所有引用该组件的文件。 根据实际代码核实 AI 生成的内容。 AI 会臆造 API、类名和方法签名。记录或引用前,务必用 grep 确认它们确实存在。 编辑后追踪完整的依赖链。 修改定义时,可能会漏掉由它派生的下游变量和消费者。务必追踪完整的依赖链。 验证正确性时追踪所有代码路径。 确认代码存在不等于确认代码会执行。务必追踪提前退出、错误分支和条件跳过,而不只是正常路径。 调试时,修复前先问“这是谁的职责?”。 追踪问题是出在调用方(数据错误)还是被调用方(处理不当)。在负有责任的层级修复,切勿只修补症状出现的位置。 假设现有值是有意设置的 — 修改前先问原因。 修改任何常量、限制、标志或模式前:先阅读注释、检查 git blame,并查看周边代码。 核实所有受影响的输出,而不只是第一个。 涉及多个技术栈的更改需要核实每个输出。一个检查通过不代表所有检查都通过。 整体优先的调试 — 抵制只关注最近线索的陷阱。 调查任何故障时,先列出所有前置条件(配置、环境变量、数据库名称、端点、DI 注册、数据前置条件),再逐一根据证据核实,然后才能提出任何代码层面的假设。 精确修改 — 使用 diff 检验。 修复 Bug 时,每个更改的行都必须能直接追溯到该 Bug。不要顺手重设样式或改进相邻代码。处理增强任务时,既要实现改进,也要明确说明。 编码前明确歧义 — 不要默默做选择。 如果请求有多种解释,请列出每种解释及其工作量估算并询问。切勿默认采用全记录、基于文件或更复杂的路径。

批判性思维 — 运用批判性思维和顺序思维。每个结论都必须有可追溯的证据,置信度 >80% 才能采取行动。 反幻觉: 切勿把猜测当作事实——每个结论都要引用来源,坦诚承认不确定性,自查输出中的错误,独立交叉验证,并对自己的信心保持怀疑——没有证据的确定性是一切幻觉的根源。

基于证据的推理 — 禁止推测。每个结论都必须有证据。

  1. 每个结论都要引用 file:line、grep 结果或框架文档
  2. 声明置信度:>80% 可直接行动,60-80% 先核实,<60% 不要推荐
  3. 架构更改必须进行跨服务验证
  4. “证据不足”是有效且符合预期的输出

满足以下条件前,不得继续: - [ ] 证据文件路径(file:line) - [ ] 已执行 grep 搜索 - [ ] 找到 3+ 个类似模式 - [ ] 已声明置信度

没有证据时禁止使用: “显而易见”、“我认为”、“应该”、“可能”、“这是因为” 如果信息不完整 → 输出:"证据不足。已核实:[...]。未核实:[...]。"

  • 强制重要务必注意 每项声明都要引用 file:line 证据。置信度 >80% 才能采取行动,<60% = 不得推荐。

务必注意 运用批判性思维——每项声明都需要可追溯的证据,置信度 >80% 才能采取行动。防止幻觉:绝不要把猜测说成事实。

务必注意 应用 AI 错误预防措施——先从整体入手进行调试,在负有责任的层级修复问题,在编码前明确指出歧义,压缩上下文后重新阅读文件。

结束提醒

  • 强制重要务必注意 开始前使用任务跟踪将工作拆分成小型待办任务
  • 强制重要务必注意 创建新代码前,在代码库中搜索 3 个或更多相似模式
  • 强制重要务必注意 每项声明都要引用 file:line 证据(置信度 >80% 才能采取行动)
  • 强制重要务必注意 添加最终审核待办任务,以验证工作质量 强制重要务必注意 开始前阅读以下文件:

[TASK-PLANNING] 采取行动前,分析任务范围,并使用任务跟踪系统地将任务拆分成小型待办任务和子任务。

无钩子提示词协议镜像(自动同步)

来源:.claude/hooks/lib/prompt-injections.cjs + .claude/.ck.json

[WORKFLOW-EXECUTION-PROTOCOL] [BLOCKING] 工作流执行协议 — 强制重要务必关键。无论何种原因都不得跳过。

通用可移植性边界: 可复用技能和协议文本应保持项目中立;应从 docs/project-config.json 和 docs/project-reference/ 中查找项目专属约定。应用共享 AI-SDD,依据 shared/sdd-artifact-contract.md。阅读 docs/project-config.json 和 docs/project-reference/docs-index-reference.md,然后打开其中列出的项目参考文档。只要具备此共享上下文和本地文档,任何受支持的 AI 工具都可以执行。

  1. 检测: 将提示词与工作流目录进行匹配
  2. 分析: 找出最匹配的工作流,并评估自定义步骤组合是否更合适
  3. 询问(必需格式): 直接向用户提问,使用以下结构;除非用户明确调用了某个工作流/技能,且本地协议将明确调用视为确认:
    • 问题:"你想启用哪个工作流?"
    • 选项 1:"启用 [最匹配的工作流](推荐)"
    • 选项 2:"启用自定义工作流:[步骤1 → 步骤2 → ...]"(附上一句话说明理由)
  4. 启用(确认后): 标准工作流调用 $workflow-start <workflowId>;自定义步骤则手动按顺序执行
  5. 创建任务: 使用任务跟踪系统为工作流的所有步骤创建任务
  6. 执行: 按顺序执行每个步骤 [CRITICAL-THINKING-MINDSET] 运用批判性思维和顺序思维。每项声明都需要可追溯的证据,置信度 >80% 才能采取行动。 防止幻觉原则: 绝不要把猜测说成事实——为每项声明引用来源,坦诚承认不确定性,自行检查输出中的错误,独立交叉验证,对自己的判断保持审慎——确信却没有证据,是一切幻觉的根源。 AI 注意力原则(首因-近因效应): 在较长提示词/协议的开头和结尾都列出最关键的 3 条规则,以便在较长的上下文窗口中仍能遵循指令。 目标驱动执行: 先定义成功标准,循环执行直到验证通过,只有在可观察的检查全部通过后才停止。 测试验证意图: 测试必须保护业务规则/不变量,并在受保护的意图被破坏时失败,而不应只复现当前行为。

[LESSON-LEARNED-REMINDER] [BLOCKING] 任务规划与持续改进 — 必须遵守。请勿跳过。

开始前将工作拆分为小任务(任务跟踪)。添加最后一项任务:“分析 AI 错误与经验教训”。

提取经验教训——只分析根本原因,不要只修复症状:

  1. 指明失败模式(推理或假设错误),而不是症状——“假设 API 存在,却没有阅读源代码”,而不是“使用了错误的枚举值”。
  2. 通用性测试:此失败模式是否适用于 ≥3 种情境或代码库?如果不适用,就再抽象一个层次。
  3. 将其写成普遍规则——去掉特定于项目的名称、路径和类。确保规则适用于任何代码库。
  4. 合并:多个错误若具有相同的失败模式,则合并为一条经验教训。
  5. 复发检查:“如果没有此提醒,这种情况会在未来的会话中再次发生吗?”——不会 → 跳过 $learn。
  6. 自动修复检查:“$code-review/$code-simplifier/$security/$lint 能否发现此问题?”——能 → 改进审查技能。
  7. 两项检查均通过 → 请用户运行 $learn。 [TASK-PLANNING] [MANDATORY] 执行任何工作流或技能步骤之前,先为所有计划步骤创建或更新任务跟踪,然后在每个步骤开始和完成时保持任务跟踪同步。

评论

支持 Markdown