import { NextRequest, NextResponse } from "next/server"; import { withPermission } from "@/lib/middleware/authorize"; import { withTenantContext } from "@/lib/prisma-tenant"; import { updateServicePlan } from "@/lib/services/service-plan-service"; import { BillingType } from "@prisma/client"; /** * PUT /api/service-plans/[id] * * Partially update a service plan. * Accepts: { name?, speed?, monthlyPrice?, billingType?, description?, isActive? } * * Requires: manage on Subscriber subject. * * Response: * 200 OK — updated service plan object * 400 Bad Request — validation error * 401 Unauthorized — no session * 403 Forbidden — insufficient role * 404 Not Found — plan not found in tenant scope */ export function PUT(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { return withPermission("manage", "Subscriber")( async (req: NextRequest, { user }) => { if (!user.tenantId) { return NextResponse.json( { error: "No tenant context — super-admins must use the admin API" }, { status: 400 } ); } const { id } = await params; let body: unknown; try { body = await req.json(); } catch { return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); } const updates = body as Record; // Validate billingType if provided if ( updates.billingType !== undefined && !Object.values(BillingType).includes(updates.billingType as BillingType) ) { return NextResponse.json( { error: `billingType must be one of: ${Object.values(BillingType).join(", ")}` }, { status: 400 } ); } const tenantPrisma = withTenantContext(user.tenantId); try { const plan = await updateServicePlan(tenantPrisma, id, { name: updates.name as string | undefined, speed: updates.speed as string | undefined, monthlyPrice: updates.monthlyPrice as number | undefined, billingType: updates.billingType as BillingType | undefined, description: updates.description as string | undefined, isActive: updates.isActive as boolean | undefined, }); return NextResponse.json(plan); } catch (err) { const message = err instanceof Error ? err.message : "Failed to update service plan"; // Prisma throws P2025 for record not found if (message.includes("Record to update not found") || message.includes("P2025")) { return NextResponse.json({ error: "Service plan not found" }, { status: 404 }); } return NextResponse.json({ error: message }, { status: 400 }); } } )(req); }