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.
Production Jetstream Consumer:
- Start community consumer in main.go (not just tests)
- Subscribe to social.coves.community.subscription collection
- Handle CREATE, UPDATE, DELETE operations atomically
- Idempotent event handling (safe for Jetstream replays)
ContentVisibility Implementation (1-5 scale):
- Handler: Accept contentVisibility parameter (default: 3)
- Service: Clamp to valid range, write to PDS with user token
- Consumer: Extract from events, index in AppView
- Repository: Store with CHECK constraint, composite indexes
Fixed Critical Bugs:
- Use social.coves.community.subscription (not social.coves.actor.subscription)
- DELETE operations properly delete from PDS (unsubscribe bug fix)
- Atomic subscriber count updates (SubscribeWithCount/UnsubscribeWithCount)
Subscriber Count Management:
- Increment on CREATE, decrement on DELETE
- Atomic updates prevent race conditions
- Idempotent operations prevent double-counting
Impact:
- ✅ Subscriptions now indexed in AppView from Jetstream
- ✅ Feed generation enabled (know who subscribes to what)
- ✅ ContentVisibility stored for feed customization
- ✅ Subscriber counts accurate
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add atProto-compliant subscription lexicon following Bluesky conventions:
- Collection: social.coves.community.subscription (singular namespace)
- Field: subject (not community) per atProto graph record standards
- ContentVisibility: 1-5 scale for feed slider (default: 3)
Migration 008 adds content_visibility column:
- INTEGER with CHECK constraint (1-5 range)
- Indexed for feed generation queries
- Composite index (user_did, content_visibility) for performance
Follows atProto naming guidelines from bluesky-social/atproto#4245
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements user-scoped OAuth tokens for subscription operations, replacing
the deprecated OAuth/DPoP implementation with simplified JWT validation.
This merge includes 8 commits:
1. Remove deprecated OAuth implementation (2,738 lines)
2. Add JWT validation with JWKS fetching (845 lines)
3. Store user access tokens in middleware context
4. Update service to use user tokens for subscriptions
5. Update handlers to extract and forward tokens
6. Fix integration tests for new auth flow
7. Update server initialization
8. Update all documentation
Key Changes:
- ✅ Users can now subscribe/unsubscribe (proper PDS authorization)
- ✅ Simplified auth system (-615 net lines)
- ✅ All E2E tests passing with real authentication
- ✅ Comprehensive documentation (PRD_OAUTH.md)
Known Issue:
- Subscription indexing needs Jetstream consumer in production
(see docs/PRD_COMMUNITIES.md)
Net change: -615 lines (removed 3,166, added 2,551)
Documentation updates:
PRD_OAUTH.md (new):
- Document OAuth Phase 1 vs Phase 2 approach
- Explain why we simplified from DPoP to JWT-only
- Detail the new authentication flow
- Document known limitations and future work
PRD_COMMUNITIES.md:
- Mark OAuth authentication as complete (2025-10-16)
- Add new critical blocker: subscription indexing
- Document missing Jetstream consumer in production
- Update security section with completion status
PRD_BACKLOG.md:
- Mark user subscription auth issue as resolved
- Reorganize priorities post-OAuth completion
CLAUDE.md:
- Update builder guidelines
- Clarify security-first principles
- Add atProto authentication best practices
Server and infrastructure updates:
- Initialize auth middleware with JWT validation
- Remove OAuth route registration
- Update imports to use new auth package
- Clean up unused OAuth configuration
- Update PDS provisioning comments for clarity
- Fix repository query parameter ordering
These changes complete the migration from OAuth to JWT-based auth
throughout the application initialization and routing layers.
Update integration tests to pass access tokens:
- Pass accessToken to SubscribeToCommunity() calls
- Add comments explaining token usage in tests
- Verify subscribe/unsubscribe E2E flows with real auth
Tests now validate the complete authentication chain:
1. User authenticates with PDS (gets access token)
2. User makes request with Authorization header
3. Middleware validates JWT and stores token
4. Handler extracts token from context
5. Service uses token to write to user's PDS repo
6. PDS validates user owns the repository
7. Record successfully written
All E2E tests pass with real PDS authentication.