This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-TMP-REPO/apps/api/src/modules/channel/CONTRACT.md
T

2.4 KiB

module: channel

职责: 通道实例:配置(归属键提取规则 / 载荷映射 / 默认认领岗位)、入站归一 (解析 → 系统写 → 数据事件)、出站发送与出站关联记录登记 不负责: 归属解析与三级消费判定(见 event,经 EventGateway 端口)、 台账写入的实现(见 ledger,经 LedgerSystemWriter 端口)、消息兜底的呈现(见 message)

公开出口: index.ts

  • 类型:ChannelService ChannelInstanceConfig ExtractRule LedgerMapping NormalizedWrite InboundOutcome OutboundMail
  • 错误:ChannelNotFoundError ChannelDisabledError
  • 端口类型:ChannelRepository EventGateway LedgerSystemWriter MailTransport AttachmentArchive Clock IdGenerator
  • 用例工厂:createChannelService(deps: ChannelServiceDeps): ChannelService
  • 纯函数:extractFields normalize
  • adapter:createChannelRepository createSimulatedMailTransport createFileAttachmentArchive
  • Drizzle 表:channelTable outboundMailTable

层级: L2(编码规范 §4) 依赖: @contracts;@shared/db;port:EventGateway(app 注入 event)、 LedgerSystemWriter(app 注入 ledger)、MailTransport(app 注入,转 mail 模块) 被依赖: release(出站发送)、app(治理台 · 系统管理 / ingest 路由)

不变量:

  • 活动认数据,不认通道:入站一律归一为域.对象.字段的写入,通道对活动的前提不可见
  • 入站归一走 系统写(登记世界已发生的事实,免门、即时抛数据事件), 绝不走草稿写、也不绕过 ledger 出口(§12.5#9)
  • 归属解析不在本模块:通道只交事实,判定归 event —— 匹配次序与降级口径一处实现
  • 无主不写台账:仅有主入站才归一为系统写;无主入站只入事件流并走消息兜底
  • 无主键的映射结果丢弃(无从定位),由调用方按提取失败处置
  • 出站即登记关联记录:线程 ID 与往来地址是归属解析①③级的对表来源
  • 邮件通道是外界:真通道由 mail 模块提供(ADR-013)—— app 把 channel.ingestMail 注册为它的订阅方, 把 MailTransport 注入为「转 mail.send」(按发件地址找账号,对不上不回落默认); createSimulatedMailTransport 只剩测试 / 演示用途,/api/ingest 仍是注入门(e2e 用); 系统内部机制一律真跑,不得 mock

影响半径: index/contract/port 未变 → 对外零影响