Files
scaffold/template/.claude/rules/ddd.md
T
baozaotumao df48c36422 refactor: 规则中性化——剥离 PPT 业务,统一为订单示范域
把规则从原 ppt-gen 项目泛化为通用脚手架,覆盖 19 个文件:
- ddd/architecture/design-discipline/error-codes/communication-* 等:
  领域术语、错误码、消息示例、扩展点、状态流统一为「订单」示范域
- agent-dag/agent.md/agent-concurrency/agent-llm-*:DAG 节点、配置、并发、
  LLM 适配从「对话→预览→生成→截图→合成」改为「intake→process→validate→finalize」
- backend-db:Session 实体/状态机/ORM/仓储/checkpoint 对齐新流水线
- 移除幻灯片专属依赖与产物:agent 去 playwright/python-pptx,
  Dockerfile 去 Chromium 系统库,.gitignore 去 *.pptx
- 保留合法通用项:ANSI(PTY 处理)、Playwright(E2E 测试工具)、Gemini CLI(真实 provider)

验证:gemini-cli/openai-api 两变体生成退出 0,生成项目零 PPT 残留,
backend/agent 骨架均可 import 运行。
2026-06-01 23:15:05 -07:00

2.9 KiB
Raw Blame History

领域驱动设计(DDD

统一语言(术语表)+ 领域建模规约(6 条强制)。

本项目领域优先:先建模领域,再落实现。任何编码前须完成领域建模,模型即代码结构的蓝图。

统一语言(Ubiquitous Language

代码、注释、提交、文档、对话一律使用同一套领域术语,禁止同义异名。

下表用「订单」作示范领域,仅为占位——新项目应替换为自己的业务术语;结构和约束保持不变:

术语 定义
订单 Order 一次交易的生命周期聚合根
订单项 OrderItem Order 内的单条商品明细
金额 Money 币种 + 数值的值对象(构造即自校验)
收货地址 ShippingAddress 带校验规则的值对象
订单状态 OrderStatus 状态机(待支付/已支付/已发货/已完成/已取消)
修订 Revision 对已存在 Order 的一次受控修改
检查点 Checkpoint 可恢复的状态快照
端口 Port 领域对外部能力的抽象接口(支付 / 通知 / 导出 / 存储)

术语变更须同步更新本表、代码标识符与契约,三者恒一致。

领域建模规约(强制)

目标:让后续未预见的变化只改一处(变化局部化)。不追求初期设计周全,追求封装良好——围绕「易变的决策」隐藏信息(Parnas Information Hiding)。以下为硬约束:

  1. 按意图建模,不按 CRUD 建模 领域对象暴露的是领域操作place / cancel / add_item),不是数据表的增删改查。先问"这个对象能做什么",而非"它有哪些字段的 getter/setter"。

  2. 易变规则收拢为值对象(Value Object 有规则、有约束的概念不用裸标量表示。规则全封进值对象,一处定义、全局复用。 反例:password: str,加密/校验规则散落各处 → 改一条动全身。 正例:Password 值对象(不可变、构造即自校验、matches() 比对),换算法/加规则只改它。

  3. 禁止暴露裸可变属性(封装 + Tell-Don't-Ask 不写 obj.x = v 这种外部直接改内部状态。通过意图方法操作,方法内强制不变量。 user.change_password(raw)  user.password = hash(raw)

  4. 充血模型,非贫血模型 数据与操作它的行为放在一起。领域逻辑属于领域对象/领域服务,禁止把领域规则泄漏到 application/service 层做成一堆过程式代码。

  5. 聚合根守护不变量 外部只能经聚合根操作其内部(如 User 之于 PasswordSession 之于其状态机),根负责保证整体一致性;不允许绕过根直接改内部对象。

  6. 判断"该不该独立 CRUD" 子概念若无独立生命周期(密码脱离用户无意义),它就不该有独立的增删改查,而是宿主聚合的行为。