From 1bd0000667cc0db08a173cbecf1077ac62eee631 Mon Sep 17 00:00:00 2001 From: ssavutu Date: Fri, 31 Jul 2026 01:10:02 -0400 Subject: [PATCH] fix(comments): hide pingbacks and trackbacks from the public endpoint adminCommentConditions has always excluded them, which left GetApprovedCommentsByArticleSlug as the one place they still surfaced. They are automated link notifications rather than anything a reader wrote, and in the migrated WordPress data they are almost entirely SEO spam: 155 rows sourced from domains like weddingdressesideas.com and garciniacambogia-reviews.org, every one of them approved by WordPress. Same predicate as the admin path, so the two agree. Rows stay in the table. Co-Authored-By: Claude Opus 5 --- server/internal/database/comments.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/internal/database/comments.go b/server/internal/database/comments.go index 5ebf826..2e9a9ea 100644 --- a/server/internal/database/comments.go +++ b/server/internal/database/comments.go @@ -110,6 +110,14 @@ func ScanComment(rows *sql.Rows) (Comment, error) { return comment, nil } +// GetApprovedCommentsByArticleSlug returns the reader comments shown under an +// article. Pingbacks and trackbacks are excluded: WordPress stored them in the +// same table, but they are automated link notifications rather than anything a +// reader wrote, and on the imported data they are almost entirely SEO spam. +// This matches the predicate adminCommentConditions already applies, which is +// what left the public endpoint as the one place they still surfaced. Rows stay +// in the table; nothing renders them. A NULL or empty type means a comment -- +// that is what WordPress wrote for ordinary rows. func GetApprovedCommentsByArticleSlug(ctx context.Context, conn *sql.DB, slug string) ([]Comment, error) { rows, err := conn.QueryContext(ctx, ` SELECT @@ -126,6 +134,7 @@ func GetApprovedCommentsByArticleSlug(ctx context.Context, conn *sql.DB, slug st FROM comments c JOIN articles a ON a.id = c.article_id WHERE a.slug = ? AND c.status = 'approved' + AND (c.`+"`type`"+` IS NULL OR c.`+"`type`"+` = '' OR c.`+"`type`"+` = 'comment') ORDER BY COALESCE(c.created_at_gmt, c.created_at), c.id `, slug) if err != nil {