feat: share post to other apps

This commit is contained in:
Krispire Admin
2026-05-31 08:05:02 +05:30
parent 05b61cef09
commit 0969887008
8 changed files with 313 additions and 14 deletions
+56
View File
@@ -228,6 +228,62 @@ func (r *PostRepo) collectPosts(ctx context.Context, total int, query string, ar
return posts, total, nil
}
// AddReshare records that `viewerID` reshared `postID`. Idempotent —
// repeated calls with the same pair are no-ops (the PRIMARY KEY makes
// the second insert a conflict, which we explicitly ignore). Returns
// nil on success regardless of whether a row was actually inserted.
func (r *PostRepo) AddReshare(ctx context.Context, postID, viewerID string) error {
const q = `
INSERT INTO post_reshares (post_id, user_id)
VALUES ($1, $2)
ON CONFLICT (post_id, user_id) DO NOTHING`
if _, err := r.pg.Pool.Exec(ctx, q, postID, viewerID); err != nil {
return fmt.Errorf("add reshare: %w", err)
}
return nil
}
// RemoveReshare deletes the reshare relationship. Idempotent — deleting
// a row that doesn't exist returns nil rather than ErrPostNotFound,
// since "I'm not subscribed" is the desired end state either way.
func (r *PostRepo) RemoveReshare(ctx context.Context, postID, viewerID string) error {
const q = `DELETE FROM post_reshares WHERE post_id = $1 AND user_id = $2`
if _, err := r.pg.Pool.Exec(ctx, q, postID, viewerID); err != nil {
return fmt.Errorf("remove reshare: %w", err)
}
return nil
}
// ReshareStatesFor returns a set of post IDs that `viewerID` has
// reshared, filtered to the supplied `postIDs`. Same shape as
// ImagesFor — one batched query so a feed render doesn't N+1 the
// reshare table. Returns an empty map when `viewerID` is "" (anonymous
// viewer can't have reshared anything).
func (r *PostRepo) ReshareStatesFor(ctx context.Context, viewerID string, postIDs []string) (map[string]bool, error) {
out := make(map[string]bool, len(postIDs))
if viewerID == "" || len(postIDs) == 0 {
return out, nil
}
rows, err := r.pg.Pool.Query(ctx, `
SELECT post_id
FROM post_reshares
WHERE user_id = $1 AND post_id = ANY($2)`,
viewerID, postIDs,
)
if err != nil {
return nil, fmt.Errorf("query reshare states: %w", err)
}
defer rows.Close()
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
return nil, fmt.Errorf("scan reshare state: %w", err)
}
out[id] = true
}
return out, rows.Err()
}
// ImagesFor returns a map post_id → [images...] for a batch of post IDs in
// a single query so we don't N+1 the feed endpoint. Exported because the
// CollectionService needs to hydrate images onto posts that come back