import { NextResponse } from "next/server"; import { getSessionUser } from "@/lib/session"; import { getSkillActivationRequestById, updateSkillActivationRequestStatus, } from "@/lib/db"; /** * POST /api/skills/requests/[id]/withdraw * * The owner of a pending activation request can cancel it. This * doesn't touch K8s (the skill was never enabled) — it just flips * the row to 'withdrawn' so the user's UI clears the pending * state and they can try a different skill or retry later. * * Authorization: only the original requester OR a platform admin * can withdraw a request. We deliberately don't allow other org * members to cancel each other's requests in v1 — the partial * unique index would let one user repeatedly cancel another's * pending request. */ export async function POST( _request: Request, { params }: { params: Promise<{ id: string }> } ) { const user = await getSessionUser(); if (!user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const { id } = await params; const req = await getSkillActivationRequestById(id); if (!req) { return NextResponse.json({ error: "Request not found" }, { status: 404 }); } if (!user.isPlatform && req.zitadelUserId !== user.id) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } if (req.status !== "pending") { return NextResponse.json( { error: `Request is already ${req.status}` }, { status: 409 } ); } const updated = await updateSkillActivationRequestStatus(id, "withdrawn", { reviewedBy: user.id, }); if (!updated) { return NextResponse.json( { error: "Request status changed during withdraw." }, { status: 409 } ); } return NextResponse.json(updated); }