feat(history-service): rooms.get — batch room last-message read (#393)#413
Draft
chenjr0719 wants to merge 3 commits into
Draft
feat(history-service): rooms.get — batch room last-message read (#393)#413chenjr0719 wants to merge 3 commits into
chenjr0719 wants to merge 3 commits into
Conversation
New per-site, account-scoped RPC chat.user.{account}.request.history.{siteID}.rooms.get:
given {roomIds[]}, returns each accessible room's latest message ({roomId -> lastMessage}),
resolved at read time. Mirrors the ThreadSubscriptionList per-site shape; the caller
groups rooms by site and issues one batch per site.
Per room: existing access check, then the latest message via the existing
messages_by_room DESC read (access-window + history-floor aware). A2 read-only — no
denormalized write, no event, no walk-back: a soft-deleted latest message is returned
as-is with deleted=true. Best-effort batch (bounded concurrency; a non-accessible/empty/
errored room is omitted, never failing the batch); content preview-trimmed to 256 runes.
docs/client-api.md updated (doc-ratchet). Closes #393.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The per-room loop broke on c.Err() then returned a nil-error partial response, which golangci-lint's nilerr flagged. On a cancelled/timed-out context the caller is gone, so propagate the error instead of returning a partial OK that won't be read.
…rooms.get (#393) Add read-time (A2) last-message enrichment to subscription.list: a new enrichWithLastMessage pass groups every resolved room by site and fans out one rooms.get RPC per site (bounded by maxSiteFanout, chunked at 100), embedding the result as SubscriptionRoom.LastMessage. No denormalized writes, no edit/delete hooks, no event — a degraded site simply leaves LastMessage nil. Move the rooms.get wire types (LastMessage/RoomsGetRequest/RoomsGetResponse) to pkg/model so user-service consumes them without importing history-service internals; history-service aliases them (no behavior change). Add historyclient.RoomsGet mirroring GetThreadList; regenerate mocks. Doc-ratchet client-api.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements
rooms.get(chat#393) — the room last-message endpoint (the customer's/api/v1/rooms.get, used by mobile to render the last-message snippet in the roomlist). A new history-service, per-site, account-scoped batch RPC that resolves each
requested room's latest message at read time (A2). Maintainer-approved approach (A2,
option E2) per the #393 design-lock.
What's included
chat.user.{account}.request.history.{siteID}.rooms.get— account+site fromthe subject,
{roomIds[]}in the body. One batch per site; the caller groups a user'srooms by site and fans out (same shape as
ThreadSubscriptionList).RoomsGethandler (history-service) →roomLastMessage: per room, the existingaccess check (
checkAccessAndRoomTimes) then the latest message via the existingmessages_by_room … DESCreads (GetMessagesBefore/GetMessagesBetweenDesc,limit 1) — access-window + history-floor aware (mirrors LoadHistory). No new repo method.
walk-back — a soft-deleted latest message is returned as-is with
deleted=true.not-accessible / empty / errored is omitted, never failing the batch. Batch ≤ 100;
contentpreview-trimmed to 256 runes.docs/client-api.md§3.2 "Get Rooms Last Message" (doc-ratchet).#393 completion — web-sidebar integration
pkg/model(LastMessage,RoomsGetRequest,RoomsGetResponse) so user-service can consume them without importinghistory-service internals; history-service's own
modelspackage now aliases them(
type LastMessage = model.LastMessage, etc. — no behavior change).SubscriptionRoom.LastMessage *model.LastMessage(pkg/model/subscription.go) —new optional field on the room-derived view returned by
subscription.list.historyclient.Client.RoomsGet— new per-site RPC call mirroring the existingGetThreadListpattern (marshal request, NATS request/reply,errcode.Parse,unmarshal). Added to the
HistoryClientinterface; mocks regenerated.UserService.enrichWithLastMessage(user-service/service/subscriptions.go) —new enrichment pass in
ListSubscriptions, run afterenrichWithRoomInfo. Groupsevery subscription with a resolved
Roomby site (local and cross-site — unlikeroom-info enrichment, last-message isn't part of the local
$lookupbaseline), fansout one
rooms.getcall per site (bounded by the existingmaxSiteFanoutsemaphore), chunking each site's roomIds at 100 to respect history-service's own
batch cap. A degraded or absent site just leaves those rooms'
lastMessagenil —it never fails the list.
docs/client-api.md— added thelastMessagefield to theSubscriptionRoomtable + example, and reconciled the
rooms.getRPC description to notesubscription.listnow calls it server-side (the RPC also remains directly callable).Out of scope (follow-up)
included above.
Verification
go build ./pkg/... ./history-service/... ./user-service/...— clean.go test ./pkg/... ./history-service/... ./user-service/...— green, including twonew
TestListSubscriptions_LocalBaselineRoom_NoKeyassertions and a newTestListSubscriptions_LastMessage_SiteDegradestest (site RPC failure degradesgracefully, list still succeeds).
🤖 Generated with Claude Code