feat: per-tier feature toggles for recipe variations/pairings (v0.50.0)
Admins can now disable specific AI features per tier from Admin > Tier Limits — new feature_flags table (feature x tier -> enabled, defaulting to true so adding a new gated feature never needs a backfill). Covers recipe variations, drink pairing, and meal pairing to start. When disabled for a user's tier, the button stays visible (with a small lock badge) but opens an upgrade dialog instead of running; the API route rejects the call server-side either way (requireFeatureEnabled, re-reads tier from the DB rather than trusting the session's cache, same rationale as checkAndIncrementTierLimit). The upgrade dialog is informational only — no Stripe checkout exists yet (STRIPE_PLAN.md is still just a plan) — its CTA links to /support prefilled as an upgrade-interest suggestion. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import type { Metadata } from "next";
|
||||
import { db, tierDefinitions } from "@epicure/db";
|
||||
import { TierLimitsForm } from "@/components/admin/tier-limits-form";
|
||||
import { FeatureFlagsForm } from "@/components/admin/feature-flags-form";
|
||||
import { getFeatureFlagMatrix, FEATURE_DEFINITIONS } from "@/lib/feature-flags";
|
||||
|
||||
export const metadata: Metadata = {};
|
||||
|
||||
export default async function AdminTiersPage() {
|
||||
const tiers = await db.select().from(tierDefinitions);
|
||||
const [tiers, featureFlagMatrix] = await Promise.all([
|
||||
db.select().from(tierDefinitions),
|
||||
getFeatureFlagMatrix(),
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
@@ -19,6 +24,11 @@ export default async function AdminTiersPage() {
|
||||
{tiers.map((tierDefinition) => (
|
||||
<TierLimitsForm key={tierDefinition.tier} tierDefinition={tierDefinition} />
|
||||
))}
|
||||
|
||||
<FeatureFlagsForm
|
||||
features={FEATURE_DEFINITIONS.map((f) => ({ key: f.key, label: f.label, description: f.description }))}
|
||||
initialMatrix={featureFlagMatrix}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user