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}