A community based topic aggregation platform built on atproto
1package votes 2 3import ( 4 "context" 5 "strings" 6) 7 8// SubjectExistsFunc is a function type that checks if a subject exists 9type SubjectExistsFunc func(ctx context.Context, uri string) (bool, error) 10 11// CompositeSubjectValidator validates subjects by checking both posts and comments 12type CompositeSubjectValidator struct { 13 postExists SubjectExistsFunc 14 commentExists SubjectExistsFunc 15} 16 17// NewCompositeSubjectValidator creates a validator that checks both posts and comments 18// Pass nil for either function to skip validation for that type 19func NewCompositeSubjectValidator(postExists, commentExists SubjectExistsFunc) *CompositeSubjectValidator { 20 return &CompositeSubjectValidator{ 21 postExists: postExists, 22 commentExists: commentExists, 23 } 24} 25 26// SubjectExists checks if a post or comment exists at the given URI 27// Determines type from the collection in the URI (e.g., social.coves.feed.post vs social.coves.feed.comment) 28func (v *CompositeSubjectValidator) SubjectExists(ctx context.Context, uri string) (bool, error) { 29 // Parse collection from AT-URI: at://did/collection/rkey 30 // Example: at://did:plc:xxx/social.coves.feed.post/abc123 31 if strings.Contains(uri, "/social.coves.feed.post/") { 32 if v.postExists != nil { 33 return v.postExists(ctx, uri) 34 } 35 // If no post checker, assume exists (for testing) 36 return true, nil 37 } 38 39 if strings.Contains(uri, "/social.coves.feed.comment/") { 40 if v.commentExists != nil { 41 return v.commentExists(ctx, uri) 42 } 43 // If no comment checker, assume exists (for testing) 44 return true, nil 45 } 46 47 // Unknown collection type - could be from another app 48 // For now, allow voting on unknown types (future-proofing) 49 return true, nil 50}