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.
This commit migrates the vote lexicon to align with atProto conventions and
fixes several pre-existing bugs discovered during the migration.
## Main Changes
1. **Namespace Migration**: social.coves.interaction.vote → social.coves.feed.vote
- Follows Bluesky's pattern (app.bsky.feed.like)
- All feed interactions now in consistent namespace
- Updated all code references, tests, and Jetstream consumers
2. **atProto Best Practices** (per https://github.com/bluesky-social/atproto/discussions/4245):
- Changed `enum` to `knownValues` for future extensibility
- Use standard `com.atproto.repo.strongRef` instead of custom definition
- Enhanced description to mention authentication requirement
3. **Added Core atProto Schemas**:
- com.atproto.repo.strongRef.json
- com.atproto.label.defs.json
- Required for lexicon validation, standard practice for Go projects
## Bug Fixes
1. **Foreign Key Constraint Mismatch** (013_create_votes_table.sql):
- REMOVED FK constraint on voter_did → users(did)
- Code comments stated FK was removed, but migration still had it
- Tests expected no FK for out-of-order Jetstream indexing
- Now consistent: votes can be indexed before users
2. **Invalid Test Data** (tests/lexicon-test-data/feed/vote-valid.json):
- Missing required `direction` field
- `subject` was string instead of strongRef object
- Now valid: includes direction, proper strongRef with uri+cid
## Files Changed
**Lexicon & Test Data:**
- Moved: internal/atproto/lexicon/social/coves/{interaction → feed}/vote.json
- Moved: tests/lexicon-test-data/{interaction → feed}/vote-valid.json
- Added: internal/atproto/lexicon/com/atproto/repo/strongRef.json
- Added: internal/atproto/lexicon/com/atproto/label/defs.json
**Code (10 files updated):**
- internal/validation/lexicon.go
- internal/validation/lexicon_test.go
- internal/atproto/jetstream/vote_consumer.go
- cmd/server/main.go (Jetstream URL)
- internal/db/postgres/vote_repo_test.go (12 test URIs)
- internal/db/migrations/013_create_votes_table.sql
## Tests
✅ All vote repository tests passing (11 tests)
✅ Validation tests passing with new lexicon path
✅ TestVoteRepo_Create_VoterNotFound passing (validates FK removal)
✅ Lexicon schema validation passing
✅ No regressions introduced
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Updates remaining documentation, code references, and configuration
to reflect the lexicon namespace migration and labels changes.
Changes:
- Update docs (PRDs, CLAUDE.md) with new namespace references
- Update API routes and handlers for community.post
- Update aggregator client references
- Update feed system documentation
- Remove deprecated interaction/comment schemas (moved to feed/comment)
No functional changes - documentation and reference updates only.
Updates all tests to use new social.coves.community.post namespace and
structured com.atproto.label.defs#selfLabels format.
Changes:
- Update test data to match new lexicon schema (author field, facets, etc)
- Update integration tests to use SelfLabels{Values: []SelfLabel{...}}
- Update vote_repo_test to use new namespace
- Update post creation tests for label validation
- Update E2E tests for community post namespace
All lexicon validation tests passing (64 pass, 2 skip for defs files).
All integration tests passing with JSONB label storage.
Migrates content_labels column from TEXT[] to JSONB to preserve full
com.atproto.label.defs#selfLabels structure including the optional 'neg' field.
Changes:
- Migration 015: TEXT[] → JSONB with data conversion function
- Convert existing {nsfw,spoiler} to {"values":[{"val":"nsfw"},{"val":"spoiler"}]}
- Update post_repo to store/retrieve full JSON blob (no flattening)
- Update feed repos to deserialize JSONB directly
- Remove pq.StringArray usage from all repositories
Before: TEXT[] storage lost 'neg' field and future extensions
After: JSONB preserves complete selfLabels structure with no data loss
Migration uses temporary PL/pgSQL function to handle conversion safely.
Rollback migration converts back to TEXT[] (lossy - drops 'neg' field).
Implements proper atproto label structure with optional 'neg' field for negating labels.
This fixes client-supplied labels being dropped and ensures full round-trip compatibility.
Changes:
- Add SelfLabels and SelfLabel structs per com.atproto.label.defs spec
- SelfLabel includes Val (required) and Neg (optional bool pointer) fields
- Update CreatePostRequest.Labels from []string to *SelfLabels
- Update PostRecord.Labels to structured format
- Update validation logic to iterate over Labels.Values
- Update jetstream consumer to use structured labels
Before: Labels were []string, breaking in 3 ways:
1. Client-supplied structured labels ignored (JSON decoder drops object)
2. PDS rejects unknown contentLabels array field
3. Jetstream consumer marshals incorrectly
After: Full com.atproto.label.defs#selfLabels support with neg field preservation.