fix: add link_preview_* columns to all post queries

All post-fetching SQL queries were missing the link_preview_url,
link_preview_title, link_preview_description, link_preview_image_url,
and link_preview_site_name columns. The Go model had the fields but
they were never populated from the DB.

Fixed in: GetFeed, GetPostsByAuthor, GetPostByID, GetSavedPosts,
GetLikedPosts, SearchPosts, GetPostFocusContext (children + siblings),
GetPopularPublicPosts
This commit is contained in:
Patrick Britton 2026-02-09 19:05:30 -06:00
parent 257acb0e51
commit 0a420278ec

View file

@ -167,7 +167,8 @@ func (r *PostRepository) GetFeed(ctx context.Context, userID string, categorySlu
COALESCE((SELECT jsonb_object_agg(emoji, count) FROM (SELECT emoji, COUNT(*) as count FROM public.post_reactions WHERE post_id = p.id GROUP BY emoji) r), '{}'::jsonb) as reaction_counts, COALESCE((SELECT jsonb_object_agg(emoji, count) FROM (SELECT emoji, COUNT(*) as count FROM public.post_reactions WHERE post_id = p.id GROUP BY emoji) r), '{}'::jsonb) as reaction_counts,
CASE WHEN ($4::text) != '' THEN COALESCE((SELECT jsonb_agg(emoji) FROM public.post_reactions WHERE post_id = p.id AND user_id = $4::text::uuid), '[]'::jsonb) ELSE '[]'::jsonb END as my_reactions, CASE WHEN ($4::text) != '' THEN COALESCE((SELECT jsonb_agg(emoji) FROM public.post_reactions WHERE post_id = p.id AND user_id = $4::text::uuid), '[]'::jsonb) ELSE '[]'::jsonb END as my_reactions,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -216,6 +217,7 @@ func (r *PostRepository) GetFeed(ctx context.Context, userID string, categorySlu
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.AllowChain, &p.Visibility, &p.Reactions, &p.MyReactions, &p.AllowChain, &p.Visibility, &p.Reactions, &p.MyReactions,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -272,7 +274,8 @@ func (r *PostRepository) GetPostsByAuthor(ctx context.Context, authorID string,
COALESCE((SELECT jsonb_object_agg(emoji, count) FROM (SELECT emoji, COUNT(*) as count FROM public.post_reactions WHERE post_id = p.id GROUP BY emoji) r), '{}'::jsonb) as reaction_counts, COALESCE((SELECT jsonb_object_agg(emoji, count) FROM (SELECT emoji, COUNT(*) as count FROM public.post_reactions WHERE post_id = p.id GROUP BY emoji) r), '{}'::jsonb) as reaction_counts,
CASE WHEN ($4::text) != '' THEN COALESCE((SELECT jsonb_agg(emoji) FROM public.post_reactions WHERE post_id = p.id AND user_id = $4::text::uuid), '[]'::jsonb) ELSE '[]'::jsonb END as my_reactions, CASE WHEN ($4::text) != '' THEN COALESCE((SELECT jsonb_agg(emoji) FROM public.post_reactions WHERE post_id = p.id AND user_id = $4::text::uuid), '[]'::jsonb) ELSE '[]'::jsonb END as my_reactions,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -308,6 +311,7 @@ func (r *PostRepository) GetPostsByAuthor(ctx context.Context, authorID string,
&p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL, &p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.AllowChain, &p.Visibility, &p.Reactions, &p.MyReactions, &p.LikeCount, &p.CommentCount, &p.IsLiked, &p.AllowChain, &p.Visibility, &p.Reactions, &p.MyReactions,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -351,7 +355,8 @@ func (r *PostRepository) GetPostByID(ctx context.Context, postID string, userID
CASE WHEN $2 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::uuid) ELSE FALSE END as is_liked, CASE WHEN $2 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::uuid) ELSE FALSE END as is_liked,
p.allow_chain, p.visibility, p.allow_chain, p.visibility,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -375,6 +380,7 @@ func (r *PostRepository) GetPostByID(ctx context.Context, postID string, userID
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.AllowChain, &p.Visibility, &p.AllowChain, &p.Visibility,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -602,7 +608,8 @@ func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit
COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count, COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count,
EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $1::uuid) as is_liked, EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $1::uuid) as is_liked,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.post_saves ps FROM public.post_saves ps
JOIN public.posts p ON ps.post_id = p.id JOIN public.posts p ON ps.post_id = p.id
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
@ -626,6 +633,7 @@ func (r *PostRepository) GetSavedPosts(ctx context.Context, userID string, limit
&p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL, &p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -655,7 +663,8 @@ func (r *PostRepository) GetLikedPosts(ctx context.Context, userID string, limit
COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count, COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count,
TRUE as is_liked, TRUE as is_liked,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.post_likes pl FROM public.post_likes pl
JOIN public.posts p ON pl.post_id = p.id JOIN public.posts p ON pl.post_id = p.id
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
@ -679,6 +688,7 @@ func (r *PostRepository) GetLikedPosts(ctx context.Context, userID string, limit
&p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL, &p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -820,7 +830,8 @@ func (r *PostRepository) SearchPosts(ctx context.Context, query string, viewerID
p.created_at, p.created_at,
pr.handle as author_handle, pr.display_name as author_display_name, COALESCE(pr.avatar_url, '') as author_avatar_url, pr.handle as author_handle, pr.display_name as author_display_name, COALESCE(pr.avatar_url, '') as author_avatar_url,
COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count, COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count,
CASE WHEN $3 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $3::uuid) ELSE FALSE END as is_liked CASE WHEN $3 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $3::uuid) ELSE FALSE END as is_liked,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -854,6 +865,7 @@ func (r *PostRepository) SearchPosts(ctx context.Context, query string, viewerID
&p.ID, &p.AuthorID, &p.CategoryID, &p.Body, &p.ImageURL, &p.VideoURL, &p.ThumbnailURL, &p.DurationMS, &p.Tags, &p.CreatedAt, &p.ID, &p.AuthorID, &p.CategoryID, &p.Body, &p.ImageURL, &p.VideoURL, &p.ThumbnailURL, &p.DurationMS, &p.Tags, &p.CreatedAt,
&p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL, &p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -1056,7 +1068,8 @@ func (r *PostRepository) GetPostFocusContext(ctx context.Context, postID string,
CASE WHEN $2 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::uuid) ELSE FALSE END as is_liked, CASE WHEN $2 != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::uuid) ELSE FALSE END as is_liked,
p.allow_chain, p.visibility, p.allow_chain, p.visibility,
COALESCE(p.is_nsfw, FALSE) as is_nsfw, COALESCE(p.is_nsfw, FALSE) as is_nsfw,
COALESCE(p.nsfw_reason, '') as nsfw_reason COALESCE(p.nsfw_reason, '') as nsfw_reason,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -1087,6 +1100,7 @@ func (r *PostRepository) GetPostFocusContext(ctx context.Context, postID string,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.AllowChain, &p.Visibility, &p.AllowChain, &p.Visibility,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to scan child post: %w", err) return nil, fmt.Errorf("failed to scan child post: %w", err)
@ -1128,6 +1142,7 @@ func (r *PostRepository) GetPostFocusContext(ctx context.Context, postID string,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.AllowChain, &p.Visibility, &p.AllowChain, &p.Visibility,
&p.IsNSFW, &p.NSFWReason, &p.IsNSFW, &p.NSFWReason,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to scan parent child post: %w", err) return nil, fmt.Errorf("failed to scan parent child post: %w", err)
@ -1377,7 +1392,8 @@ func (r *PostRepository) GetPopularPublicPosts(ctx context.Context, viewerID str
pr.handle as author_handle, pr.display_name as author_display_name, COALESCE(pr.avatar_url, '') as author_avatar_url, pr.handle as author_handle, pr.display_name as author_display_name, COALESCE(pr.avatar_url, '') as author_avatar_url,
COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count, COALESCE(m.like_count, 0) as like_count, COALESCE(m.comment_count, 0) as comment_count,
CASE WHEN ($2::text) != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::text::uuid) ELSE FALSE END as is_liked, CASE WHEN ($2::text) != '' THEN EXISTS(SELECT 1 FROM public.post_likes WHERE post_id = p.id AND user_id = $2::text::uuid) ELSE FALSE END as is_liked,
p.allow_chain, p.visibility p.allow_chain, p.visibility,
p.link_preview_url, p.link_preview_title, p.link_preview_description, p.link_preview_image_url, p.link_preview_site_name
FROM public.posts p FROM public.posts p
JOIN public.profiles pr ON p.author_id = pr.id JOIN public.profiles pr ON p.author_id = pr.id
LEFT JOIN public.post_metrics m ON p.id = m.post_id LEFT JOIN public.post_metrics m ON p.id = m.post_id
@ -1402,6 +1418,7 @@ func (r *PostRepository) GetPopularPublicPosts(ctx context.Context, viewerID str
&p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL, &p.AuthorHandle, &p.AuthorDisplayName, &p.AuthorAvatarURL,
&p.LikeCount, &p.CommentCount, &p.IsLiked, &p.LikeCount, &p.CommentCount, &p.IsLiked,
&p.AllowChain, &p.Visibility, &p.AllowChain, &p.Visibility,
&p.LinkPreviewURL, &p.LinkPreviewTitle, &p.LinkPreviewDescription, &p.LinkPreviewImageURL, &p.LinkPreviewSiteName,
) )
if err != nil { if err != nil {
return nil, err return nil, err