fix(channel): message_sent 回声升 T2 落行,出站消息 id 不再被丢

塔转 M12 登记的缺口(塔裁定「归你」,文件都在本片 scope 内):她自己发出消息
的回声(message_sent)被当成「帧级链路遥测」一并豁免 self 升档 ⇒ 停在 T1,
只进计数、不落行,`message_id` 被丢,「她最近发了哪些消息」在库里查不到。

- events.go: 把 MessageSent 从 isFrameTelemetry 的豁免里摘出(它不是帧级遥测:
  一帧 = 她真发出的一条消息,回声带的是那条出站消息的 id)。
  心跳 / 生命周期的豁免**保持不变**(其登记的迁移债注释原样保留)。
- events_mapping_test.go: 两条 MessageSent 断言同步更新
  (:52 自身回声命中自己 ⇒ 由 T1 改 T2;:33 无 self 信号仍走基础档 T1,标签改精确)。
- events_test.go: 新增端到端用例(真 SQLite):self 命中 ⇒ 落 1 行、tier=t2、
  MessageID=out-msg-42 留在库里、不进上下文、不驱动 loop。
This commit is contained in:
AskaEth committed 2026-10-13 20:50:31 +08:00
1 parent 537a8b7988
commit 1d49d266f0
3 files changed
+56 -9

No files matched your search

@@ -205,6 +205,48 @@ func TestRecordEvent_unknown不进上下文但落行_正常(t *testing.T) {
}
}
// TestRecordEvent_自身回声升T2落行带出站id_正常 钉住切 M13 修掉的缺口(原 M12 登记):
// 她自己发出消息的回声(message_sent)**不是帧级遥测** —— self 命中必须把它从 T1 升到 T2
// 逐条落行,`message_id`(出站消息 id)随之留在库里;此前它被帧级豁免挡回 T1,id 被丢。
func TestRecordEvent_自身回声升T2落行带出站id_正常(t *testing.T) {
t.Parallel()
ctx := context.Background()
store := newTestEventStore(t)
ad := eventAdapter("qq-obv11:conf0", adapter.SystemNotice{
Kind: adapter.NoticeOther,
Category: adapter.NoticeCategoryMessageSent,
PlatformType: "message_sent",
Ignorable: true,
SelfRelated: true,
RefMessage: "out-msg-42",
})
b, chat, hist, _ := eventBridgeFixture(t, ad, store)
b.processFrom(ctx, groupNoticeMessage(), ad)
if chat.sessionID != "" {
t.Fatalf("出站回声驱动了 loop:session=%q", chat.sessionID)
}
if recs := hist.records(); len(recs) != 0 {
t.Fatalf("出站回声被登记进会话历史:%+v", recs)
}
rows, err := store.List(ctx, events.Filter{})
if err != nil {
t.Fatalf("List: %v", err)
}
if len(rows) != 1 {
t.Fatalf("出站回声落行数 = %d, want 1(self 命中 ⇒ T2 逐条落行)", len(rows))
}
ev := rows[0]
if ev.Tier != events.TierT2 || ev.Category != events.Category(adapter.NoticeCategoryMessageSent) {
t.Fatalf("落行档位/类别 = (%s,%s), want (t2,message_sent)", ev.Tier, ev.Category)
}
if ev.MessageID != "out-msg-42" {
t.Fatalf("出站消息 id = %q, want out-msg-42(id 必须留在库里)", ev.MessageID)
}
}
// TestRecordEvent_未接线时入站照常_异常:`Options.EventStore == nil` 时降级为
// 「内存计数 + 首次一条 DEBUG」,**绝不**中断入站 —— 高价值事件的升级真会话行为必须
// 逐字不变(fail-visible 而非 fail-crash,§4.3)。