From 210fe8c12c08fe2a1b47b730928d254e9b21db2e Mon Sep 17 00:00:00 2001 From: rayhpeng Date: Fri, 31 Jul 2026 11:16:30 +0800 Subject: [PATCH] docs(hexagonal): establish the layering spec and its enforcement Introduces the ports-and-adapters standard new backend modules are expected to follow, plus the two pieces that make it more than prose: `deerflow/domain/` as the inner-ring namespace, and an AST test that fails when anything under it imports infrastructure. The spec is normative rather than descriptive -- the existing modules predate it, so the test guards the namespace, not the whole backend. Co-Authored-By: Claude Opus 5 --- backend/docs/HEXAGONAL_ARCHITECTURE_zh.md | 291 ++++++++++++++++++ .../docs/assets/hexagonal_architecture.png | Bin 0 -> 1339805 bytes .../assets/hexagonal_dispatch_relation.png | Bin 0 -> 1011017 bytes .../harness/deerflow/domain/__init__.py | 9 + backend/tests/test_harness_domain_purity.py | 72 +++++ 5 files changed, 372 insertions(+) create mode 100644 backend/docs/HEXAGONAL_ARCHITECTURE_zh.md create mode 100644 backend/docs/assets/hexagonal_architecture.png create mode 100644 backend/docs/assets/hexagonal_dispatch_relation.png create mode 100644 backend/packages/harness/deerflow/domain/__init__.py create mode 100644 backend/tests/test_harness_domain_purity.py diff --git a/backend/docs/HEXAGONAL_ARCHITECTURE_zh.md b/backend/docs/HEXAGONAL_ARCHITECTURE_zh.md new file mode 100644 index 000000000..2a1c8b090 --- /dev/null +++ b/backend/docs/HEXAGONAL_ARCHITECTURE_zh.md @@ -0,0 +1,291 @@ +# DeerFlow 后端架构:六边形设计规范 + +> 本文是**规范**:新业务模块必须按此结构落地,代码与规范冲突时以规范为准。全文只讲标准形态,不绑定具体模块——规则落到真实代码上的样子,见参考实现的模块文档:[SCHEDULE_DESIGN_zh.md](SCHEDULE_DESIGN_zh.md)。编码规约见 `backend/AGENTS.md`。 +> +> 引用标记 [C] / [G] / [B] / [P] 的出处见 §7。 + +--- + +## 1. 六边形架构是什么 + +真名 **Ports & Adapters**(Cockburn, 2005 [C])。"六边形"只是画图的偶然。它的意图,原文一句话说尽: + +> "Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases." [C] +> +> (允许应用被用户、程序、自动化测试或批处理脚本**平等地**驱动,并且能在与最终运行期设备和数据库**隔离**的条件下开发与测试。) + +![六边形架构定义图](assets/hexagonal_architecture.png) + +| 图中概念 | 定义 | 规范落点 | +|---|---|---| +| Domain Model · Aggregates | 聚合:一致性边界,不变量在构造期成立 | `domain//model` | +| Domain Model · Value Objects | 值对象:无身份、按值比较;解析校验过的领域概念 | 同上 | +| Domain Model · Domain Errors | 领域自己的失败词汇——入口拿它们映射协议码,而不是让领域认识 409 | `exceptions.py` | +| Application Service(input port) | 用例编排的入口面,自身不含业务规则 | `service.py` | +| Ports | **领域自己声明、自己拥有**的技术中立接口,画在六边形的边上——它是六边形的一部分 | `ports.py` | +| Driving / Primary Adapters | 驱动应用的入口。Cockburn 点名 http 应用、批处理、**自动化测试**皆是 driver——"测试与真实入口平等"是定义的一部分 | 入口 + 时钟 + 回调 + service 测试 | +| Driven / Secondary Adapters | 实现端口的外部集成:自有持久化 与 防腐层 两形态(§2) | `app/adapters//` | +| External Service / Other Context | 对一个六边形而言,**同进程的邻居上下文也是外部世界**——这是防腐层存在的原因 | 防腐层的对接对象 | + +**全图的题眼是两种箭头**:实线 "calls" 是调用方向(入口调进来,业务也经端口调出去);虚线 "implements" 是依赖方向(适配器实现领域声明的接口)。调用可以双向穿越边界,**依赖永远指向内**——两者解耦即"依赖反转"的准确含义([B]:"the domain is the core of the application and doesn't depend on any other module")。 + +**唯一检验**:业务逻辑能否在没有 HTTP、没有数据库的测试里(全部换成 fake)完整运行——参考实现的 service 测试套件就是这个检验的常态化:整个用例在零 IO 的 dict fake 上端到端跑通。 + +## 2. 标准结构 + +本仓库先有一条自己的边界:**harness(`deerflow.*`,可发布框架包)/ app(`app.*`,不发布应用层)**,依赖单向 app → harness。六边形叠加其上的切分规则一句话: + +> **domain(模型 + 命令 + 端口 + 应用服务)归 harness;adapters + 入口 + 组合根归 app。** + +结构直接采用 AWS Prescriptive Guidance 的三文件夹划分——"entrypoints (primary adapters), domain (domain and interfaces), and adapters (secondary adapters)" [B]——每个业务模块的规定形态: + +``` +packages/harness/deerflow/domain// # 内圈(对应 AWS domain/ 七件套 [B]) +├── model.py 或 model/ # 聚合·值对象(model/:"entities, value objects, and domain services") +├── exceptions.py # 领域错误(exceptions/:"the known errors defined within the domain"; +│ # 与 model 平级——AWS 树中 exceptions/ 是七件套的独立成员) +├── commands.py # 命令(commands/:"command objects that define the information +│ # required to perform an operation on the domain";见 §3.1) +├── ports.py # 端口(ports/:"abstractions through which the domain communicates +│ # with databases, APIs, or other external components") +│ # ★ ports 是 domain 的子目录,不是与之平级的第三层——抽成独立层 +│ # 会让领域依赖外部包才能声明自己的需求,恰好破坏依赖倒置 +├── service.py # 应用服务(command_handlers/:"methods or classes that run commands +│ # on the domain";写方法即 handler,命名依据见 §3.1) +└── (events.py) # 领域事件——按 §3.2 的触发条件引入,默认不建 + +backend/app/adapters// # 从适配器(AWS adapters/ [B]) +├── <端口名snake_case>.py # 一个端口一个文件;两种形态见下 +backend/app/gateway/routers// # 入口(AWS entrypoints/ [B];目录名沿用既有 routers, +│ # 等多数模块六边形化后一次性更名) +├── router.py # 协议转换 + 领域错误→HTTP 单表映射 +└── models.py # api model:"defines the interface the primary adapter requires to + # communicate with clients" [B] —— 主适配器自己的模型,不是领域 + # 对象的视图;入向 to_command、出向 from_domain,见 §2.1 +backend/app/composition.py # 组合根:适配器唯一实例化点(AWS 未定义此概念, + # 本仓库自有——纯函数,装配规则可被单测断言) +``` + +**文件命名规则**: + +- **单复数**:装同类多件的文件用复数(`ports.py` / `commands.py` / `exceptions.py` / `events.py`);装单一整体概念或单个类的用单数(`model` = the domain model 这个整体,AWS 目录树与 cosmicpython 同为单数;`service.py` 里恰好一个 Application Service 类)。名从形态,不照搬 Django 的 `models.py`——那是 ORM 语境。 +- **错误类名保留 PEP 8 的 `Error` 后缀**(如 `XxxNotFoundError`),文件名叫 `exceptions.py` 对齐 AWS 概念名——两者不冲突,`requests/exceptions.py` 里放 `HTTPError` 正是先例;`Exception` 后缀是 Java/C# 惯例,与标准库和本仓库全部现存错误类相悖,禁止引入。 +- 一个上下文一个错误基类(`Error`),入口的单表映射可按基类兜底。 + +**从适配器的两种形态**,判据两问——表归本上下文所有吗?自己写 SQL 吗: + +| | 两问皆是:自有持久化 | 两问皆否:防腐层(ACL) | +|---|---|---| +| docstring 首行标记 | `Secondary adapter (owned persistence)` | `Secondary adapter (anti-corruption layer)` | +| 类名前缀 | `Sql`(我自己写 SQL) | 被包装者的名字(读作"我借道那个组件") | +| 职责 | 领域对象 ↔ ORM 行显式互译;技术异常 → 领域错误 | 把上游宽接口收窄成本上下文的一个问题 | + +技术维度不进文件名(换存储时 `sql_` 前缀就得改名,而端口没变);防腐层的 TODO 写**触发条件**而非抱怨——上游发布契约(一个 DTO,不是它的聚合或仓储)时替换类体,端口不动。**跨上下文只能拿 DTO**,永远不依赖别人的聚合或仓储。 + +**ORM 行的归属**是一条有意规则而非欠债:表定义随共享的 engine/alembic migrations 基建统一居住在 harness `persistence/` 下,**适配器是它唯一的读写方**;迁出的触发条件是共享基建的所属模块自身六边形化。 + +### 2.1 转换链:数据的四次变形 + +**线上格式(wire)**:HTTP body 中实际传输的原始 JSON——转换链的最外端形态,类型系统之外的世界(没有 tuple 只有 array、没有 datetime 只有字符串,客户端想塞什么字段都能塞)。wire 上的字节就是 API 契约本身。 + +一个写请求穿过六边形时,数据恰好变形四次(① ② ③w ④);读回程经 ③r 重建。每次变形有**唯一的 owner 和规定的方法名**——这是全文档最机械、也最值得机械执行的部分: + +| # | 变形 | Owner | 方法 | 规则 | +|---|---|---|---|---| +| ① | wire → Command | 请求模型 | `to_command(path_params..., user_id)` | body 归模型字段;路径参数与**服务端解析的身份**经参数注入——**身份字段禁止出现在请求模型上**;wire 类型 → 领域类型(如 `list` → `tuple`)在此完成;无 body 的用例在端点内直接构造 command,不造空请求模型 | +| ② | Command → 聚合 | handler(service 写方法) | 显式逐字段调聚合工厂 `Aggregate.create(...)` | 禁止 `**asdict(cmd)`——显式字段列表是闸门;禁止聚合与 command 互相 import(两者只在 service 相遇);**工厂参数 = 聚合字段(减去工厂生成的代理主键)**:标量传标量、多个参数共同表达一个领域概念时聚成值对象传入,永不收 command——聚合的构造面向多个来源(handler、适配器重建、测试),不绑定任何用例的输入形态 | +| ③w | 聚合 → ORM 行 | 自有持久化适配器 | `_apply(row, aggregate)`(就地) | **一份显式字段清单服务 insert 与 update 两条写路径**——新字段不可能"插入有值、更新静默丢失";代理主键不进 `_apply`(在 insert 构造行时定死,upsert 保留既有身份归端口契约)。例外:CAS 型写方法(§4)分字段所有权,**刻意不走**整聚合映射 | +| ③r | ORM 行 → 聚合 | 自有持久化适配器 | `_to_domain(row)` | 显式字段列表;读取归一化(如补时区)只发生在此处;重建也过 `__post_init__`(坏行读取即爆);技术异常在适配器译成领域错误 | +| ④ | 聚合 → wire | 响应模型 | `from_domain(aggregate)` classmethod | 白名单渲染,服务端字段(租约、身份内部形态…)不进 wire;禁止模块级散转换函数 | + +**命名链**:一个写用例一个名字,三种拼写互为变体——command `PascalCase` 祈使动词短语(无 `Command` 后缀,模块路径已是语境)↔ handler 方法 `snake_case` ↔ 请求模型 `Request`。grep 任何一个拼写就能找到用例的全部三层。 + +静态结构(类图,通用角色): + +```mermaid +classDiagram + class UseCaseRequest { + <> + +仅 body 字段 + +to_command(path_params, user_id) Command + } + class ResourceResponse { + <> + +from_domain(aggregate)$ + } + class Command { + <> + +路径参数·user_id·payload + } + class ApplicationService { + <> + +use_case(cmd) Aggregate + +query(params) 批量 + } + class Aggregate { + <> + +create()$ + +__post_init__() 校验 + } + class OutputPort { + <> + +save(aggregate) + } + class SqlAdapter { + <> + -_apply(row, aggregate) + -_to_domain(row) + } + class OrmRow + + UseCaseRequest ..> Command : ① to_command + ApplicationService ..> Command : 消费 + ApplicationService ..> Aggregate : ② create + ApplicationService --> OutputPort : 调用 + SqlAdapter ..|> OutputPort : 实现 + SqlAdapter ..> OrmRow : ③w _apply / ③r _to_domain + ResourceResponse ..> Aggregate : ④ from_domain + note for Command "Command 与 Aggregate 互不 import\n唯一汇点是 Service" +``` + +## 3. Commands 与 Events + +AWS 的 domain 七件套里有 `commands/` 与 `events/` [B]。commands 是本仓库的标准配备;events 采用轻量形态 + 明确的升格触发条件——不是省略,是设计决策,何时升格写在这里。 + +### 3.1 Commands:写用例一律 command 化,查询不 + +标准形态是每个用例一个 command 对象 + 每 command 一个 handler——[G] 指出这是单一职责与开闭原则的应用方式。本仓库的规定: + +- **写用例一律 command 化**:每个改变状态的用例对应 `commands.py` 里的一个 frozen dataclass,handler 即 service 方法;**查询保持普通参数**——command 表达改变状态的意图,包装读操作是纯样板(CQRS 的最浅形态:读写异形)。 +- **command 是哑数据**:不做业务校验——值规则归聚合 `__post_init__`,结构校验归入口的 api model,所以错误归因顺序(构造聚合先于任何 IO)仍由 handler 的构造顺序拥有。 +- **构造点在 api model**:`body.to_command(...)`(§2.1 变形 ①)——wire 形状拥有"翻译成领域词汇"这半边。 +- **部分更新的提示**:update 类用例(`None` = 未提供)command 化时需要 `Unset` sentinel 表达三态,勿把 `None` 的两种含义混进一个字段。 +- **文件为何叫 `service.py` 而非 `command_handlers.py`**:"Application Service" 是六边形/DDD 的一级正统术语,AWS 的 `command_handlers/` 是它的一种实现风格(函数式 handler + 注册表分发),不是概念本身的名字——名字跟着选定的形态走:本仓库的形态是"handler 即 service 方法",且该类还持有不收 command 的查询方法,叫 `command_handlers.py` 会错报一半内容(cosmicpython 同样先叫 `services.py`,到引入 message bus 那章才改名 `handlers.py`)。**演进分界**:当 §3.2 的 events 升格、组合根引入统一 dispatcher 时,写路径的自然形态变为独立 handler 函数(command handler 与 event handler 同居 `handlers.py`,按类型分发),`Service` 类在写侧消解、读侧留成 `queries.py`——在那之前,一个 Service 类聚合读写用例是更少样板、类型可追踪的形态。它的贫血风险由既有规则守住:"service 自身不含业务规则"(§4)。 + +### 3.2 Events:业务事实默认走入站适配器,第二订阅方出现时升格为事件 + +标准形态是领域行为完成后发出事件("Define events that the domain objects emit after they complete a behavior" [B]),供其他模块订阅。本仓库的对应设计: + +- **轻量形态**:一个业务事实只有一个消费者时,用**点对点回调 + 入站适配器**表达——入站适配器负责过滤(与本上下文无关的事件压根产生不出领域 DTO,service 因此不需要守卫子句)与翻译(运行时类型 → 领域词汇),再调用用例。组合根只装这一个监听者,领域不产生事件对象。 +- **升格触发条件**:同一业务事实出现**第二个订阅方**。判例:要给某个已有回调链的事实加通知——在监听者里加分支(入站适配器开始编排)或让 service 调通知端口(本上下文被迫认识通知领域)都是错误答案——正确答案是此刻引入事件。 +- **升格路径**: + 1. 事件类型放 `domain//events.py`(frozen dataclass,领域词汇),由**应用服务**在用例完成处发出——聚合保持纯函数式(返回新状态),不自带事件收集器; + 2. 组合根装配一个进程内同步 dispatcher(`dict[事件类型, list[订阅者]]` 即可起步),替换单一 hook;订阅者住各自上下文的入站适配器; + 3. 既有入站适配器的过滤与翻译职责不变——它翻译出的领域 DTO 驱动用例,用例完成后发领域事件;跨进程投递(AWS 语境的 "routed to other microservices")是第三阶段,触发条件是真的拆了服务。 + +## 4. 规则清单 + +每条附执法手段;无机械执法的靠 review,标 ⚠。 + +| 规则 | 执法 | +|---|---| +| harness 永不 import `app.*` | `tests/test_harness_boundary.py` | +| `domain/` 永不 import sqlalchemy / fastapi / pydantic / app / harness 基础设施 | `tests/test_harness_domain_purity.py`(AST) | +| 不变量在 `__post_init__` 校验,工厂与直接构造走同一条路("创建即一致",绕不过去) | 域测试(直接构造也校验的用例模式) | +| `now` 与运营阈值显式传入(`now=` 参数、policy 值对象注入),领域不读时钟与配置 | 纯度测试拦 import;⚠ `datetime.now` 靠 review | +| 端口签名技术中立:不出现 SQL、表名、HTTP 状态码、`Mapping[str, Any]`、运行时类型 | ⚠ review;`Mapping` 出现即领域在处理传输/存储格式 | +| 事务边界在端口方法内部(`async with session_factory()`);session 不进路由签名 | ⚠ review;per-request session 会破坏冲突翻译点与非 HTTP 入口 | +| 技术异常在适配器译成领域错误,翻译点唯一;防腐层只许端口契约声明的异常逃逸 | 契约测试 + service 测试 | +| 领域错误 → HTTP 码单表映射;未分类错误落 500,不默认 4xx | router 测试 | +| 转换链四次变形的 owner 与方法名固定(§2.1),身份字段禁止出现在请求模型上 | ⚠ review | +| 契约测试覆盖每个端口方法**并断言返回值**——`isinstance(repo, Port)` 抓不到拼错的方法名(Protocol 继承使名字总是存在) | 各上下文契约套件 × 双实现 | +| CAS 不得表达成 `save(aggregate)`——读改写会重新引入 CAS 要关的竞态 | 契约测试 | +| 响应模型是白名单不是 dump;服务端字段不进 wire | api model 显式字段 | +| 越权一律表现为"不存在"(None / False / 404),不抛权限错误 | 契约测试 + owner isolation 测试 | + +测试分层与架构分层一一对应:域测试红 = 规则错;service 测试红 = 编排错;契约测试红 = 存储实现错。契约测试全绿**不代表**可以多实例并发——原子性归实现不归契约,由真数据库的 race 测试单独负责。 + +## 5. 调用关系:读与写的标准链路 + +### 5.1 写链路 + +```mermaid +sequenceDiagram + participant C as Client + participant R as Router + API Model + participant S as Application Service + participant A as Aggregate + participant P as 防腐层
(经 output port) + participant AD as SQL Adapter
(经 output port) + participant DB as DB + + C->>R: PUT /resource {body} + R->>R: ① body.to_command(path, user_id) + Note over R: 身份服务端解析,禁止进 body + R->>S: use_case(cmd) + S->>A: ② Aggregate.create(...) + Note over S,A: 构造期校验——规则先于任何 IO + S->>P: 引用完整性 / 前置事实 + S->>AD: save(aggregate) + AD->>DB: ③w _apply(row) → 短事务 + DB-->>AD: row + AD-->>S: ③r _to_domain → Aggregate + S-->>R: Aggregate + R-->>C: ④ 200 Response.from_domain(...) + Note over R: 白名单渲染 + + alt 领域错误 + S--)R: DomainError + R-->>C: 单表映射 → 4xx(未分类落 500) + end +``` + +要点各归其位:编排顺序本身是设计——先构造聚合(零 IO 校验先行),错误归因不受 IO 结果影响;事务收在端口方法内部,路由不知道 session 存在;技术异常在适配器译成领域错误后才穿出边界。 + +### 5.2 读链路 + +```mermaid +sequenceDiagram + participant C as Client + participant R as Router + participant S as Application Service + participant AD as SQL Adapter
(经 output port) + participant DB as DB + + C->>R: GET /...(一页数据) + R->>S: query(scope_id, keys, user_id) + Note over R,S: 查询不 command 化——普通参数 + S->>AD: 批量读 + AD->>DB: 单次查询覆盖整页(防 N+1) + DB-->>AD: rows + AD-->>S: dict[key, Aggregate] + Note over AD: _to_domain 逐行重建——
坏行读取即爆(单行)或跳过并记日志(列表) + S-->>R: 领域对象批量 + R-->>C: from_domain 白名单渲染,嵌入宿主响应 + Note over R: 越权数据表现为"查不到",不是权限错误 +``` + +读侧三条规则在此汇齐:查询收普通参数(§3.1);批量方法按页返回、不设 N+1 形态的单条端点;所有者过滤是仓储参数而非异常。 + +### 5.3 多驱动源 + +写链路的 driver 不只 HTTP:时钟入口(poller)与运行时回调入口(inbound adapter)走完全相同的 `Service → Ports → Adapters` 路径,只是 ① 的形态不同——时钟入口没有 wire 形状,直接构造调用;回调入口先过滤再翻译成领域 DTO(§3.2)。真实系统中三种驱动源共存的宏观图与派发闭环,见 [SCHEDULE_DESIGN_zh.md](SCHEDULE_DESIGN_zh.md)。 + +**本节的结论**:调用双向穿越边界(入口调进来、业务调出去、回调再调进来),依赖从不——六边形内的代码 import 不到链路右侧的任何东西,由 §4 的 AST 测试执法而非自觉。 + +## 6. 现状与待办 + +| 模块 | 状态 | +|---|---| +| **Scheduling** | ✅ 参考实现(`domain/schedule/` + `app/adapters/schedule/`);旧代码已删除 | +| Feedback | 旧模式,待迁移 | +| Run / ThreadMeta / RunEvent / Channel 等 | 旧模式,待迁移——阅读时勿以其为模板,新模块一律照 §2 | + +待办,按优先级: + +| # | 待办 | +|---|---| +| 1 | 补防腐层对真实上游组件的契约测试(防腐层的门本身没被测过) | + +## 7. 引用出处 + +引用 AWS / Cockburn 须给页面级出处;JS 渲染页(`welcome.html` 等)不作引用锚点。 + +- **[C]** Cockburn, *Hexagonal Architecture*(2005)——Intent 原句与 driver 类别清单: + +- **[G]** AWS Prescriptive Guidance, *Building hexagonal architectures on AWS* — Introduction: + +- **[B]** 同指南 *Best practices*——三文件夹结构与 domain 七件套定义: + +- **[P]** *Structure a Python project in hexagonal architecture using AWS Lambda*——同一结构的 Python 落地示例: + diff --git a/backend/docs/assets/hexagonal_architecture.png b/backend/docs/assets/hexagonal_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7c4d2a4b6cb26e892f6dab78d1ee0078c54a08 GIT binary patch literal 1339805 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