A community based topic aggregation platform built on atproto
1package communities
2
3import (
4 "time"
5)
6
7// Community represents a Coves community indexed from the firehose
8// Communities are federated, instance-scoped forums built on atProto
9type Community struct {
10 ID int `json:"id" db:"id"`
11 DID string `json:"did" db:"did"` // Permanent community identifier (did:plc:xxx)
12 Handle string `json:"handle" db:"handle"` // Scoped handle (!gaming@coves.social)
13 Name string `json:"name" db:"name"` // Short name (local part of handle)
14 DisplayName string `json:"displayName" db:"display_name"` // Display name for UI
15 Description string `json:"description" db:"description"` // Community description
16 DescriptionFacets []byte `json:"descriptionFacets,omitempty" db:"description_facets"` // Rich text annotations (JSONB)
17
18 // Media
19 AvatarCID string `json:"avatarCid,omitempty" db:"avatar_cid"` // CID of avatar image
20 BannerCID string `json:"bannerCid,omitempty" db:"banner_cid"` // CID of banner image
21
22 // Ownership
23 OwnerDID string `json:"ownerDid" db:"owner_did"` // Instance DID in V1, community DID in V3
24 CreatedByDID string `json:"createdByDid" db:"created_by_did"` // User who created the community
25 HostedByDID string `json:"hostedByDid" db:"hosted_by_did"` // Instance hosting this community
26
27 // Visibility & Federation
28 Visibility string `json:"visibility" db:"visibility"` // public, unlisted, private
29 AllowExternalDiscovery bool `json:"allowExternalDiscovery" db:"allow_external_discovery"` // Can other instances index?
30
31 // Moderation
32 ModerationType string `json:"moderationType,omitempty" db:"moderation_type"` // moderator, sortition
33 ContentWarnings []string `json:"contentWarnings,omitempty" db:"content_warnings"` // NSFW, violence, spoilers
34
35 // Statistics (cached counts)
36 MemberCount int `json:"memberCount" db:"member_count"`
37 SubscriberCount int `json:"subscriberCount" db:"subscriber_count"`
38 PostCount int `json:"postCount" db:"post_count"`
39
40 // Federation metadata (future: Lemmy interop)
41 FederatedFrom string `json:"federatedFrom,omitempty" db:"federated_from"` // lemmy, coves
42 FederatedID string `json:"federatedId,omitempty" db:"federated_id"` // Original ID on source platform
43
44 // Timestamps
45 CreatedAt time.Time `json:"createdAt" db:"created_at"`
46 UpdatedAt time.Time `json:"updatedAt" db:"updated_at"`
47
48 // AT-Proto metadata
49 RecordURI string `json:"recordUri,omitempty" db:"record_uri"` // AT-URI of community profile record
50 RecordCID string `json:"recordCid,omitempty" db:"record_cid"` // CID of community profile record
51}
52
53// Subscription represents a lightweight feed follow (user subscribes to see posts)
54type Subscription struct {
55 ID int `json:"id" db:"id"`
56 UserDID string `json:"userDid" db:"user_did"`
57 CommunityDID string `json:"communityDid" db:"community_did"`
58 SubscribedAt time.Time `json:"subscribedAt" db:"subscribed_at"`
59
60 // AT-Proto metadata (subscription is a record in user's repo)
61 RecordURI string `json:"recordUri,omitempty" db:"record_uri"`
62 RecordCID string `json:"recordCid,omitempty" db:"record_cid"`
63}
64
65// Membership represents active participation with reputation tracking
66type Membership struct {
67 ID int `json:"id" db:"id"`
68 UserDID string `json:"userDid" db:"user_did"`
69 CommunityDID string `json:"communityDid" db:"community_did"`
70 ReputationScore int `json:"reputationScore" db:"reputation_score"` // Gained through participation
71 ContributionCount int `json:"contributionCount" db:"contribution_count"` // Posts + comments + actions
72 JoinedAt time.Time `json:"joinedAt" db:"joined_at"`
73 LastActiveAt time.Time `json:"lastActiveAt" db:"last_active_at"`
74
75 // Moderation status
76 IsBanned bool `json:"isBanned" db:"is_banned"`
77 IsModerator bool `json:"isModerator" db:"is_moderator"`
78}
79
80// ModerationAction represents a moderation action taken against a community
81type ModerationAction struct {
82 ID int `json:"id" db:"id"`
83 CommunityDID string `json:"communityDid" db:"community_did"`
84 Action string `json:"action" db:"action"` // delist, quarantine, remove
85 Reason string `json:"reason,omitempty" db:"reason"`
86 InstanceDID string `json:"instanceDid" db:"instance_did"` // Which instance took this action
87 Broadcast bool `json:"broadcast" db:"broadcast"` // Share signal with network?
88 CreatedAt time.Time `json:"createdAt" db:"created_at"`
89 ExpiresAt *time.Time `json:"expiresAt,omitempty" db:"expires_at"` // Optional: temporary moderation
90}
91
92// CreateCommunityRequest represents input for creating a new community
93type CreateCommunityRequest struct {
94 Name string `json:"name"`
95 DisplayName string `json:"displayName,omitempty"`
96 Description string `json:"description"`
97 AvatarBlob []byte `json:"avatarBlob,omitempty"` // Raw image data
98 BannerBlob []byte `json:"bannerBlob,omitempty"` // Raw image data
99 Rules []string `json:"rules,omitempty"`
100 Categories []string `json:"categories,omitempty"`
101 Language string `json:"language,omitempty"`
102 Visibility string `json:"visibility"` // public, unlisted, private
103 AllowExternalDiscovery bool `json:"allowExternalDiscovery"`
104 CreatedByDID string `json:"createdByDid"` // User creating the community
105 HostedByDID string `json:"hostedByDid"` // Instance hosting the community
106}
107
108// UpdateCommunityRequest represents input for updating community metadata
109type UpdateCommunityRequest struct {
110 CommunityDID string `json:"communityDid"`
111 UpdatedByDID string `json:"updatedByDid"` // User making the update (for authorization)
112 DisplayName *string `json:"displayName,omitempty"`
113 Description *string `json:"description,omitempty"`
114 AvatarBlob []byte `json:"avatarBlob,omitempty"`
115 BannerBlob []byte `json:"bannerBlob,omitempty"`
116 Visibility *string `json:"visibility,omitempty"`
117 AllowExternalDiscovery *bool `json:"allowExternalDiscovery,omitempty"`
118 ModerationType *string `json:"moderationType,omitempty"`
119 ContentWarnings []string `json:"contentWarnings,omitempty"`
120}
121
122// ListCommunitiesRequest represents query parameters for listing communities
123type ListCommunitiesRequest struct {
124 Limit int `json:"limit"`
125 Offset int `json:"offset"`
126 Visibility string `json:"visibility,omitempty"` // Filter by visibility
127 HostedBy string `json:"hostedBy,omitempty"` // Filter by hosting instance
128 SortBy string `json:"sortBy,omitempty"` // created_at, member_count, post_count
129 SortOrder string `json:"sortOrder,omitempty"` // asc, desc
130}
131
132// SearchCommunitiesRequest represents query parameters for searching communities
133type SearchCommunitiesRequest struct {
134 Query string `json:"query"` // Search term
135 Limit int `json:"limit"`
136 Offset int `json:"offset"`
137 Visibility string `json:"visibility,omitempty"` // Filter by visibility
138}