A community based topic aggregation platform built on atproto
1package aggregators 2 3import "time" 4 5// Aggregator represents a service declaration record indexed from the firehose 6// Aggregators are autonomous services that can post content to communities after authorization 7// Following Bluesky's pattern: app.bsky.feed.generator and app.bsky.labeler.service 8type Aggregator struct { 9 DID string `json:"did" db:"did"` // Aggregator's DID (primary key) 10 DisplayName string `json:"displayName" db:"display_name"` // Human-readable name 11 Description string `json:"description,omitempty" db:"description"` // What the aggregator does 12 AvatarURL string `json:"avatarUrl,omitempty" db:"avatar_url"` // Optional avatar image URL 13 ConfigSchema []byte `json:"configSchema,omitempty" db:"config_schema"` // JSON Schema for configuration (JSONB) 14 MaintainerDID string `json:"maintainerDid,omitempty" db:"maintainer_did"` // Contact for support/issues 15 SourceURL string `json:"sourceUrl,omitempty" db:"source_url"` // Source code URL (transparency) 16 CommunitiesUsing int `json:"communitiesUsing" db:"communities_using"` // Auto-updated by trigger 17 PostsCreated int `json:"postsCreated" db:"posts_created"` // Auto-updated by trigger 18 CreatedAt time.Time `json:"createdAt" db:"created_at"` // When aggregator was created (from lexicon) 19 IndexedAt time.Time `json:"indexedAt" db:"indexed_at"` // When we indexed this record 20 RecordURI string `json:"recordUri,omitempty" db:"record_uri"` // at://did/social.coves.aggregator.service/self 21 RecordCID string `json:"recordCid,omitempty" db:"record_cid"` // Content hash 22} 23 24// Authorization represents a community's authorization for an aggregator 25// Stored in community's repository: at://community_did/social.coves.aggregator.authorization/{rkey} 26type Authorization struct { 27 ID int `json:"id" db:"id"` // Database ID 28 AggregatorDID string `json:"aggregatorDid" db:"aggregator_did"` // Which aggregator 29 CommunityDID string `json:"communityDid" db:"community_did"` // Which community 30 Enabled bool `json:"enabled" db:"enabled"` // Current status 31 Config []byte `json:"config,omitempty" db:"config"` // Aggregator-specific config (JSONB) 32 CreatedBy string `json:"createdBy,omitempty" db:"created_by"` // Moderator DID who enabled it 33 DisabledBy string `json:"disabledBy,omitempty" db:"disabled_by"` // Moderator DID who disabled it 34 CreatedAt time.Time `json:"createdAt" db:"created_at"` // When authorization was created 35 DisabledAt *time.Time `json:"disabledAt,omitempty" db:"disabled_at"` // When authorization was disabled (for modlog/audit) 36 IndexedAt time.Time `json:"indexedAt" db:"indexed_at"` // When we indexed this record 37 RecordURI string `json:"recordUri,omitempty" db:"record_uri"` // at://community_did/social.coves.aggregator.authorization/{rkey} 38 RecordCID string `json:"recordCid,omitempty" db:"record_cid"` // Content hash 39} 40 41// AggregatorPost represents tracking of posts created by aggregators 42// AppView-only table for rate limiting and statistics 43type AggregatorPost struct { 44 ID int `json:"id" db:"id"` 45 AggregatorDID string `json:"aggregatorDid" db:"aggregator_did"` 46 CommunityDID string `json:"communityDid" db:"community_did"` 47 PostURI string `json:"postUri" db:"post_uri"` 48 PostCID string `json:"postCid" db:"post_cid"` 49 CreatedAt time.Time `json:"createdAt" db:"created_at"` 50} 51 52// EnableAggregatorRequest represents input for enabling an aggregator in a community 53type EnableAggregatorRequest struct { 54 CommunityDID string `json:"communityDid"` // Which community (resolved from identifier) 55 AggregatorDID string `json:"aggregatorDid"` // Which aggregator 56 Config map[string]interface{} `json:"config,omitempty"` // Aggregator-specific configuration 57 EnabledByDID string `json:"enabledByDid"` // Moderator making the change (from JWT) 58 EnabledByToken string `json:"-"` // User's access token for PDS write 59} 60 61// DisableAggregatorRequest represents input for disabling an aggregator 62type DisableAggregatorRequest struct { 63 CommunityDID string `json:"communityDid"` // Which community (resolved from identifier) 64 AggregatorDID string `json:"aggregatorDid"` // Which aggregator 65 DisabledByDID string `json:"disabledByDid"` // Moderator making the change (from JWT) 66 DisabledByToken string `json:"-"` // User's access token for PDS write 67} 68 69// UpdateConfigRequest represents input for updating an aggregator's configuration 70type UpdateConfigRequest struct { 71 CommunityDID string `json:"communityDid"` // Which community (resolved from identifier) 72 AggregatorDID string `json:"aggregatorDid"` // Which aggregator 73 Config map[string]interface{} `json:"config"` // New configuration 74 UpdatedByDID string `json:"updatedByDid"` // Moderator making the change (from JWT) 75 UpdatedByToken string `json:"-"` // User's access token for PDS write 76} 77 78// GetServicesRequest represents query parameters for fetching aggregator details 79type GetServicesRequest struct { 80 DIDs []string `json:"dids"` // List of aggregator DIDs to fetch 81} 82 83// GetAuthorizationsRequest represents query parameters for listing authorizations 84type GetAuthorizationsRequest struct { 85 AggregatorDID string `json:"aggregatorDid"` // Which aggregator 86 EnabledOnly bool `json:"enabledOnly,omitempty"` // Only return enabled authorizations 87 Limit int `json:"limit"` 88 Offset int `json:"offset"` 89} 90 91// ListForCommunityRequest represents query parameters for listing aggregators for a community 92type ListForCommunityRequest struct { 93 CommunityDID string `json:"communityDid"` // Which community (resolved from identifier) 94 EnabledOnly bool `json:"enabledOnly,omitempty"` // Only return enabled aggregators 95 Limit int `json:"limit"` 96 Offset int `json:"offset"` 97}