mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-09 09:56:47 +08:00
Before: the feed could not tell which conversations had moved since the
reader last looked, so every card read the same.
After: opening an issue (page or peek) records a per-user read cursor after
1.5 s, posting a comment records it at once, and feed cards whose newest
counted comment is later than the cursor carry a small dot on the left: a
plain dot when the reader spoke last, a ringed one when someone else did
and the reply is theirs to make.
How: table issue_read_cursor (no primary key in the create, a CONCURRENTLY
built unique index on (user_id, issue_id) attached as the primary key in a
later migration, no foreign keys), queries UpsertIssueReadCursor (monotonic
GREATEST on the database clock), ListIssueReadCursors and the three
cleanup deletes wired into issue deletion, member removal and workspace
teardown. PUT /api/issues/{id}/read returns 204; thread-summaries gains
last_read_at for the caller. Core adds api.markIssueRead, useMarkIssueRead
and patchThreadSummariesLastRead; the comment-created patch keeps the
cursor. Views add getFeedReadState and the dot on FeedMessageCard, the
delayed mark in IssueDetail and the immediate mark on send in
useIssueTimeline.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_017deksZDSzZBA4QSqZZoBip
20 lines
888 B
SQL
20 lines
888 B
SQL
-- Per-user issue read cursors for the project feed's unread dots.
|
|
--
|
|
-- One row per (user, issue): last_read_at is the server time at which the user
|
|
-- last opened the issue. A card is unread when the issue's newest counted
|
|
-- comment is later than the cursor; no row means the user never opened it.
|
|
--
|
|
-- workspace_id is stored so member removal and workspace teardown can sweep a
|
|
-- user's or a workspace's cursors without joining issue. No foreign keys by
|
|
-- project rule: issue deletion, member removal and workspace deletion clean
|
|
-- the rows up in application code.
|
|
--
|
|
-- (user_id, issue_id) is attached as the primary key in 587 from the index
|
|
-- built CONCURRENTLY in 586 (repo convention, see 573-575).
|
|
CREATE TABLE IF NOT EXISTS issue_read_cursor (
|
|
user_id UUID NOT NULL,
|
|
issue_id UUID NOT NULL,
|
|
workspace_id UUID NOT NULL,
|
|
last_read_at TIMESTAMPTZ NOT NULL
|
|
);
|