From bc101b32787bafa53df6bb9c3b0771cc2185a386 Mon Sep 17 00:00:00 2001 From: richjohnrambo Date: Wed, 21 Oct 2026 12:40:40 +0800 Subject: [PATCH] fix: query tenant-sharded private messages --- server/auth_audit_test.go | 13 +++++++++++++ server/internal_admin_query_resources.go | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/server/auth_audit_test.go b/server/auth_audit_test.go index f6c9be0..b8625ec 100644 --- a/server/auth_audit_test.go +++ b/server/auth_audit_test.go @@ -72,6 +72,19 @@ func TestMessageQuerySpecsExposeAdminFields(t *testing.T) { } } +func TestPrivateMessageQueryUsesTenantShardTables(t *testing.T) { + spec := privateMessagesInternalQuerySpecForTenant(types.TenantID(9)) + query := strings.ToLower(spec.From) + for _, table := range []string{"im_009_messages", "im_009_subscriptions"} { + if !strings.Contains(query, table) { + t.Fatalf("private message query must use tenant shard table %q: %s", table, query) + } + } + if strings.Contains(query, "from im_messages ") || strings.Contains(query, "from im_subscriptions ") { + t.Fatalf("private message query must not use legacy shared tables: %s", query) + } +} + func TestGroupMessageQuerySupportsOperationalFilters(t *testing.T) { req := httptest.NewRequest("GET", "/?seq_id=42&sender_username=alice&sender_nickname=%E5%B0%8F%E6%98%8E&group_name=%E6%B5%8B%E8%AF%95%E7%BE%A4", nil) query, _, args, _, _, err := buildInternalAdminListQuery(req, groupMessagesInternalQuerySpec(), "", types.TenantID(1)) diff --git a/server/internal_admin_query_resources.go b/server/internal_admin_query_resources.go index 7662422..b410dfe 100644 --- a/server/internal_admin_query_resources.go +++ b/server/internal_admin_query_resources.go @@ -127,6 +127,9 @@ func serveInternalAdminResourceList(wrt http.ResponseWriter, req *http.Request, writeIMError(wrt, req, http.StatusNotFound, 30004, imReasonMalformedRequest, "resource not found", nil) return } + if resource == "private-messages" { + spec = privateMessagesInternalQuerySpecForTenant(tenantID) + } if resource == "group-messages" { var err error spec, err = groupMessagesInternalQuerySpecForTenant(tenantID) @@ -400,6 +403,14 @@ func privateMessagesInternalQuerySpec() *internalQuerySpec { } } +func privateMessagesInternalQuerySpecForTenant(tenantID types.TenantID) *internalQuerySpec { + spec := privateMessagesInternalQuerySpec() + prefix := fmt.Sprintf("im_%03d_", tenantID) + spec.From = strings.Replace(spec.From, "FROM im_messages ", "FROM "+prefix+"messages ", 1) + spec.From = strings.ReplaceAll(spec.From, "FROM im_subscriptions ", "FROM "+prefix+"subscriptions ") + return spec +} + func groupMessagesInternalQuerySpec() *internalQuerySpec { status := `CASE WHEN aa.action='delete' THEN 'deleted' WHEN aa.action='hide' THEN 'hidden' WHEN m.status='recalled' THEN 'recalled' WHEN m.status IN ('deleted','blocked') THEN m.status ELSE 'normal' END` contentType := `CASE m.msg_type WHEN 'call' THEN 'system' WHEN 'system_notice' THEN 'system' WHEN 'contact_card' THEN 'card' WHEN 'forward_bundle' THEN 'card' WHEN 'link' THEN 'text' ELSE m.msg_type END`