From 98234db263968aae33f943e12124eb455c8423c4 Mon Sep 17 00:00:00 2001 From: richjohnrambo Date: Wed, 9 Sep 2026 17:39:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E6=94=B6=E8=97=8F=E6=BA=90=E9=81=BF=E5=85=8D=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/im_http.go | 17 ++++++++++++++--- server/im_http_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/server/im_http.go b/server/im_http.go index b2e623f..3a5aefb 100644 --- a/server/im_http.go +++ b/server/im_http.go @@ -7912,6 +7912,12 @@ func favoritePayloadForPrincipal(principal *imPrincipal, item types.FavoriteItem } sourceTopic, ok := normalizeIMFavoriteSourceTopic(principal.Uid, item.SourceTopic) if !ok { + if legacyFavoriteSnapshotOnly(item) { + if item.Availability == "" { + item.Availability = "available" + } + return favoritePayload(item), true + } return nil, false } if err := requireTopicReader(principal, sourceTopic); err != nil { @@ -7934,6 +7940,11 @@ func favoritePayloadForPrincipal(principal *imPrincipal, item types.FavoriteItem return favoritePayload(item), true } +func legacyFavoriteSnapshotOnly(item types.FavoriteItem) bool { + source := strings.TrimSpace(item.SourceTopic) + return strings.HasPrefix(source, "favSeed") && item.Snapshot != nil +} + func messageSearchPayload(msg types.Message, query string) map[string]any { text := messageText(msg) snippet := textSnippet(text, query) @@ -9586,15 +9597,15 @@ func normalizeIMUserVisibleTopic(viewer types.Uid, topic string) (string, bool) if len(topic) < 3 { return "", false } - switch types.GetTopicCat(topic) { - case types.TopicCatMe: + switch topic[:3] { + case "usr": peer := types.ParseUserId(topic) if peer.IsZero() { return "", false } p2p := viewer.P2PName(peer) return p2p, p2p != "" - case types.TopicCatP2P, types.TopicCatGrp, types.TopicCatSlf: + case "p2p", "grp", "slf": return topic, true default: return "", false diff --git a/server/im_http_test.go b/server/im_http_test.go index a83728e..8962c0a 100644 --- a/server/im_http_test.go +++ b/server/im_http_test.go @@ -4964,6 +4964,41 @@ func TestServeIMFavoritesListSupportsRefOnlyAttachment(t *testing.T) { } } +func TestServeIMFavoritesListKeepsLegacySeedSnapshots(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + expectIMBearer(t, ctrl, "token-1", 7, 42) + oldFavorites := store.Favorites + oldSubs := store.Subs + oldMessages := store.Messages + now := time.Date(2026, 9, 9, 9, 0, 0, 0, time.UTC) + store.Favorites = &testFavoritesStore{items: []types.FavoriteItem{{ + TenantID: 7, FavoriteID: "fav_seed_19179719768_text", UserID: 42, ItemType: "text", + SourceTopic: "favSeed19179719768", SourceSeq: 7001, Availability: "available", CollectedAt: now, + Snapshot: map[string]any{"text": "seed favorite"}, + }}} + store.Subs = mock_store.NewMockSubsPersistenceInterface(ctrl) + store.Messages = nil + defer func() { + store.Favorites = oldFavorites + store.Subs = oldSubs + store.Messages = oldMessages + }() + + req := httptest.NewRequest(http.MethodGet, "/v1/im/favorites?type=all", nil) + req.Header.Set("Authorization", "Bearer token-1") + rec := httptest.NewRecorder() + serveIMFavorites(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String()) + } + data := decodeIMHTTPResponse(t, rec).Data.(map[string]any) + items := data["items"].([]any) + if len(items) != 1 || items[0].(map[string]any)["favorite_id"] != "fav_seed_19179719768_text" { + t.Fatalf("unexpected legacy seed favorite response: %#v", data) + } +} + func TestNormalizeIMUserVisibleTopicSelf(t *testing.T) { uid := types.Uid(42) got, ok := normalizeIMUserVisibleTopic(uid, "slf")