Files
Epicure/apps/web/app/api/v1/recipes/[id]/versions/route.ts
T
Arnaud 1fe379bcdc feat: version history as 10th feature flag, richer upgrade prompts, close unguarded photo-import tab (v0.80.0)
Recipe version history is now gated like the other 9 per-tier features (enabled by default, locked-vs-hidden treatment via isFeatureAvailableAnyTier). UpgradeDialog now shows a tagline + concrete bullet list per feature instead of one generic sentence.

Also closes a real gap: the AI-generate dialog's Photo tab hit /api/v1/ai/import-photo directly with no tier check in the UI (server route was already correctly gated) — a locked-out user could fill it in and hit a dead-end error instead of an upgrade prompt. Now threaded through the same lock/hide props as the dedicated PhotoImportButton.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 14:04:27 +02:00

38 lines
1.4 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { db, recipes, recipeSnapshots } from "@epicure/db";
import { eq, and, desc } from "@epicure/db";
import { requireSessionOrApiKey } from "@/lib/api-auth";
import { requireFeatureEnabledResponse } from "@/lib/feature-flags";
type Params = { params: Promise<{ id: string }> };
export async function GET(req: NextRequest, { params }: Params) {
const { session, response } = await requireSessionOrApiKey(req, { rateLimit: { limit: 60, windowSeconds: 60 } });
if (response) return response;
const featureDenied = await requireFeatureEnabledResponse(session!.user.id, "version_history");
if (featureDenied) return featureDenied;
const { id } = await params;
// Verify ownership
const recipe = await db.query.recipes.findFirst({
where: and(eq(recipes.id, id), eq(recipes.authorId, session!.user.id)),
});
if (!recipe) return NextResponse.json({ error: "Not found" }, { status: 404 });
const versions = await db
.select({
id: recipeSnapshots.id,
version: recipeSnapshots.version,
title: recipeSnapshots.title,
createdAt: recipeSnapshots.createdAt,
})
.from(recipeSnapshots)
.where(and(eq(recipeSnapshots.recipeId, id), eq(recipeSnapshots.authorId, session!.user.id)))
.orderBy(desc(recipeSnapshots.version))
.limit(20);
return NextResponse.json(versions);
}