mirror of
https://github.com/block/buzz.git
synced 2026-10-28 21:11:48 +00:00
Extend the merged /buzz/v1 read-state wire with the minimum the follow model needs: - `follow` / `unfollow` intents on a thread target. An unfollow sticks until the actor posts in the thread or is mentioned there again. - `GET /me/threads`: followed threads in joined channels, newest reply arrival first, cursor-paged, at most 50 per page. - Thread rows count `mentions` as direct mentions only. - Broadcast replies count on the channel timeline and are valid channel anchors. - NIP-11 advertises `capabilities: ["follow","threads"]` and `max_threads`. Migration 0061 adds `events.read_timeline`, `thread_metadata.received_at` and `personal_read_frontiers.unfollowed`, plus arrival-ordered partial indexes so the sidebar and threads view probe an index per channel and per follow instead of scanning a bounded window. No backfill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
34 lines
1.8 KiB
SQL
34 lines
1.8 KiB
SQL
-- ── Thread metadata ───────────────────────────────────────────────────────────
|
|
-- Conformance: thread lookups filter by community before event matching.
|
|
|
|
CREATE TABLE thread_metadata (
|
|
community_id UUID NOT NULL REFERENCES communities(id),
|
|
event_created_at TIMESTAMPTZ NOT NULL,
|
|
event_id BYTEA NOT NULL,
|
|
channel_id UUID NOT NULL,
|
|
parent_event_id BYTEA,
|
|
parent_event_created_at TIMESTAMPTZ,
|
|
root_event_id BYTEA,
|
|
root_event_created_at TIMESTAMPTZ,
|
|
depth INT NOT NULL DEFAULT 0,
|
|
reply_count INT NOT NULL DEFAULT 0,
|
|
descendant_count INT NOT NULL DEFAULT 0,
|
|
last_reply_at TIMESTAMPTZ,
|
|
broadcast BOOLEAN NOT NULL DEFAULT FALSE,
|
|
-- A reply's relay arrival; NULL on root stubs and rows before 0061.
|
|
received_at TIMESTAMPTZ,
|
|
PRIMARY KEY (community_id, event_created_at, event_id),
|
|
FOREIGN KEY (community_id, channel_id) REFERENCES channels (community_id, id)
|
|
);
|
|
|
|
CREATE INDEX idx_thread_metadata_parent ON thread_metadata (community_id, parent_event_id);
|
|
CREATE INDEX idx_thread_metadata_root ON thread_metadata (community_id, root_event_id);
|
|
CREATE INDEX idx_thread_metadata_window
|
|
ON thread_metadata (community_id, root_event_id, event_created_at DESC, event_id ASC);
|
|
CREATE INDEX idx_thread_metadata_channel_depth
|
|
ON thread_metadata (community_id, channel_id, depth, event_created_at);
|
|
CREATE INDEX idx_thread_metadata_event_id ON thread_metadata (community_id, event_id);
|
|
CREATE INDEX idx_thread_metadata_read_arrival
|
|
ON thread_metadata (community_id, root_event_id, received_at DESC, event_id)
|
|
WHERE received_at IS NOT NULL;
|