From fec7c682f07e33995ef03b39dcc35fef2c76396f Mon Sep 17 00:00:00 2001 From: robbond Date: Thu, 5 Mar 2026 12:42:51 +0000 Subject: [PATCH] feat(sync): ingest subscription status during sync --- lib/plesk/sync.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/lib/plesk/sync.ts b/lib/plesk/sync.ts index 6976e2c..a3fe605 100644 --- a/lib/plesk/sync.ts +++ b/lib/plesk/sync.ts @@ -32,6 +32,31 @@ export async function syncPleskInstance( ): Promise { const startedAtIso = new Date().toISOString(); + const logStatusSyncEvent = async ( + eventAction: + | "subscription_status_sync_started" + | "subscription_status_sync_completed" + | "subscription_status_sync_failed", + metadata?: Record, + status: "success" | "failed" = "success", + errorMessage?: string | null, + ) => { + try { + await supabase.from("actions_log").insert({ + agency_id: instance.agency_id, + actor_user_id: actorUserId ?? null, + target_type: "plesk_instance", + target_id: instance.id, + action: eventAction, + status, + error_message: errorMessage ?? null, + metadata: metadata ?? {}, + }); + } catch { + // Logging should never block sync flow. + } + }; + await supabase .from("plesk_instances") .update({ @@ -67,6 +92,10 @@ export async function syncPleskInstance( } try { + await logStatusSyncEvent("subscription_status_sync_started", { + started_at: startedAtIso, + }); + const [subscriptionsRaw, domainsRaw] = await Promise.all([ listPleskSubscriptions({ baseUrl: instance.base_url, @@ -95,6 +124,8 @@ export async function syncPleskInstance( plesk_subscription_id: String(sourceId), name: item?.name ? String(item.name) : String(sourceId), status: item?.status ? String(item.status) : "unknown", + status_raw: item?.status_raw ? String(item.status_raw) : null, + last_status_sync_at: startedAtIso, owner_login: item?.owner_login ? String(item.owner_login) : item?.owner?.login @@ -109,6 +140,10 @@ export async function syncPleskInstance( }) .filter(Boolean) as Array>; + const subscriptionStatusSyncFailures = subscriptionsRaw.filter( + (item: any) => Boolean(item?.status_sync_error), + ); + if (subscriptionsForUpsert.length > 0) { const { error } = await supabase .from("plesk_subscriptions") @@ -221,6 +256,40 @@ export async function syncPleskInstance( }, }); + await logStatusSyncEvent("subscription_status_sync_completed", { + synced_subscriptions: subscriptionsRaw.length, + failed_subscriptions: subscriptionStatusSyncFailures.length, + failed_subscription_ids: subscriptionStatusSyncFailures + .slice(0, 50) + .map((item: any) => + String( + item?.plesk_subscription_id ?? item?.subscription_id ?? "unknown", + ), + ), + completed_at: new Date().toISOString(), + }); + + if (subscriptionStatusSyncFailures.length > 0) { + await logStatusSyncEvent( + "subscription_status_sync_failed", + { + failed_subscriptions: subscriptionStatusSyncFailures.length, + sample_errors: subscriptionStatusSyncFailures + .slice(0, 20) + .map((item: any) => ({ + subscription: String( + item?.plesk_subscription_id ?? + item?.subscription_id ?? + "unknown", + ), + error: String(item?.status_sync_error ?? "status_sync_failed"), + })), + }, + "failed", + `${subscriptionStatusSyncFailures.length} subscription status sync failures`, + ); + } + return { instanceId: instance.id, agencyId: instance.agency_id, @@ -232,6 +301,15 @@ export async function syncPleskInstance( const message = error instanceof Error ? error.message.slice(0, 1000) : "Sync failed"; + await logStatusSyncEvent( + "subscription_status_sync_failed", + { + failed_at: new Date().toISOString(), + }, + "failed", + message, + ); + await supabase .from("plesk_instances") .update({