From fa434281537ed15e40e3119d225a4f7e2b640aaf Mon Sep 17 00:00:00 2001 From: robbond Date: Thu, 5 Mar 2026 10:10:17 +0000 Subject: [PATCH] Fix subscription status via CLI; derive domain status + badges --- components/dashboard/dashboard-controls.tsx | 14 +--- lib/plesk/client.ts | 84 +++++++++---------- lib/plesk/sync.ts | 9 +- ...main_status_backfill_from_subscription.sql | 7 +- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/components/dashboard/dashboard-controls.tsx b/components/dashboard/dashboard-controls.tsx index dd27721..9af6dbd 100644 --- a/components/dashboard/dashboard-controls.tsx +++ b/components/dashboard/dashboard-controls.tsx @@ -52,19 +52,13 @@ type Props = { function getDomainStatusBadge(status: string | null) { const normalized = (status ?? "unknown").toLowerCase(); - if ( - normalized.includes("active") || - normalized.includes("ok") || - normalized.includes("enabled") - ) { - return "bg-emerald-100 text-emerald-700"; - } - - if (normalized.includes("suspended") || normalized.includes("disabled")) { + if (normalized.includes("suspend") || normalized.includes("disabled")) { return "bg-rose-100 text-rose-700"; } - if (normalized.includes("inactive")) return "bg-amber-100 text-amber-700"; + if (normalized.includes("active") || normalized.includes("enabled")) { + return "bg-emerald-100 text-emerald-700"; + } return "bg-slate-100 text-slate-600"; } diff --git a/lib/plesk/client.ts b/lib/plesk/client.ts index 90be078..843db76 100644 --- a/lib/plesk/client.ts +++ b/lib/plesk/client.ts @@ -9,6 +9,7 @@ export type PleskConnection = { }; export type PleskSubscription = { + plesk_subscription_id?: string; id?: string | number; guid?: string; subscription_id?: string | number; @@ -137,51 +138,50 @@ export async function testPleskConnection(connection: PleskConnection) { } export async function listPleskSubscriptions(connection: PleskConnection) { - try { - const all: PleskSubscription[] = []; + const listOutput = await pleskCliCall(connection, "subscription", ["--list"]); - for (let page = 1; page <= 20; page += 1) { - const payload = await pleskRequest( - connection, - `/api/v2/subscriptions?page=${page}&per_page=100`, - ); - const rows = Array.isArray(payload) ? payload : []; - all.push(...rows); - if (rows.length < 100) break; + const subscriptionNames = listOutput + .split(/\r?\n/) + .map((line) => line.trim()) + .filter(Boolean); + + const subscriptions: PleskSubscription[] = []; + + for (const subscriptionName of subscriptionNames) { + let status = "unknown"; + + try { + const infoOutput = await pleskCliCall(connection, "subscription", [ + "--info", + subscriptionName, + ]); + const normalizedInfo = infoOutput.toLowerCase(); + + const hasSuspendedMarker = + normalizedInfo.includes("suspended") || + normalizedInfo.includes("webspace-off") || + normalizedInfo.includes("disabled"); + + const hasActiveMarker = + normalizedInfo.includes("active") || + normalizedInfo.includes("enabled") || + normalizedInfo.includes("ok"); + + if (hasSuspendedMarker) status = "suspended"; + else if (hasActiveMarker || !hasSuspendedMarker) status = "active"; + } catch { + status = "unknown"; } - return all; - } catch { - const cli = await pleskRequest( - connection, - "/api/v2/cli/subscription/call", - { - method: "POST", - body: JSON.stringify({ params: ["--list"] }), - }, - ); - - const stdout = cli?.stdout ?? ""; - if (!stdout.trim()) { - return []; - } - - return stdout - .split(/\r?\n/) - .map((line) => line.trim()) - .filter(Boolean) - .map((line) => { - const columns = line.split(/\s+/); - const externalId = columns[0] ?? line; - return { - id: externalId, - subscription_id: externalId, - external_id: externalId, - name: columns.slice(1).join(" ") || externalId, - status: null, - }; - }); + subscriptions.push({ + plesk_subscription_id: subscriptionName, + subscription_id: subscriptionName, + name: subscriptionName, + status, + }); } + + return subscriptions; } export async function pleskCliCall( @@ -208,7 +208,7 @@ export async function pleskCliCall( ); } - return { code, stdout, stderr }; + return stdout; } export async function listPleskDomains(connection: PleskConnection) { diff --git a/lib/plesk/sync.ts b/lib/plesk/sync.ts index 52cddc6..554b2dd 100644 --- a/lib/plesk/sync.ts +++ b/lib/plesk/sync.ts @@ -82,13 +82,18 @@ export async function syncPleskInstance( const subscriptionsForUpsert = subscriptionsRaw .map((item: any) => { - const sourceId = item?.id ?? item?.guid ?? item?.subscription_id; + const sourceId = + item?.plesk_subscription_id ?? + item?.name ?? + item?.id ?? + item?.guid ?? + item?.subscription_id; if (!sourceId) return null; return { agency_id: instance.agency_id, plesk_instance_id: instance.id, plesk_subscription_id: String(sourceId), - name: item?.name ? String(item.name) : null, + name: item?.name ? String(item.name) : String(sourceId), status: item?.status ? String(item.status) : null, owner_login: item?.owner_login ? String(item.owner_login) diff --git a/supabase/migrations/CL37_domain_status_backfill_from_subscription.sql b/supabase/migrations/CL37_domain_status_backfill_from_subscription.sql index 9bf0be2..b662035 100644 --- a/supabase/migrations/CL37_domain_status_backfill_from_subscription.sql +++ b/supabase/migrations/CL37_domain_status_backfill_from_subscription.sql @@ -3,4 +3,9 @@ update public.plesk_domains d set status = s.status from public.plesk_subscriptions s where d.subscription_id = s.id - and d.agency_id = s.agency_id; \ No newline at end of file + and d.agency_id = s.agency_id + and (d.status is null or d.status = 'unknown'); + +update public.plesk_subscriptions +set status = 'unknown' +where status is null; \ No newline at end of file