Skip to content

Commit fbd1a05

Browse files
authored
fix(subscription): surface favorite timestamp under favoriteUpdatedAt (#423)
1 parent e3b4e70 commit fbd1a05

4 files changed

Lines changed: 24 additions & 22 deletions

File tree

docs/client-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ user-service endpoints via room-service's `GetRoomsInfo` enrichment. `room` is
665665
| `restricted` | boolean | Optional. Denormalized room restricted flag. |
666666
| `externalAccess` | boolean | Optional. Denormalized room external-access flag. |
667667
| `room` | [SubscriptionRoom](#subscriptionroom) | Optional. Room-derived view (read-time enrichment; user-service endpoints only). |
668-
| `favoritedAt` | RFC3339 timestamp | Optional. When the user favorited the room. |
668+
| `favoriteUpdatedAt` | RFC3339 timestamp | Optional. Last time the user toggled favorite on the room (also bumped on un-favorite). |
669669
| `updatedAt` | RFC3339 timestamp | Optional. When the subscription was last updated. |
670670

671671
#### SubscriptionRoom

pkg/model/model_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4079,19 +4079,19 @@ func TestSubscriptionEnrichmentFields_RoundTrip(t *testing.T) {
40794079
}
40804080

40814081
func TestSubscriptionBaseMetadata_RoundTrip(t *testing.T) {
4082-
favoritedAt := time.Date(2026, 2, 1, 9, 0, 0, 0, time.UTC)
4082+
favoriteUpdatedAt := time.Date(2026, 2, 1, 9, 0, 0, 0, time.UTC)
40834083
updatedAt := time.Date(2026, 3, 2, 10, 0, 0, 0, time.UTC)
40844084
src := model.Subscription{
4085-
ID: "s1",
4086-
User: model.SubscriptionUser{ID: "u1", Account: "alice"},
4087-
RoomID: "r1",
4088-
SiteID: "site-a",
4089-
Roles: []model.Role{model.RoleMember},
4090-
RoomType: model.RoomTypeChannel,
4091-
JoinedAt: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
4092-
HasUnread: true,
4093-
FavoritedAt: &favoritedAt,
4094-
UpdatedAt: &updatedAt,
4085+
ID: "s1",
4086+
User: model.SubscriptionUser{ID: "u1", Account: "alice"},
4087+
RoomID: "r1",
4088+
SiteID: "site-a",
4089+
Roles: []model.Role{model.RoleMember},
4090+
RoomType: model.RoomTypeChannel,
4091+
JoinedAt: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
4092+
HasUnread: true,
4093+
FavoriteUpdatedAt: &favoriteUpdatedAt,
4094+
UpdatedAt: &updatedAt,
40954095
}
40964096
dst := model.Subscription{}
40974097
roundTrip(t, &src, &dst)
@@ -4107,7 +4107,7 @@ func TestSubscriptionBaseMetadata_RoundTrip(t *testing.T) {
41074107
zb, err := json.Marshal(&model.Subscription{ID: "z", JoinedAt: time.Now().UTC()})
41084108
require.NoError(t, err)
41094109
require.NoError(t, json.Unmarshal(zb, &zero))
4110-
for _, k := range []string{"favoritedAt", "updatedAt"} {
4110+
for _, k := range []string{"favoriteUpdatedAt", "updatedAt"} {
41114111
_, present := zero[k]
41124112
assert.False(t, present, "%q must be omitted when unset", k)
41134113
}

pkg/model/subscription.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ type Subscription struct {
5858
// Subscription-level metadata persisted on the Mongo subscriptions document.
5959
// UpdatedAt is a nullable pointer so a creating writer that doesn't stamp it
6060
// (e.g. room-worker's $setOnInsert) never persists a zero-time placeholder.
61-
FavoritedAt *time.Time `json:"favoritedAt,omitempty" bson:"favoritedAt,omitempty"`
61+
// Last favorite-toggle time (also bumped on un-favorite). bson key matches what the
62+
// writers store; the old `favoritedAt` key was never written, so the value never surfaced.
63+
FavoriteUpdatedAt *time.Time `json:"favoriteUpdatedAt,omitempty" bson:"favoriteUpdatedAt,omitempty"`
6264
// Stored as `_updatedAt` in Mongo (matches the canonical subscriptions schema);
6365
// serialized on the wire as `updatedAt`. Rooms keep the plain `updatedAt` field.
6466
UpdatedAt *time.Time `json:"updatedAt,omitempty" bson:"_updatedAt,omitempty"`

user-service/mongorepo/subscriptions.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,14 @@ func subscriptionProjection(extra bson.M) bson.M {
177177
"hasMention": 1,
178178
// hasGroupMention removed from the schema; hasUnread is computed at read
179179
// time (bson:"-"). Neither is projected from Mongo.
180-
"threadUnread": 1,
181-
"alert": 1,
182-
"muted": 1,
183-
"favorite": 1,
184-
"restricted": 1,
185-
"externalAccess": 1,
186-
"favoritedAt": 1,
187-
"_updatedAt": 1, // subscription's Mongo field (wire: updatedAt)
180+
"threadUnread": 1,
181+
"alert": 1,
182+
"muted": 1,
183+
"favorite": 1,
184+
"restricted": 1,
185+
"externalAccess": 1,
186+
"favoriteUpdatedAt": 1,
187+
"_updatedAt": 1, // subscription's Mongo field (wire: updatedAt)
188188
// room baseline copied to the top level (consumed by local enrichment)
189189
"userCount": 1,
190190
"lastMsgAt": 1,

0 commit comments

Comments
 (0)