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.
Remove all vote write endpoints from the AppView. Vote creation and
deletion are now performed directly by clients at their PDS using
standard atProto repo operations.
Removed:
- POST /xrpc/social.coves.interaction.createVote handler
- POST /xrpc/social.coves.interaction.deleteVote handler
- Vote route registration
- E2E tests for write-forward pattern (~800 lines)
Endpoints now return 404. Clients should use:
- com.atproto.repo.createRecord (collection: social.coves.interaction.vote)
- com.atproto.repo.deleteRecord (extract rkey from vote URI)
The AppView indexes votes from Jetstream for aggregation and querying.
Deleted files:
- internal/api/handlers/vote/create_vote.go
- internal/api/handlers/vote/delete_vote.go
- internal/api/routes/vote.go
- tests/integration/vote_e2e_test.go
Remove unused Service interface that declared CreateVote/DeleteVote
methods. These write operations are no longer supported by the AppView.
Remove request/response types that were only used by deleted handlers:
- CreateVoteRequest
- CreateVoteResponse
- DeleteVoteRequest
Keep only types needed for Jetstream indexing:
- Vote (AppView database model)
- VoteRecord (atProto record structure)
- StrongRef (AT-URI + CID reference)
- Repository interface (indexing operations)
Add architecture documentation explaining client-direct write pattern.
Before: 154 lines
After: 99 lines (36% reduction)
Delete write-forward service implementation (448 lines) and tests
(280 lines) that are no longer used after switching to client-direct
writes.
The service contained:
- CreateVote() - write-forward to user's PDS
- DeleteVote() - delete on user's PDS
- PDS write operations using DPoP-bound tokens (impossible)
These operations are now performed directly by clients at their PDS.
The AppView only indexes votes from Jetstream.
Deleted:
- internal/core/votes/service.go (448 lines)
- internal/core/votes/service_test.go (280 lines)
Add comprehensive documentation explaining why vote write-forward
endpoints were removed:
- OAuth DPoP tokens are cryptographically bound to client's private key
- Backend cannot create DPoP proofs (doesn't have the key)
- Solution: Clients write directly to their PDS using
com.atproto.repo.createRecord/deleteRecord
- AppView indexes votes from Jetstream for aggregation
Also documented future work needed for subscriptions and blocking.
See: docs/PRD_BACKLOG.md#oauth-dpop-token-architecture
- Document P0 blocker: DPoP token write-forward architecture issue
- Analyze correct client-direct-write pattern (following Bluesky)
- Add feed system implementation documentation
- Clean up CLAUDE.md whitespace
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- CovesClient.create_post() accepts optional title parameter
- Kagi aggregator now passes story titles to posts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add mobile testing targets to Makefile (adb port forwarding, ngrok)
- Fix PDS port configuration (3000→3001 for correct DID registration)
- Add AUTH_SKIP_VERIFY flag for local JWT development
- Add scripts for mobile port setup and ngrok tunnels
- Add bin/ to .gitignore for build artifacts
Enables USB-connected Android testing and iOS/WiFi testing via ngrok
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>