A community based topic aggregation platform built on atproto
1package posts 2 3import ( 4 "time" 5) 6 7// SelfLabels represents self-applied content labels per com.atproto.label.defs#selfLabels 8// This is the structured format used in atProto for content warnings 9type SelfLabels struct { 10 Values []SelfLabel `json:"values"` 11} 12 13// SelfLabel represents a single label value per com.atproto.label.defs#selfLabel 14// Neg is optional and negates the label when true 15type SelfLabel struct { 16 Neg *bool `json:"neg,omitempty"` 17 Val string `json:"val"` 18} 19 20// Post represents a post in the AppView database 21// Posts are indexed from the firehose after being written to community repositories 22type Post struct { 23 CreatedAt time.Time `json:"createdAt" db:"created_at"` 24 IndexedAt time.Time `json:"indexedAt" db:"indexed_at"` 25 EditedAt *time.Time `json:"editedAt,omitempty" db:"edited_at"` 26 Embed *string `json:"embed,omitempty" db:"embed"` 27 DeletedAt *time.Time `json:"deletedAt,omitempty" db:"deleted_at"` 28 ContentLabels *string `json:"labels,omitempty" db:"content_labels"` 29 Title *string `json:"title,omitempty" db:"title"` 30 Content *string `json:"content,omitempty" db:"content"` 31 ContentFacets *string `json:"contentFacets,omitempty" db:"content_facets"` 32 CID string `json:"cid" db:"cid"` 33 CommunityDID string `json:"communityDid" db:"community_did"` 34 RKey string `json:"rkey" db:"rkey"` 35 URI string `json:"uri" db:"uri"` 36 AuthorDID string `json:"authorDid" db:"author_did"` 37 ID int64 `json:"id" db:"id"` 38 UpvoteCount int `json:"upvoteCount" db:"upvote_count"` 39 DownvoteCount int `json:"downvoteCount" db:"downvote_count"` 40 Score int `json:"score" db:"score"` 41 CommentCount int `json:"commentCount" db:"comment_count"` 42} 43 44// CreatePostRequest represents input for creating a new post 45// Matches social.coves.community.post.create lexicon input schema 46type CreatePostRequest struct { 47 OriginalAuthor interface{} `json:"originalAuthor,omitempty"` 48 FederatedFrom interface{} `json:"federatedFrom,omitempty"` 49 Location interface{} `json:"location,omitempty"` 50 Title *string `json:"title,omitempty"` 51 Content *string `json:"content,omitempty"` 52 Embed map[string]interface{} `json:"embed,omitempty"` 53 ThumbnailURL *string `json:"thumbnailUrl,omitempty"` 54 Labels *SelfLabels `json:"labels,omitempty"` 55 Community string `json:"community"` 56 AuthorDID string `json:"authorDid"` 57 Facets []interface{} `json:"facets,omitempty"` 58} 59 60// CreatePostResponse represents the response from creating a post 61// Matches social.coves.community.post.create lexicon output schema 62type CreatePostResponse struct { 63 URI string `json:"uri"` // AT-URI of created post 64 CID string `json:"cid"` // CID of created post 65} 66 67// PostRecord represents the actual atProto record structure written to PDS 68// This is the data structure that gets stored in the community's repository 69type PostRecord struct { 70 OriginalAuthor interface{} `json:"originalAuthor,omitempty"` 71 FederatedFrom interface{} `json:"federatedFrom,omitempty"` 72 Location interface{} `json:"location,omitempty"` 73 Title *string `json:"title,omitempty"` 74 Content *string `json:"content,omitempty"` 75 Embed map[string]interface{} `json:"embed,omitempty"` 76 Labels *SelfLabels `json:"labels,omitempty"` 77 Type string `json:"$type"` 78 Community string `json:"community"` 79 Author string `json:"author"` 80 CreatedAt string `json:"createdAt"` 81 Facets []interface{} `json:"facets,omitempty"` 82} 83 84// PostView represents the full view of a post with all metadata 85// Matches social.coves.community.post.get#postView lexicon 86// Used in feeds and get endpoints 87type PostView struct { 88 IndexedAt time.Time `json:"indexedAt"` 89 CreatedAt time.Time `json:"createdAt"` 90 Record interface{} `json:"record,omitempty"` 91 Embed interface{} `json:"embed,omitempty"` 92 Language *string `json:"language,omitempty"` 93 EditedAt *time.Time `json:"editedAt,omitempty"` 94 Title *string `json:"title,omitempty"` 95 Text *string `json:"text,omitempty"` 96 Viewer *ViewerState `json:"viewer,omitempty"` 97 Author *AuthorView `json:"author"` 98 Stats *PostStats `json:"stats,omitempty"` 99 Community *CommunityRef `json:"community"` 100 RKey string `json:"rkey"` 101 CID string `json:"cid"` 102 URI string `json:"uri"` 103 TextFacets []interface{} `json:"textFacets,omitempty"` 104 UpvoteCount int `json:"-"` 105 DownvoteCount int `json:"-"` 106 Score int `json:"-"` 107 CommentCount int `json:"-"` 108} 109 110// AuthorView represents author information in post views 111type AuthorView struct { 112 DisplayName *string `json:"displayName,omitempty"` 113 Avatar *string `json:"avatar,omitempty"` 114 Reputation *int `json:"reputation,omitempty"` 115 DID string `json:"did"` 116 Handle string `json:"handle"` 117} 118 119// CommunityRef represents minimal community info in post views 120type CommunityRef struct { 121 Avatar *string `json:"avatar,omitempty"` 122 DID string `json:"did"` 123 Handle string `json:"handle"` 124 Name string `json:"name"` 125 PDSURL string `json:"-"` // Not exposed to API, used for blob URL transformation 126} 127 128// PostStats represents aggregated statistics 129type PostStats struct { 130 TagCounts map[string]int `json:"tagCounts,omitempty"` 131 Upvotes int `json:"upvotes"` 132 Downvotes int `json:"downvotes"` 133 Score int `json:"score"` 134 CommentCount int `json:"commentCount"` 135 ShareCount int `json:"shareCount,omitempty"` 136} 137 138// ViewerState represents the viewer's relationship with the post 139type ViewerState struct { 140 Vote *string `json:"vote,omitempty"` 141 VoteURI *string `json:"voteUri,omitempty"` 142 SavedURI *string `json:"savedUri,omitempty"` 143 Tags []string `json:"tags,omitempty"` 144 Saved bool `json:"saved"` 145}