feat: rating stars on recipe cards (Search, Explore)
New lib/recipe-ratings.ts helper batches avg score + review count for a set of recipe ids in one grouped query, kept separate from the main paginated/sorted search query rather than joining+grouping it directly (would've forced grouping by every selected column). Wired into /api/v1/search and the Explore page's trending/recent queries; SearchResultCard renders the star only when a recipe has at least one rating. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { db, ratings, inArray, sql } from "@epicure/db";
|
||||
|
||||
export type RatingSummary = { avgRating: number; ratingCount: number };
|
||||
|
||||
/** Average score + review count per recipe, for a batch of recipe ids — used to show rating stars on list/search cards without a per-row join. */
|
||||
export async function getAvgRatingsByRecipeId(recipeIds: string[]): Promise<Map<string, RatingSummary>> {
|
||||
if (recipeIds.length === 0) return new Map();
|
||||
|
||||
const rows = await db
|
||||
.select({
|
||||
recipeId: ratings.recipeId,
|
||||
avgScore: sql<number>`avg(${ratings.score})::float`,
|
||||
count: sql<number>`count(*)::int`,
|
||||
})
|
||||
.from(ratings)
|
||||
.where(inArray(ratings.recipeId, recipeIds))
|
||||
.groupBy(ratings.recipeId);
|
||||
|
||||
return new Map(rows.map((r) => [r.recipeId, { avgRating: r.avgScore, ratingCount: r.count }]));
|
||||
}
|
||||
Reference in New Issue
Block a user