feat: followers-only recipe visibility
Adds a fourth visibility tier alongside private/unlisted/public: "followers" — visible to the author and anyone who follows them, excluded from public search/explore/profile listings and from the anonymous /r/[id] share route, included in the Following feed. The in-app recipe detail gate and the public share route both check follow status directly against the DB rather than the union type alone, since neither previously had any per-viewer access logic for a non-public/non-owner case. Requires the generated migration (0041) to run against a live DB — not applied in this sandbox (no Docker here); run `pnpm db:migrate`. v0.41.0
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { recipes, userFollows, 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.
|
||||
*/
|
||||
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 ${userFollows} where ${userFollows.followerId} = ${viewerId} and ${userFollows.followingId} = ${recipes.authorId})`
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user