v1.0.1 to v1.1.0

16 added, 1 removed. Audit A to A.

---
name: ddd-domain-interactions
description: "Design collaboration mechanisms between building blocks: domain events, domain services, repository interfaces, and factories. Use when designing domain services, repositories, domain events, or factories."
risk: safe
source: self
tags: "[ddd, tactical, events, services, repositories]"
date_added: "2026-05-08"
slug: ddd-domain-interactions
- version: 1.0.1
+ version: 1.1.0
displayName: ddd-domain-interactions
---
# DDD Domain Interactions
> English version: [English](SKILL.en.md)
## 使用时机
- 聚合边界已设计完毕,需要定义聚合之间、聚合与外部之间的协作机制。
- 需要回答"聚合如何通信、谁编排跨聚合流程、持久化契约是什么"。
- 作为战术建模的最后一步,补全所有"连接组织"。
## 输入要求
- **必需**:聚合目录与不变量表(来自 `ddd-aggregates`)、事件候选清单(来自 `ddd-discover`)。
- **可选**:上下文映射与契约信息(来自 `ddd-context-map`)、上下文目录与词汇表(来自 `ddd-contexts`,用于区分领域事件与集成事件的边界)。
## 流程
1. **事件规范化**:统一事件命名规则(过去时、业务可读、无技术词);为每个事件定义触发条件、源聚合、关键字段、排序要求。
2. **区分范围**:区分领域事件(上下文内)与集成事件(跨上下文/对外发布)。
3. **可靠性策略**:为每个事件定义幂等键、重放策略、去重窗口、死信处理。
4. **领域服务**:识别不属于任何单一聚合但承载领域逻辑的操作,定义为领域服务——明确输入、输出、使用的聚合与事件。
5. **仓储接口**:为每个聚合定义仓储的语义接口(加载、持久化、查询)——仅定义契约,不涉及实现。
6. **工厂**:识别复杂的聚合创建逻辑,定义工厂方法——明确创建条件、验证规则与初始状态。
7. **订阅者与副作用**:明确每个事件的消费者、触发的动作、补偿策略、监控指标。
## 输出
| 工件 | 结构要求 |
| :------------- | :------------------------------------------------------------------- |
| 领域事件目录 | 表格:事件名、源聚合、触发条件、关键字段、范围(Domain/Integration) |
| 集成事件契约 | 表格:事件名、发布者、消费者、契约 Owner、版本策略、兼容窗口 |
| 幂等与重放策略 | 表格:事件、幂等键、去重窗口、重放规则、异常处理 |
| 领域服务定义 | 表格:服务名、职责、输入、输出、依赖的聚合/事件、不应包含的逻辑 |
| 仓储接口清单 | 表格:聚合、方法签名(语义)、语义说明、查询边界 |
| 工厂清单 | 表格:工厂名/方法、创建目标、创建条件、验证规则、初始状态 |
| 订阅者与副作用 | 表格:事件、订阅者、触发动作、补偿策略、监控指标 |
## 校验清单
- [ ] 所有事件命名使用过去时,无技术词污染
- [ ] 跨上下文发布的事件有版本策略与兼容窗口
- [ ] 关键事件提供幂等键与重放策略
- [ ] 领域服务不包含本应属于聚合的业务逻辑(避免贫血模型)
- [ ] 仓储接口仅定义语义契约,不包含实现细节(SQL、ORM)
- [ ] 每个复杂创建逻辑都有对应工厂(不在应用层裸 new)
## 回溯触发
- 事件需携带另一聚合的私有数据(无法设计干净的 event schema) → 回溯至 `ddd-aggregates`(聚合边界需调整以保证事件自包含)。
+
+ ## 失败出口
+
+ - **缺聚合目录或事件候选清单**:停下并列出缺失工件(及其来源技能 `ddd-aggregates` / `ddd-discover`),请用户先补跑上游或直接粘贴等价材料。禁止凭空补造聚合与不变量——后续所有仓储接口与事件契约都会失去验收依据。
+ - **上游聚合边界存疑**(事件无法自包含):按回溯触发回退,但必须输出触发回溯的具体事件与缺失字段清单,而不是笼统说"建模有问题"。
+ - **输入与既定上下文冲突**(如事件命名规则与词汇表不一致):以词汇表为准并在产出中标注冲突项,交用户裁定。
+
+ ## 错法 → 改法
+
+ | 错法 | 改法 |
+ | :--- | :--- |
+ | 把另一聚合的字段塞进事件(如 BookingConfirmed 携带 RoomSchedule 排期详情) | 事件只含源聚合自身标识与关键字段;消费方经 ID 回查或订阅读上下文(见回溯触发) |
+ | 领域服务做全套 CRUD 并直接持久化 | 服务只编排聚合与仓储接口;方法数超过 5 个通常是聚合边界没切好,先回查 `ddd-aggregates` |
+ | 仓储接口暴露实现形态(`findByNameAndDateRangeSQL(...)`) | 定义语义方法(如 `findActiveBookings(roomId)`),实现留给技术栈 |
+ | 所有事件一律配死信 + 去重窗口全套可靠性策略 | 只有跨上下文、影响资金或合规的事件需要全套;域内事件从简 |
## 示例
```text
@ddd-domain-interactions
基于以下聚合设计,帮我设计领域交互层:
- 聚合:Booking(根:Booking,VO:TimeSlot, BookingStatus)
- 聚合:RoomSchedule(根:RoomSchedule,VO:TimeSlotOccupancy)
- 事件候选:BookingConfirmed, BookingCancelled, CheckInRecorded
请输出领域事件目录、领域服务、仓储接口与订阅者清单。
```