3.2 KiB
3.2 KiB
Dever Port 与 Adapter
Goal
把外部 HTTP、邮件、对象存储等依赖变成编译期验证、运行时可配置替换的 Port/Adapter 边界,同时收紧应用角色依赖,禁止 App 绕过 Port 和 Domain/Adapter 反向依赖业务层。
Dependencies
secure-data-contracts:Secret setting 和不可观察边界。time-typed-codec:类型化 setting 解码和共享 wire schema。
Requirements
port.dever/port/*.dever只允许类型和 bodyless function contract;每个 contract 显式fails同领域 App 公开 error choice 或公开标准 error choice,至少一个显式 error variant。Port 自有 DTO 仍私有。- Port contract 输入、命名输出、failure contract 和逻辑身份稳定,不从任一 Adapter 实现反推。
- Adapter 通过 qualified Port target 显式实现;签名必须相同,实际 failure set 必须是声明集合的子集。
- Adapter 可包含同文件私有类型/helper,但不能调用 App、Domain、Model、其他 Adapter 或 Port;只能调用标准库和自身 helper。
- App 只能调用同领域 Port;Domain 只能调用同领域 Domain;Model 无业务函数;API/Job 只调用同领域 App。
- Port 调用的 suspend/effect 是所有可选实现的保守并集,仍由现有静态 effect 系统决定 worker/await 边界。
- 单实现自动绑定;多个实现必须由
config/setting.json的稳定 Port identity 选择,未配置、未知实现或未知 setting 字段启动失败。 - Adapter 可声明一个 typed setting record;只有被选择实现的 setting 必须存在并解码,Secret 字段不进入日志/错误。
- 编译产物包含闭合实现集合和直接 match,不使用动态库、反射、trait-object business dispatch 或运行时源码扫描。
- Test 可在同一个测试文件完整 fake 多个 Port;fake 只绑定当前 TestCase,测试不读取项目 Adapter setting 或回退到生产实现。
- Port/Adapter 的
.dever.md文档合同与普通源码一致。
Acceptance Criteria
- 合法 bodyless Port 和单 Adapter 可被 App 调用并生成直接静态实现调用。
- Port body、Adapter 缺失/重复实现、签名/命名输出/failure 不匹配在 check 阶段拒绝。
- App 直调 Adapter、Domain 访问 Model/Port/Adapter、Adapter 反调 App/Domain/Model 和跨领域 Port 调用全部拒绝。
- 多 Adapter 通过
setting.json在不重新编译的情况下选择;未知选择、缺配置、未知字段和错误类型启动失败。 - 未选择 Adapter 的 setting 不要求存在,其代码仍通过静态检查并包含在闭合产物中。
- Secret setting 可以用于批准 sink,但不能出现在日志、错误、API/Job output 或普通字符串中。
- 两个应用测试可以对同一 Port 使用不同 fake,单套件编译后各自运行且互不泄漏。
- Port effect/failure 通过 App、transaction、handler specialization 正确传播,不出现动态 fallback。
Out Of Scope
- 运行时安装插件、动态库、服务发现和远端代码加载。
- 跨领域直接共享 Port;领域间继续通过 App 合同协作。
- 通用依赖注入容器、Service locator 或应用可变全局 registry。
- Adapter 热切换;setting 在进程启动时验证并固定。