code
Clone this repository
https://tangled.org/bretton.dev/coves
git@knot.bretton.dev:bretton.dev/coves
For self-hosted knots, clone URLs may differ based on your setup.
Add 16 integration test cases covering:
1. Jetstream Consumer Indexing (4 tests):
- Block CREATE event indexing
- Block DELETE event indexing
- Idempotent duplicate event handling
- Graceful handling of non-existent block deletion
2. List Operations (3 tests):
- List all blocked communities for user
- Pagination with limit/offset
- Empty list for users with no blocks
3. IsBlocked Queries (3 tests):
- Returns false when not blocked
- Returns true when blocked
- Returns false after unblock
4. GetBlock Operations (3 tests):
- Error when block doesn't exist
- Retrieve block by user DID + community DID
- Retrieve block by AT-URI (for DELETE operations)
All tests verify proper database state, idempotency guarantees,
and Jetstream event processing.
Implement Jetstream consumer support for community block records:
- handleBlock: Routes CREATE/DELETE operations for social.coves.community.block
- createBlock: Indexes block CREATE events from firehose
- Extracts community DID from "subject" field (atProto convention)
- Builds AT-URI: at://user_did/social.coves.community.block/rkey
- Preserves createdAt timestamp for chronological ordering during replays
- Idempotent: handles duplicate events via ON CONFLICT
- deleteBlock: Processes block DELETE events from firehose
- Looks up block by URI (DELETE events don't include record data)
- Removes from AppView index
- Gracefully handles deletion of non-existent blocks
Completes the write-forward flow:
Client → PDS → Jetstream Firehose → Consumer → AppView DB
Register community blocking XRPC endpoints:
- POST /xrpc/social.coves.community.blockCommunity (requires auth)
- POST /xrpc/social.coves.community.unblockCommunity (requires auth)
Both routes use RequireAuth middleware to ensure proper authentication
before allowing block/unblock operations.
Add XRPC handlers for community blocking endpoints:
- HandleBlock: POST /xrpc/social.coves.community.blockCommunity
- HandleUnblock: POST /xrpc/social.coves.community.unblockCommunity
Features:
- Input validation: Community must be DID (did:plc:...) or handle (!name@instance)
- Authentication: Requires user DID and access token from middleware
- Response format: Follows atProto conventions with recordUri/recordCid
- Error handling: Uses shared handleServiceError for consistency
Addresses PR review comment on input validation.
Implement service layer for community blocking following atProto
write-forward architecture:
- BlockCommunity: Creates block record on PDS using user's access token,
handles duplicate errors gracefully by fetching existing block
- UnblockCommunity: Deletes block record from PDS, extracts rkey from URI
- GetBlockedCommunities: Queries AppView with pagination
- IsBlocked: Fast boolean check for block status
Key architectural decisions:
- Write-forward pattern: All mutations go through PDS first
- Race condition fix: Removed preemptive existence check, rely on PDS
duplicate detection + repository ON CONFLICT handling
- User authentication: Uses user's access token (not instance token)
- Identifier resolution: Supports both DIDs and handles via
resolveCommunityIdentifier
Resolves race condition identified in PR review.
Add core domain support for community blocking feature:
- CommunityBlock struct with proper atProto metadata (RecordURI, RecordCID)
- ErrBlockNotFound error constant
- Repository interface methods: BlockCommunity, UnblockCommunity, GetBlock,
GetBlockByURI, ListBlockedCommunities, IsBlocked
- Service interface methods: BlockCommunity, UnblockCommunity,
GetBlockedCommunities, IsBlocked
This establishes the domain layer contracts that will be implemented
in subsequent commits following clean architecture principles.