Files
Epicure/apps/web/lib/recipe-ratings.ts
Arnaud c21157fc93 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>
2026-07-13 22:43:58 +02:00

21 lines
815 B
TypeScript

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 }]));
}