fix: feed repitition

This commit is contained in:
Krispire Admin
2026-06-14 00:18:11 +05:30
parent 8a2bdf945a
commit 2afbbfa0f2
6 changed files with 263 additions and 11 deletions
+20 -7
View File
@@ -219,14 +219,27 @@ func (r *PostRepo) ListByUser(ctx context.Context, userID string, limit, offset
// tier 0 — posts by people the viewer follows that they haven't liked yet
// tier 1 — everything else (followed-and-liked, followers', strangers')
//
// The viewer's own posts and anything involving a block (either direction)
// are excluded. The tier is computed in ORDER BY via correlated EXISTS, so no
// extra columns leak into scanPost. No total is computed (infinite scroll
// infers "more" from a full page); offset paging keeps it simple. At larger
// scale this would move to a precomputed fan-out / keyset cursor.
func (r *PostRepo) FeedForViewer(ctx context.Context, viewerID string, limit, offset int) ([]model.Post, error) {
// The viewer's own posts, anything involving a block (either direction), and
// any id in `exclude` (the already-served set) are filtered out. The tier is
// computed in ORDER BY via correlated EXISTS, so no extra columns leak into
// scanPost. No total is computed (infinite scroll infers "more" from a full
// page).
//
// With a non-empty `exclude` the caller drives pagination purely by exclusion
// (pass offset 0): since the tier depends on viewer state — liking a post
// moves it between tiers — an OFFSET would drift and repeat/skip rows, so the
// seen-set is the correct cursor. Without Redis, `exclude` is empty and OFFSET
// paginates (the frontend de-dups the rare drift). At larger scale this moves
// to a precomputed fan-out / keyset cursor.
func (r *PostRepo) FeedForViewer(ctx context.Context, viewerID string, limit, offset int, exclude []string) ([]model.Post, error) {
// nil would encode as SQL NULL, and `id <> ALL(NULL)` is NULL (excludes
// every row); a non-nil empty array means "exclude nothing".
if exclude == nil {
exclude = []string{}
}
q := `SELECT ` + postSelectColumns + postSelectFrom + `
WHERE p.user_id <> $1
AND p.id <> ALL($4)
AND NOT EXISTS (
SELECT 1 FROM user_blocks b
WHERE (b.blocker_id = $1 AND b.blocked_id = p.user_id)
@@ -247,7 +260,7 @@ func (r *PostRepo) FeedForViewer(ctx context.Context, viewerID string, limit, of
END) ASC,
p.created_at DESC, p.id DESC
LIMIT $2 OFFSET $3`
posts, _, err := r.collectPosts(ctx, 0, q, viewerID, limit, offset)
posts, _, err := r.collectPosts(ctx, 0, q, viewerID, limit, offset, exclude)
return posts, err
}