feat(backend): __DEV__ /api/dev/set-plan — user sets own plan (non-prod only)
POST /api/dev/set-plan { plan: 'free'|'pro'|'legend' } — requireUser, sets the
caller's own profile.plan via Prisma. Refuses on production URL (same guard as
the cooldown testMode: appUrl includes rebreak.org && !includes staging). Lets
the __DEV__ tier-toggle work without admin rights. Does NOT weaken updateProfile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
14452b2a46
commit
eb871073f2
47
backend/server/api/dev/set-plan.post.ts
Normal file
47
backend/server/api/dev/set-plan.post.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { usePrisma } from "../../utils/prisma";
|
||||
|
||||
const VALID_PLANS = ["free", "pro", "legend"] as const;
|
||||
type AppPlan = (typeof VALID_PLANS)[number];
|
||||
|
||||
/**
|
||||
* POST /api/dev/set-plan
|
||||
*
|
||||
* DEV/STAGING-ONLY: Setzt den eigenen Plan ohne Admin-Rechte.
|
||||
* Blocked in Production (appUrl enthält "rebreak.org" aber NICHT "staging").
|
||||
*
|
||||
* Body: { plan: "free" | "pro" | "legend" }
|
||||
* Response: { success: true, plan: AppPlan }
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUser(event);
|
||||
|
||||
// Prod-Guard: analog cooldown/request.post.ts
|
||||
const config = useRuntimeConfig(event);
|
||||
const appUrl = (config.public?.appUrl as string) ?? "";
|
||||
const isProductionUrl =
|
||||
appUrl.includes("rebreak.org") && !appUrl.includes("staging");
|
||||
if (isProductionUrl) {
|
||||
throw createError({ statusCode: 403, message: "dev-only" });
|
||||
}
|
||||
|
||||
const body = await readBody(event).catch(() => ({}));
|
||||
const plan = body?.plan as string | undefined;
|
||||
|
||||
if (!plan || !(VALID_PLANS as readonly string[]).includes(plan)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
data: {
|
||||
error: "INVALID_PLAN",
|
||||
message: `plan must be one of: ${VALID_PLANS.join(", ")}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const db = usePrisma();
|
||||
await db.profile.update({
|
||||
where: { id: user.id },
|
||||
data: { plan: plan as AppPlan },
|
||||
});
|
||||
|
||||
return { success: true, plan: plan as AppPlan };
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user