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}