feat: community moderation, invitations, notifications, and cursor pagination
Adds 14 new XRPC endpoints across community moderation, invitations, channel
reads, and a notification system, plus fixes the pagination TODO in
list_atproto_records to use rkey-based opaque cursors matching
com.atproto.repo.listRecords semantics.
Highlights:
- Cursor pagination: rkey-based, atproto-style. listRecords now returns
cursors only when a page is full.
- Read endpoints: listCategories, listChannels, listMembers,
channel.listMessages, channel.getReadCursor, channel.listReactions.
- Community moderation: blockUser, unblockUser, blockMessage,
listBlockedUsers. Backed by a new social.colibri.moderation record type
(single lexicon with action field, ozone-style audit log).
- Role/permission system: new social.colibri.role + social.colibri.member
lexicons; ActorAuthz with owner shortcut, channel overrides
(allow/deny), Discord-style hierarchy enforcement on ban+kick.
- Invitations: createInvitation, getInvitation, listInvitations,
deleteInvitation backed by a new off-protocol community_invitations
table.
- Notifications: indexer parses social.colibri.richtext.facet#mention and
detects parent-author replies; rows persisted once with a unique index
for dedupe; new listNotifications (paginated, embeds message body),
getUnreadCount, updateSeen endpoints. Real-time delivery over the
existing subscribeEvents WS as notification_event.
- Lexicons: social.colibri.role, social.colibri.member, and
social.colibri.moderation added to the website's lexicons.ts (separate
repo, separate PR).
Tests: 128 passing, up from 56 before this branch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>