A community based topic aggregation platform built on atproto

docs: update PRDs to reflect subscription indexing completion

Updated PRD_COMMUNITIES.md:
- Moved subscription indexing from "Alpha Blockers" to "Completed" section
- Documented all 8 fixes implemented (collection name bug, contentVisibility,
production consumer, migration, atomic counts, DELETE ops, idempotency,
atProto compliance)
- Updated impact section: AppView indexing ✅, feed generation enabled ✅,
accurate subscriber counts ✅
- Added testing coverage: 13 integration tests, enhanced E2E tests
- Updated "Last Updated" date to 2025-10-16
- Added file references for all implementation components

Updated PRD_BACKLOG.md:
- Marked "Subscription Visibility Level (Feed Slider)" as ✅ COMPLETE
- Changed status from "P1: ALPHA BLOCKER" to "✅ DONE"
- Added completion date: 2025-10-16
- Documented complete solution with all files modified
- Listed impact: Users can now adjust feed volume per community

Impact on Alpha Launch:
- ✅ Critical alpha blocker resolved
- ✅ Feed generation infrastructure ready
- ✅ ContentVisibility (1-5 scale) fully implemented
- Remaining blocker: Community blocking feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+54 -35
docs
+24 -12
docs/PRD_BACKLOG.md
···
---
-
### Subscription Visibility Level (Feed Slider 1-5 Scale)
-
**Added:** 2025-10-15 | **Effort:** 4-6 hours | **Priority:** ALPHA BLOCKER
+
### ✅ Subscription Visibility Level (Feed Slider 1-5 Scale) - COMPLETE
+
**Added:** 2025-10-15 | **Completed:** 2025-10-16 | **Effort:** 1 day | **Status:** ✅ DONE
-
**Problem:** Users can't control how much content they see from each community. Lexicon has `contentVisibility` (1-5 scale) but code doesn't use it.
+
**Problem:** Users couldn't control how much content they see from each community. Lexicon had `contentVisibility` (1-5 scale) but code didn't use it.
-
**Solution:**
-
- Update subscribe handler to accept `contentVisibility` parameter (1-5, default 3)
-
- Store in subscription record on PDS
-
- Update feed generation to respect visibility level (beta work, but data structure needed now)
+
**Solution Implemented:**
+
- ✅ Updated subscribe handler to accept `contentVisibility` parameter (1-5, default 3)
+
- ✅ Store in subscription record on PDS (`social.coves.community.subscription`)
+
- ✅ Migration 008 adds `content_visibility` column to database with CHECK constraint
+
- ✅ Clamping at all layers (handler, service, consumer) for defense in depth
+
- ✅ Atomic subscriber count updates (SubscribeWithCount/UnsubscribeWithCount)
+
- ✅ Idempotent operations (safe for Jetstream event replays)
+
- ✅ Fixed critical collection name bug (was using wrong namespace)
+
- ✅ Production Jetstream consumer now running
+
- ✅ 13 comprehensive integration tests - all passing
-
**Code:**
-
- Lexicon: [subscription.json:28-34](../internal/atproto/lexicon/social/coves/actor/subscription.json#L28-L34) ✅ Ready
-
- Handler: [community/subscribe.go](../internal/api/handlers/community/subscribe.go) - Add parameter
-
- Service: [communities/service.go:373-376](../internal/core/communities/service.go#L373-L376) - Add to record
+
**Files Modified:**
+
- Lexicon: [subscription.json](../internal/atproto/lexicon/social/coves/community/subscription.json) ✅ Updated to atProto conventions
+
- Handler: [community/subscribe.go](../internal/api/handlers/community/subscribe.go) ✅ Accepts contentVisibility
+
- Service: [communities/service.go](../internal/core/communities/service.go) ✅ Clamps and passes to PDS
+
- Consumer: [community_consumer.go](../internal/atproto/jetstream/community_consumer.go) ✅ Extracts and indexes
+
- Repository: [community_repo_subscriptions.go](../internal/db/postgres/community_repo_subscriptions.go) ✅ All queries updated
+
- Migration: [008_add_content_visibility_to_subscriptions.sql](../internal/db/migrations/008_add_content_visibility_to_subscriptions.sql) ✅ Schema changes
+
- Tests: [subscription_indexing_test.go](../tests/integration/subscription_indexing_test.go) ✅ Comprehensive coverage
-
**Impact:** Without this, users have no way to adjust feed volume per community (key feature from DOMAIN_KNOWLEDGE.md)
+
**Documentation:** See [IMPLEMENTATION_SUBSCRIPTION_INDEXING.md](../docs/IMPLEMENTATION_SUBSCRIPTION_INDEXING.md) for full details
+
+
**Impact:** ✅ Users can now adjust feed volume per community (key feature from DOMAIN_KNOWLEDGE.md enabled)
---
+30 -23
docs/PRD_COMMUNITIES.md
···
**Status:** In Development
**Owner:** Platform Team
-
**Last Updated:** 2025-10-10
+
**Last Updated:** 2025-10-16
## Overview
···
## ⚠️ Alpha Blockers (Must Complete Before Alpha Launch)
### Critical Missing Features
-
- [ ] **Subscription Visibility Level (1-5 Scale):** Implement feed slider from DOMAIN_KNOWLEDGE.md
-
- Lexicon: ✅ Ready ([subscription.json:28-34](internal/atproto/lexicon/social/coves/actor/subscription.json))
-
- Service: ❌ Not using `contentVisibility` field
-
- Handler: ❌ Subscribe endpoint doesn't accept/store visibility level
-
- **Impact:** Users can't control how much content they see from each community
-
- [ ] **Community Blocking:** Users can block communities from their feeds
- Lexicon: ❌ Need new record type (extend `social.coves.actor.block` or create new)
- Service: ❌ No implementation (`BlockCommunity()` / `UnblockCommunity()`)
···
- Repository: ❌ No methods
- **Impact:** Users have no way to hide unwanted communities
-
### Critical Infrastructure (BLOCKING)
-
- [ ] **⚠️ Subscription Indexing - NO PRODUCTION CONSUMER**
-
- **Status:** Subscriptions write to PDS but are NEVER indexed in AppView
-
- **Root Cause:** `CommunityEventConsumer` only runs in tests, not in production
+
### ✅ Critical Infrastructure - RESOLVED (2025-10-16)
+
- [x] **✅ Subscription Indexing & ContentVisibility - COMPLETE**
+
- **Status:** Subscriptions now fully indexed in AppView with feed slider support
+
- **Completed:** 2025-10-16
+
- **What Was Fixed:**
+
1. ✅ Fixed critical collection name bug (`social.coves.actor.subscription` → `social.coves.community.subscription`)
+
2. ✅ Implemented ContentVisibility (1-5 slider) across all layers (handler, service, consumer, repository)
+
3. ✅ Production Jetstream consumer now running ([cmd/server/main.go:220-243](cmd/server/main.go#L220-L243))
+
4. ✅ Migration 008 adds `content_visibility` column with defaults and constraints
+
5. ✅ Atomic subscriber count updates (SubscribeWithCount/UnsubscribeWithCount)
+
6. ✅ DELETE operations properly handled (unsubscribe indexing)
+
7. ✅ Idempotent operations (safe for Jetstream event replays)
+
8. ✅ atProto naming compliance: singular namespace + `subject` field
- **Impact:**
-
- ❌ Users CAN subscribe/unsubscribe (writes to their PDS repo) ✅
-
- ❌ AppView has NO KNOWLEDGE of subscriptions (not consuming from Jetstream)
-
- ❌ Cannot query user's subscriptions (data doesn't exist in AppView)
-
- ❌ Feed generation impossible (don't know who's subscribed to what)
-
- **Required Fixes:**
-
1. Start `CommunityEventConsumer` in production ([cmd/server/main.go](cmd/server/main.go))
-
2. Subscribe to local Jetstream: `ws://localhost:6008/subscribe?wantedCollections=social.coves.community.subscribe`
-
3. Fix unsubscribe handler - should handle `delete` operation on `social.coves.community.subscribe`, NOT a separate collection
-
4. Remove incorrect `social.coves.community.unsubscribe` case ([community_consumer.go:40](internal/atproto/jetstream/community_consumer.go#L40))
+
- ✅ Users CAN subscribe/unsubscribe (writes to their PDS repo)
+
- ✅ AppView INDEXES subscriptions from Jetstream in real-time
+
- ✅ Can query user's subscriptions (data persisted with contentVisibility)
+
- ✅ Feed generation ENABLED (know who's subscribed with visibility preferences)
+
- ✅ Subscriber counts accurate (atomic updates)
+
- **Testing:**
+
- ✅ 13 comprehensive integration tests (subscription_indexing_test.go) - ALL PASSING
+
- ✅ Enhanced E2E tests verify complete flow (HTTP → PDS → Jetstream → AppView)
+
- ✅ ContentVisibility clamping tested (0→1, 10→5, defaults to 3)
+
- ✅ Idempotency verified (duplicate events handled gracefully)
- **Files:**
-
- Consumer: [internal/atproto/jetstream/community_consumer.go](internal/atproto/jetstream/community_consumer.go) (exists, needs fixes)
-
- Server: [cmd/server/main.go](cmd/server/main.go) (needs to instantiate consumer)
-
- **See:** Issue discovered 2025-10-16 during OAuth user token implementation
+
- Implementation Doc: [docs/IMPLEMENTATION_SUBSCRIPTION_INDEXING.md](docs/IMPLEMENTATION_SUBSCRIPTION_INDEXING.md)
+
- Lexicon: [internal/atproto/lexicon/social/coves/community/subscription.json](internal/atproto/lexicon/social/coves/community/subscription.json)
+
- Consumer: [internal/atproto/jetstream/community_consumer.go](internal/atproto/jetstream/community_consumer.go)
+
- Connector: [internal/atproto/jetstream/community_jetstream_connector.go](internal/atproto/jetstream/community_jetstream_connector.go)
+
- Migration: [internal/db/migrations/008_add_content_visibility_to_subscriptions.sql](internal/db/migrations/008_add_content_visibility_to_subscriptions.sql)
+
- Tests: [tests/integration/subscription_indexing_test.go](tests/integration/subscription_indexing_test.go)
### Critical Security (High Priority)
- [x] **OAuth Authentication:** ✅ COMPLETE - User access tokens flow end-to-end