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.
E2E Tests (3 new test cases):
- Block via XRPC endpoint: Full flow from HTTP → PDS → Jetstream → AppView
- Unblock via XRPC endpoint: Complete unblock flow with DELETE event
- Block fails without authentication: Validates auth requirement (401)
Each E2E test verifies:
✓ XRPC endpoint responds correctly
✓ Record created/deleted on PDS
✓ Jetstream consumer indexes event
✓ AppView database state updated
Unit Test Updates:
- Added 6 mock methods to mockCommunityRepo for blocking operations
- Ensures service layer tests compile and pass
All tests follow existing E2E patterns (subscribe/unsubscribe) for
consistency.
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.