A community based topic aggregation platform built on atproto
1package comments
2
3import (
4 "context"
5 "database/sql"
6)
7
8// Repository defines the data access interface for comments
9// Used by Jetstream consumer to index comments from firehose
10//
11// Architecture: Comments are written directly by clients to their PDS using
12// com.atproto.repo.createRecord/updateRecord/deleteRecord. This AppView indexes
13// comments from Jetstream for aggregation and querying.
14type Repository interface {
15 // Create inserts a new comment into the AppView database
16 // Called by Jetstream consumer after comment is created on PDS
17 // Idempotent: ON CONFLICT DO NOTHING for duplicate URIs
18 Create(ctx context.Context, comment *Comment) error
19
20 // Update modifies an existing comment's content fields
21 // Called by Jetstream consumer after comment is updated on PDS
22 // Preserves vote counts and created_at timestamp
23 Update(ctx context.Context, comment *Comment) error
24
25 // GetByURI retrieves a comment by its AT-URI
26 // Used for Jetstream UPDATE/DELETE operations and queries
27 GetByURI(ctx context.Context, uri string) (*Comment, error)
28
29 // Delete soft-deletes a comment (sets deleted_at)
30 // Called by Jetstream consumer after comment is deleted from PDS
31 // Deprecated: Use SoftDeleteWithReason for new code to preserve thread structure
32 Delete(ctx context.Context, uri string) error
33
34 // SoftDeleteWithReason performs a soft delete that blanks content but preserves thread structure
35 // This allows deleted comments to appear as "[deleted]" placeholders in thread views
36 // reason: "author" (user deleted) or "moderator" (mod removed)
37 // deletedByDID: DID of the actor who performed the deletion
38 SoftDeleteWithReason(ctx context.Context, uri, reason, deletedByDID string) error
39
40 // ListByRoot retrieves all comments in a thread (flat)
41 // Used for fetching entire comment threads on posts
42 ListByRoot(ctx context.Context, rootURI string, limit, offset int) ([]*Comment, error)
43
44 // ListByParent retrieves direct replies to a post or comment
45 // Used for building nested/threaded comment views
46 ListByParent(ctx context.Context, parentURI string, limit, offset int) ([]*Comment, error)
47
48 // CountByParent counts direct replies to a post or comment
49 // Used for showing reply counts in threading UI
50 CountByParent(ctx context.Context, parentURI string) (int, error)
51
52 // ListByCommenter retrieves all comments by a specific user
53 // Future: Used for user comment history
54 ListByCommenter(ctx context.Context, commenterDID string, limit, offset int) ([]*Comment, error)
55
56 // ListByParentWithHotRank retrieves direct replies to a post or comment with sorting and pagination
57 // Supports hot, top, and new sorting with cursor-based pagination
58 // Returns comments with author info hydrated and next page cursor
59 ListByParentWithHotRank(
60 ctx context.Context,
61 parentURI string,
62 sort string, // "hot", "top", "new"
63 timeframe string, // "hour", "day", "week", "month", "year", "all" (for "top" only)
64 limit int,
65 cursor *string,
66 ) ([]*Comment, *string, error)
67
68 // GetByURIsBatch retrieves multiple comments by their AT-URIs in a single query
69 // Returns map[uri]*Comment for efficient lookups
70 // Used for hydrating comment threads without N+1 queries
71 GetByURIsBatch(ctx context.Context, uris []string) (map[string]*Comment, error)
72
73 // GetVoteStateForComments retrieves the viewer's votes on a batch of comments
74 // Returns map[commentURI]*Vote for efficient lookups
75 // Future: Used when votes table is implemented
76 GetVoteStateForComments(ctx context.Context, viewerDID string, commentURIs []string) (map[string]interface{}, error)
77
78 // ListByParentsBatch retrieves direct replies to multiple parents in a single query
79 // Returns map[parentURI][]*Comment grouped by parent
80 // Used to prevent N+1 queries when loading nested replies
81 // Limits results per parent to avoid memory exhaustion
82 ListByParentsBatch(
83 ctx context.Context,
84 parentURIs []string,
85 sort string,
86 limitPerParent int,
87 ) (map[string][]*Comment, error)
88}
89
90// RepositoryTx provides transaction-aware operations for consumers that need atomicity
91// Used by Jetstream consumer to perform atomic delete + count updates
92// Implementations that support transactions should also implement this interface
93type RepositoryTx interface {
94 // SoftDeleteWithReasonTx performs a soft delete within a transaction
95 // If tx is nil, executes directly against the database
96 // Returns rows affected count for callers that need to check idempotency
97 // reason: must be DeletionReasonAuthor or DeletionReasonModerator
98 // deletedByDID: DID of the actor who performed the deletion
99 SoftDeleteWithReasonTx(ctx context.Context, tx *sql.Tx, uri, reason, deletedByDID string) (int64, error)
100}