diff --git a/internal/infra/notify/notify.go b/internal/infra/notify/notify.go new file mode 100644 index 0000000..7e23b7c --- /dev/null +++ b/internal/infra/notify/notify.go @@ -0,0 +1,65 @@ +// Package notify 定义通知模块的领域类型与 Notifier 接口契约。 +// +// 本文件仅做类型与接口声明,不包含任何具体投递实现。各类通道(dummy / +// email / webhook / IM 等)的真实发送逻辑由独立子包提供,并通过实现 +// Notifier 接口接入到通知服务的多通道分发流程。Channel 与 Severity 使用 +// 字符串别名作为枚举载体,便于直接落库与日志输出,同时仍保留类型安全。 +package notify + +import ( + "context" + "time" + + "github.com/google/uuid" +) + +// Channel 标识一条通知所走的投递通道。值与运行时配置/数据库中存储的字符串 +// 表示一致,新增通道时在此追加常量并实现对应的 Notifier。 +type Channel string + +const ( + // ChannelDummy 仅用于本地与测试环境,不做任何真实外发。 + ChannelDummy Channel = "dummy" + // ChannelEmail 通过 SMTP 或邮件服务商投递邮件。 + ChannelEmail Channel = "email" + // ChannelWebhook 通过 HTTP 调用外部 webhook 投递。 + ChannelWebhook Channel = "webhook" + // ChannelIM 通过即时通信服务(如企业 IM)投递。 + ChannelIM Channel = "im" +) + +// Severity 表示通知的重要级别。取值与 notifications 表中的 severity 列字符串 +// 对齐,避免在持久化与传输层做额外映射。 +type Severity string + +const ( + // SeverityInfo 为常规提示,不要求用户立即处理。 + SeverityInfo Severity = "info" + // SeverityWarning 表示需要用户关注但尚未失败的状况。 + SeverityWarning Severity = "warning" + // SeverityError 表示已经发生失败或风险事件,需用户尽快处理。 + SeverityError Severity = "error" +) + +// Message 是跨通道传递的通知载荷。各 Notifier 实现按需读取字段,未消费的 +// 字段(例如纯 IM 通知的 Link)应保持为零值而非占位字符串,以便日志与审计 +// 区分缺省与显式空。Metadata 仅存放结构化的扩展字段,不承载敏感原文。 +type Message struct { + ID uuid.UUID + UserID uuid.UUID + Topic string + Severity Severity + Title string + Body string + Link string + Metadata map[string]any + CreatedAt time.Time +} + +// Notifier 是单一投递通道的统一契约。Name 返回该实现对应的 Channel,便于 +// 上层根据配置路由消息;Send 必须是同步语义——返回 nil 视为投递成功,否则 +// 由上层决定是否重试或记录失败。实现需要尊重 ctx 的取消与超时。 +type Notifier interface { + Name() Channel + Send(ctx context.Context, msg Message) error +}