fix(actions): send and use subscription_id for domain suspend/unsuspend #17

Merged
robbond merged 1 commits from fix/actions-use-subscription-id into master 2026-03-05 14:20:34 +00:00
2 changed files with 24 additions and 12 deletions

View File

@@ -12,6 +12,7 @@ import { createSupabaseRouteClient } from "@/lib/supabase/route";
const actionSchema = z.object({ const actionSchema = z.object({
action: z.enum(["suspend", "unsuspend"]), action: z.enum(["suspend", "unsuspend"]),
subscription_id: z.string().uuid().optional(),
}); });
export async function POST( export async function POST(
@@ -32,7 +33,8 @@ export async function POST(
assertAgencyAdmin(context); assertAgencyAdmin(context);
assertRateLimit(`plesk-domain-action:${context.userId}`, 10, 60_000); assertRateLimit(`plesk-domain-action:${context.userId}`, 10, 60_000);
const { action } = actionSchema.parse(await req.json()); const payload = actionSchema.parse(await req.json());
const { action } = payload;
requestedAction = action; requestedAction = action;
const { data: domainRow, error: domainError } = await supabase const { data: domainRow, error: domainError } = await supabase
@@ -46,21 +48,23 @@ export async function POST(
throw new Error("Domain not found"); throw new Error("Domain not found");
} }
const resolvedSubscriptionId =
payload.subscription_id ??
(domainRow.subscription_id ? String(domainRow.subscription_id) : null);
domain = { domain = {
id: String(domainRow.id), id: String(domainRow.id),
subscription_id: domainRow.subscription_id subscription_id: resolvedSubscriptionId,
? String(domainRow.subscription_id)
: null,
}; };
if (!domain.subscription_id) { if (!resolvedSubscriptionId) {
throw new Error("Domain is not linked to a subscription"); throw new Error("Domain is not linked to a subscription");
} }
const { data: subscriptionRow, error: subscriptionError } = await supabase const { data: subscriptionRow, error: subscriptionError } = await supabase
.from("plesk_subscriptions") .from("plesk_subscriptions")
.select("id, plesk_subscription_id, plesk_instance_id") .select("id, plesk_subscription_id, plesk_instance_id")
.eq("id", domain.subscription_id) .eq("id", resolvedSubscriptionId)
.eq("agency_id", context.agencyId) .eq("agency_id", context.agencyId)
.single(); .single();

View File

@@ -239,13 +239,23 @@ export function DashboardControls({
} }
async function onDomainAction( async function onDomainAction(
domainId: string, domain: Domain,
action: "suspend" | "unsuspend", action: "suspend" | "unsuspend",
) { ) {
if (!domain.subscription_id) {
setMessage(
"Domain is not linked to a subscription yet. Run Sync Now (or backfill links) and try again.",
);
return;
}
setLoading(true); setLoading(true);
setMessage(null); setMessage(null);
try { try {
await runRequest(`/api/plesk/domains/${domainId}/action`, { action }); await runRequest(`/api/plesk/domains/${domain.id}/action`, {
action,
subscription_id: domain.subscription_id,
});
setMessage("Domain action completed."); setMessage("Domain action completed.");
window.location.reload(); window.location.reload();
} catch (error) { } catch (error) {
@@ -633,7 +643,7 @@ export function DashboardControls({
<td className="px-2 py-2"> <td className="px-2 py-2">
<div className="flex gap-2"> <div className="flex gap-2">
<button <button
onClick={() => onDomainAction(domain.id, "suspend")} onClick={() => onDomainAction(domain, "suspend")}
disabled={ disabled={
loading || isDomainSuspended(domain.status) loading || isDomainSuspended(domain.status)
} }
@@ -642,9 +652,7 @@ export function DashboardControls({
Suspend Suspend
</button> </button>
<button <button
onClick={() => onClick={() => onDomainAction(domain, "unsuspend")}
onDomainAction(domain.id, "unsuspend")
}
disabled={loading || isDomainActive(domain.status)} disabled={loading || isDomainActive(domain.status)}
className="rounded border border-emerald-300 px-2 py-1 text-xs text-emerald-700 disabled:cursor-not-allowed disabled:opacity-60" className="rounded border border-emerald-300 px-2 py-1 text-xs text-emerald-700 disabled:cursor-not-allowed disabled:opacity-60"
> >