/** * msg 服务 Kafka Topic 映射。 * * 仲裁依据: * - M5:消费 topic 用 `edu.teaching.*` / `edu.identity.*` / `edu.insight.*` * - 发布 topic 用 `edu.notification.*`(02-architecture-design.md §5.2) * * PRODUCER_TOPIC_MAP:eventType → topic,OutboxPublisher 按此路由发布。 * CONSUMER_TOPICS:msg 消费的所有 topic 列表,KafkaConsumer 订阅。 */ /** 生产者:eventType → Kafka topic 路由 */ export const PRODUCER_TOPIC_MAP: Record = { "notification.sent": "edu.notification.sent", "notification.read": "edu.notification.read", "notification.recalled": "edu.notification.recalled", "notification.failed": "edu.notification.failed", }; /** 兜底 topic:未在 TOPIC_MAP 命中的 eventType 走此 topic */ export const FALLBACK_TOPIC = "edu.notification.events"; /** 消费者:订阅的 topic 列表(iam 6 + core-edu 5 + data-ana 1 = 12 类事件) */ export const CONSUMER_TOPICS: readonly string[] = [ // iam(identity) "edu.identity.user.created", "edu.identity.user.updated", "edu.identity.user.deleted", "edu.identity.user.role_changed", "edu.identity.role.created", "edu.identity.role.updated", // core-edu(teaching) "edu.teaching.exam.published", "edu.teaching.assignment.submitted", "edu.teaching.assignment.graded", "edu.teaching.grade.recorded", "edu.teaching.attendance.recorded", // data-ana(insight) "edu.insight.mastery.updated", ] as const; /** 消费事件 → 通知类型 映射(KafkaConsumer 路由用) */ export const CONSUMER_EVENT_TYPE_MAP: Record = { "edu.identity.user.created": "system", "edu.identity.user.role_changed": "system", "edu.identity.role.created": "system", "edu.identity.role.updated": "system", "edu.teaching.exam.published": "exam", "edu.teaching.assignment.submitted": "homework", "edu.teaching.assignment.graded": "grade", "edu.teaching.grade.recorded": "grade", "edu.teaching.attendance.recorded": "attendance", "edu.insight.mastery.updated": "mastery", }; /** * 根据 eventType 解析目标 topic。 * 未命中时降级到 FALLBACK_TOPIC。 */ export function resolveTopic(eventType: string): string { return PRODUCER_TOPIC_MAP[eventType] ?? FALLBACK_TOPIC; }