fix(message-gatekeeper): allow quoting a tshow message from its parent channel (#432)#433
fix(message-gatekeeper): allow quoting a tshow message from its parent channel (#432)#433chenjr0719 wants to merge 1 commit into
Conversation
|
Warning Review limit reached
Next review available in: 51 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds a ChangesTShow Quoted-Parent Feature
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
ee7e485 to
eb01658
Compare
eb01658 to
bf4c348
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pkg/model/cassandra/message.go`:
- Around line 59-61: The Cassandra quoted-parent message model is now missing
the new tshow field in its UDT mirrors, so update the QuotedParentMessage
definitions to stay aligned with message.go’s TShow mapping. Add the tshow
BOOLEAN field to the QuotedParentMessage schema in both the documentation mirror
and the Cassandra init UDT, keeping the field names and ordering consistent with
the existing quoted message structure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6eb73fd9-3c79-47dd-9e72-65c4ef045396
📒 Files selected for processing (6)
docs/client-api.mdmessage-gatekeeper/fetcher_history.gomessage-gatekeeper/handler.gomessage-gatekeeper/handler_test.gopkg/model/cassandra/message.gopkg/model/cassandra/message_test.go
bf4c348 to
c803d3e
Compare
| DecodedAttachments []cassandra.Attachment `json:"attachments"` | ||
| ThreadParentID string `json:"threadParentId"` | ||
| ThreadParentCreatedAt *time.Time `json:"threadParentCreatedAt"` | ||
| TShow bool `json:"tshow"` |
There was a problem hiding this comment.
Can you check if we store tshow in quotedParentMsg in current behavior ?
There was a problem hiding this comment.
Good question — checked on current `main`: no, `tshow` is not stored in the `quoted_parent_message` snapshot. The UDT has no `tshow` field, and nothing writes one into it.
What is persisted is the message's own `tshow` — the `tshow` column on `messages_by_id` (`Message.TShow cql:"tshow"`). So this PR adds `TShow` to the quote projection as transient (`cql:"-"`, never persisted) and populates it per-request from history's by-id reply (fetcher_history.go:105 ← parent.TShow, i.e. the parent row's own persisted flag), not from the stored snapshot. That keeps it schema/UDT-change-free and migration-free — the snapshot stays as-is.
There was a problem hiding this comment.
Checked — no, current (main) behavior does not store tshow on the quoted-parent snapshot, and this PR doesn't persist it either:
- On
main, neitherquotedParentProjectionnor thecassandra.QuotedParentMessageUDT has atshowfield. The only tshow-related data captured on the parent snapshot isthread_parent_id/thread_parent_created_at(set by message-worker when the quoted message is a TShow reply), which history-service's access-window redaction reads together with the outer message's ownm.TShow(history-service/internal/service/utils.goquoteInaccessible). - The
TShowfield this PR adds toQuotedParentMessageis taggedcql:"-"— it is JSON-only, not written to thequoted_parent_messageUDT column, so there's no schema/migration change. It's populated transiently at quote-resolution time from the live parent row (FetchQuotedParentreads it via history-serviceGetMessageByID, whose reply is a fullcassandra.Messageand already carriestshow) and consumed only in-process by the gatekeeper carve-out inresolveQuoteSnapshot(tshowChannelQuote := snap.TShow && newMessageThreadID == "" && snap.RoomID == newMessageRoomID).
So the flag is authoritative from the live parent at send time; nothing new is stored, and on a later read-back of the persisted snapshot TShow is simply absent (false), which no read path depends on. Happy to drop the field from the UDT struct and thread it through a local var instead if you'd prefer it not live on QuotedParentMessage at all.
Summary
Refs #432. Quoting a
tshow("also send to channel") thread reply from itsparent channel room was rejected with
thread context mismatch, because thequoted-parent's own
ThreadParentID(non-empty, since it's a thread reply)never matched the quoting message's thread (empty, since it's posted in the
channel).
Changes
pkg/model/cassandra/message.go: addTShowtoQuotedParentMessage.message-gatekeeper/fetcher_history.go: carrytshowthrough thequoted-parent projection fetched from history-service.
message-gatekeeper/handler.go:checkQuoteThreadContextnow takes thequoting message's room and allows the quote when the parent is
tshowandthe quote is posted from that same channel room (not from an unrelated room
or a different thread).
docs/client-api.md: documented the newtshowfield onQuotedParentMessageand the carve-out in the thread-context-mismatch errorrow.
Verification
TestHandler_resolveQuoteSnapshot(
message-gatekeeper/handler_test.go): tshow-from-channel allowed,non-tshow thread reply from channel still rejected, tshow parent from an
unrelated room still rejected, tshow parent quoted from within its own
thread still allowed.
go build ./message-gatekeeper/... ./history-service/... ./pkg/...passes.go test -race ./message-gatekeeper/... ./history-service/... ./pkg/model/...passes.Why surface
tshowon the quote projectionThe guard must distinguish a tshow ("also send to channel") parent — legitimately visible
in the channel — from a normal thread reply, which is not. Both carry a non-empty
ThreadParentIDand a channelRoomID, so no existing snapshot field tells them apart;tshowis the only discriminator.tshowis not new data: it already exists on themessages_by_idrow and is alreadyreturned by history-service's get-by-id reply. The gatekeeper simply fetches a narrow
projection of the quoted parent (
quotedParentProjection) that previously dropped it — sothis change stops discarding a field already on the wire, rather than adding state. No
history-service change, no schema/DDL.
The only alternative that avoids carrying the flag is to replace the thread-linkage rule
with a room-visibility check (resolve whether the quoted message is present in the quoter's
room timeline). That costs an extra read per quote and a larger re-architecture of the
same-conversation rule for no benefit here, so it was rejected in favor of the existing,
already-transmitted
tshowflag.Summary by CodeRabbit
New Features
Bug Fixes
Documentation