返回 Skills
vinvcn/mattpocock-skills-zh-cn· MIT 内容可用

domain-modeling

构建并打磨项目的领域模型。适用于用户想明确领域术语或通用语言、记录架构决策,或其他技能需要维护领域模型时。

安装

与 skills.sh 相同的 Command / Prompt 安装方式


name: domain-modeling description: 构建并打磨项目的领域模型。适用于用户想明确领域术语或通用语言、记录架构决策,或其他技能需要维护领域模型时。

Domain Modeling

在设计过程中主动构建并打磨项目的 domain model。这是 active discipline:挑战术语、发明 edge-case scenarios,并在概念成形的当下写入 glossary 和 decisions。(仅仅读取 CONTEXT.md 来获取词汇,不是这个 skill;那只是任何 skill 都能做的一行习惯。这个 skill 用于改变 model,而不是消费 model。)

File structure

多数 repos 只有一个 context:

/
|- CONTEXT.md
|- docs/
|  `- adr/
|     |- 0001-event-sourced-orders.md
|     `- 0002-postgres-for-write-model.md
`- src/

如果 root 有 CONTEXT-MAP.md,说明 repo 有多个 contexts。map 指向每个 context 的位置:

/
|- CONTEXT-MAP.md
|- docs/
|  `- adr/                          -> system-wide decisions
`- src/
   |- ordering/
   |  |- CONTEXT.md
   |  `- docs/adr/                  -> context-specific decisions
   `- billing/
      |- CONTEXT.md
      `- docs/adr/

按需懒创建文件:只有在有内容要写时才创建。如果没有 CONTEXT.md,当第一个 term 被解决时创建它。如果没有 docs/adr/,当第一个 ADR 需要出现时创建它。

During the session

Challenge against the glossary

当用户使用的术语与 CONTEXT.md 中既有语言冲突时,立即指出。"Your glossary defines 'cancellation' as X, but you seem to mean Y - which is it?"

Sharpen fuzzy language

当用户使用模糊或过载术语时,提出一个精确的 canonical term。"You're saying 'account' - do you mean the Customer or the User? Those are different things."

Discuss concrete scenarios

讨论 domain relationships 时,用具体场景做压力测试。发明能探测 edge cases 的场景,迫使用户精确定义概念之间的 boundaries。

Cross-reference with code

当用户描述某事如何工作时,检查代码是否同意。如果发现矛盾,要指出:"Your code cancels entire Orders, but you just said partial cancellation is possible - which is right?"

Update CONTEXT.md inline

当一个 term 被解决时,立刻更新 CONTEXT.md。不要批量攒到最后;随着概念出现就捕获。使用 CONTEXT-FORMAT.md 中的格式。

CONTEXT.md 必须完全不包含 implementation details。不要把 CONTEXT.md 当 spec、scratch pad 或 implementation decisions 的仓库。它只是一份 glossary。

Offer ADRs sparingly

只有以下三项都成立时,才提出创建 ADR:

  1. Hard to reverse - 之后改变主意的成本有意义
  2. Surprising without context - 未来读者会疑惑 "why did they do it this way?"
  3. The result of a real trade-off - 确实存在替代方案,而你基于具体理由选择了其中一个

缺少任一项就跳过 ADR。使用 ADR-FORMAT.md 中的格式。

附带文件

ADR-FORMAT.md
# ADR Format

ADRs 位于 `docs/adr/`,使用连续编号:`0001-slug.md`、`0002-slug.md` 等。

按需懒创建 `docs/adr/` 目录:只有第一个 ADR 需要出现时才创建。

## Template

```md
# {Short title of the decision}

{1-3 sentences: what's the context, what did we decide, and why.}
```

就这些。ADR 可以只有一个段落。价值在于记录 *做出了某个决定* 以及 *为什么*,而不是填满章节。

## Optional sections

只有在真正增加价值时才包含这些。多数 ADRs 不需要。

- **Status** frontmatter(`proposed | accepted | deprecated | superseded by ADR-NNNN`)- 当 decisions 会被重新审视时有用
- **Considered Options** - 只有被拒绝的 alternatives 值得记住时才写
- **Consequences** - 只有需要指出非显而易见的下游影响时才写

## Numbering

扫描 `docs/adr/` 中已有的最高编号并递增一。

## When to offer an ADR

以下三项必须全部成立:

1. **Hard to reverse** - 之后改变主意的成本有意义
2. **Surprising without context** - 未来读者看到代码会疑惑 "why on earth did they do it this way?"
3. **The result of a real trade-off** - 确实存在替代方案,而你基于具体理由选择了其中一个

如果决定很容易反转,就跳过;你会直接反转它。如果它不意外,就没人会问为什么。如果没有真正 alternative,就没有超过 "we did the obvious thing" 的内容可记录。

### What qualifies

- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
- **Technology choices that carry lock-in.** Database、message bus、auth provider、deployment target。不是每个 library,只有那些替换要花一个季度的。
- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." 明确的 no 和 yes 一样有价值。
- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." 任何合理读者会默认相反方案的地方,都值得记录,避免下一个 engineer 把 deliberate choice "修掉"。
- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
- **Rejected alternatives when the rejection is non-obvious.** 如果你考虑过 GraphQL,却因为微妙原因选择 REST,就记录;否则六个月后还会有人再提 GraphQL。
CONTEXT-FORMAT.md
# CONTEXT.md Format

## Structure

```md
# {Context Name}

{One or two sentence description of what this context is and why it exists.}

## Language

**Order**:
{A one or two sentence description of the term}
_Avoid_: Purchase, transaction

**Invoice**:
A request for payment sent to a customer after delivery.
_Avoid_: Bill, payment request

**Customer**:
A person or organization that places orders.
_Avoid_: Client, buyer, account
```

## Rules

- **Be opinionated.** 当多个词指向同一概念时,选出最好的那个,并把其他词列在 `_Avoid_` 下。
- **Keep definitions tight.** 最多一两句话。定义它是什么,而不是它做什么。
- **Only include terms specific to this project's context.** 一般编程概念(timeouts、error types、utility patterns)不属于这里,即使项目大量使用它们。添加 term 前先问:这是该 context 独有的概念,还是通用编程概念?只有前者属于这里。
- **Group terms under subheadings** when natural clusters emerge. 如果所有 terms 都属于一个 cohesive area,平铺列表也可以。

## Single vs multi-context repos

**Single context(多数 repos):** root 下一个 `CONTEXT.md`。

**Multiple contexts:** root 下一个 `CONTEXT-MAP.md`,列出 contexts、它们的位置和彼此关系:

```md
# Context Map

## Contexts

- [Ordering](./src/ordering/CONTEXT.md) - receives and tracks customer orders
- [Billing](./src/billing/CONTEXT.md) - generates invoices and processes payments
- [Fulfillment](./src/fulfillment/CONTEXT.md) - manages warehouse picking and shipping

## Relationships

- **Ordering -> Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
- **Fulfillment -> Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
- **Ordering -> Billing**: Shared types for `CustomerId` and `Money`
```

Skill 会推断应使用哪种结构:

- 如果存在 `CONTEXT-MAP.md`,读取它来找到 contexts
- 如果只有 root `CONTEXT.md`,按 single context 处理
- 如果两者都没有,当第一个 term 被解决时懒创建 root `CONTEXT.md`

存在多个 contexts 时,推断当前主题属于哪一个。如果不清楚,就询问。
    domain-modeling | Prompt Minder