import { recipes, collections, eq, or, and, inArray, sql } from "@epicure/db"; /** * Drizzle condition: true when `viewerId` may view a given recipe row — the * author, always; `public`/`unlisted` recipes, to anyone; `followers`-only * recipes, only to viewers who follow the author. Meant to be `and()`ed with * an `eq(recipes.id, id)` (or similar) in a single query, so the DB does the * filtering rather than fetching content the viewer can't see. * * Uses a literal `user_follows` identifier rather than a Drizzle column * proxy for that table — inside `db.query.recipes.findFirst`/`findMany`'s * `where`, the relational query builder rewrites embedded column refs to * the outer query's own table alias regardless of which table they actually * belong to (same issue documented in recipes/page.tsx's search filter), * which would otherwise silently produce broken SQL referencing a column * that doesn't exist on `recipes`. */ export function visibleToViewer(viewerId: string) { return or( eq(recipes.authorId, viewerId), inArray(recipes.visibility, ["public", "unlisted"]), and( eq(recipes.visibility, "followers"), sql`exists (select 1 from user_follows where user_follows.follower_id = ${viewerId} and user_follows.following_id = ${recipes.authorId})` ) ); } /** Same rationale/pattern as visibleToViewer(), for collections. */ export function collectionVisibleToViewer(viewerId: string) { return or( eq(collections.userId, viewerId), inArray(collections.visibility, ["public", "unlisted"]), and( eq(collections.visibility, "followers"), sql`exists (select 1 from user_follows where user_follows.follower_id = ${viewerId} and user_follows.following_id = ${collections.userId})` ) ); }