A community based topic aggregation platform built on atproto
1package comments
2
3import (
4 "time"
5)
6
7// Comment represents a comment in the AppView database
8// Comments are indexed from the firehose after being written to user repositories
9type Comment struct {
10 ID int64 `json:"id" db:"id"`
11 URI string `json:"uri" db:"uri"`
12 CID string `json:"cid" db:"cid"`
13 RKey string `json:"rkey" db:"rkey"`
14 CommenterDID string `json:"commenterDid" db:"commenter_did"`
15
16 // Author info (hydrated from users table for view building)
17 // Only populated by ListByParentWithHotRank, not persisted in comments table
18 CommenterHandle string `json:"commenterHandle,omitempty" db:"-"`
19
20 // Threading (reply references)
21 RootURI string `json:"rootUri" db:"root_uri"`
22 RootCID string `json:"rootCid" db:"root_cid"`
23 ParentURI string `json:"parentUri" db:"parent_uri"`
24 ParentCID string `json:"parentCid" db:"parent_cid"`
25
26 // Content
27 Content string `json:"content" db:"content"`
28 ContentFacets *string `json:"contentFacets,omitempty" db:"content_facets"`
29 Embed *string `json:"embed,omitempty" db:"embed"`
30 ContentLabels *string `json:"labels,omitempty" db:"content_labels"`
31 Langs []string `json:"langs,omitempty" db:"langs"`
32
33 // Timestamps
34 CreatedAt time.Time `json:"createdAt" db:"created_at"`
35 IndexedAt time.Time `json:"indexedAt" db:"indexed_at"`
36 DeletedAt *time.Time `json:"deletedAt,omitempty" db:"deleted_at"`
37
38 // Stats (denormalized for performance)
39 UpvoteCount int `json:"upvoteCount" db:"upvote_count"`
40 DownvoteCount int `json:"downvoteCount" db:"downvote_count"`
41 Score int `json:"score" db:"score"`
42 ReplyCount int `json:"replyCount" db:"reply_count"`
43}
44
45// CommentRecord represents the atProto record structure indexed from Jetstream
46// This is the data structure that gets stored in the user's repository
47// Matches social.coves.feed.comment lexicon
48type CommentRecord struct {
49 Type string `json:"$type"`
50 Reply ReplyRef `json:"reply"`
51 Content string `json:"content"`
52 Facets []interface{} `json:"facets,omitempty"`
53 Embed map[string]interface{} `json:"embed,omitempty"`
54 Langs []string `json:"langs,omitempty"`
55 Labels *SelfLabels `json:"labels,omitempty"`
56 CreatedAt string `json:"createdAt"`
57}
58
59// ReplyRef represents the threading structure from the comment lexicon
60// Root always points to the original post, parent points to the immediate parent
61type ReplyRef struct {
62 Root StrongRef `json:"root"`
63 Parent StrongRef `json:"parent"`
64}
65
66// StrongRef represents a strong reference to a record (URI + CID)
67// Matches com.atproto.repo.strongRef
68type StrongRef struct {
69 URI string `json:"uri"`
70 CID string `json:"cid"`
71}
72
73// SelfLabels represents self-applied content labels per com.atproto.label.defs#selfLabels
74// This is the structured format used in atProto for content warnings
75type SelfLabels struct {
76 Values []SelfLabel `json:"values"`
77}
78
79// SelfLabel represents a single label value per com.atproto.label.defs#selfLabel
80// Neg is optional and negates the label when true
81type SelfLabel struct {
82 Val string `json:"val"` // Required: label value (max 128 chars)
83 Neg *bool `json:"neg,omitempty"` // Optional: negates the label if true
84}