Repository navigation
feat: who replied last on a thread, and which reply solved a topic - #348
Merged
Merged
Conversation
A page's thread summaries (chat:fetch) and the update a reply sends now carry recent_repliers: up to three people who replied most recently, newest first, for the faces on a replies line. A thread also keeps answer_message_id: it's set by thread:status:set when a topic is marked solved with answerMessageId, which has to be a reply in that topic, and any other status drops it. The column is added with ALTER TABLE like threads.tags. An older client ignores both fields, and an older server sends neither, so the phone treats them as absent. Part of GRYT-1963. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 28, 2026
grytchat
added a commit
that referenced
this pull request
Oct 28, 2026
#348 added the answer to every summary built by toThreadSummary, but thread:fetch builds its thread object by hand, so opening a solved topic didn't show which reply answered it. Found checking the phone against it. Part of GRYT-1963. Co-authored-by: Sivert <316918682+grytchat@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
The server half of C18 and C21/C22 on the design canvas. Part of GRYT-1963. Touches
src/db, so it waits for your review.Recent repliers (C18)
listRecentRepliers(threadIds)inthreads.tsreturns up to three distinct people who replied most recently in each thread, newest first. It's one grouped query overmessages.thread_id, and it doesn't count the root's author.chat:fetchincludes it on each page thread asrecent_repliers. So does thethread:updateda reply sends. Status and tag updates leave it out, and the phone keeps what it had.The answer (C21/C22)
threads.answer_message_id TEXT, added withALTER TABLElikethreads.tags. Null for every existing thread.thread:status:settakes an optionalanswerMessageId. It only counts withsolved, and has to be a reply in that topic (message.thread_id === thread.thread_id). Otherwise it'sthread:error { error: "bad_answer" }and nothing changes. Any other status clears it, so reopening forgets the answer.manage_messages.toThreadSummarycarriesanswer_message_id, so every summary has it.What to look at
GROUP BY thread_id, sender_server_id ORDER BY MAX(created_at)query. It's bounded by the page's thread ids, at most a page of threads, but it does scan their replies.listRecentRepliersonce per reply inchat:send. It's one indexed query (idx_messages_thread) on the send path.threadSummaryShape.test.tsnow expectsanswer_message_ideverywhere, andrecent_repliersonchat:fetchonly.Tests:
listRecentRepliers(three, newest first, once each, none for none), the answer being kept, broadcast and dropped on reopen, and a refused answer that isn't a reply. All 2139 server tests pass, and the build, lint and comment check are clean.The phone half is a separate mobile PR. An older server sends neither field, and the phone handles that.
🤖 Generated with Claude Code