import type { Database } from "@/lib/types"; import { listPleskDomains, listPleskSubscriptions } from "@/lib/plesk/client"; type SupabaseLike = any; type SyncResult = { instanceId: string; agencyId: string; skipped: boolean; reason?: string; subscriptionsUpserted: number; domainsUpserted: number; }; type InstanceRow = Pick< Database["public"]["Tables"]["plesk_instances"]["Row"], | "id" | "agency_id" | "base_url" | "auth_type" | "encrypted_secret" | "last_connected_at" >; const MIN_INTERVAL_MS = 3 * 60 * 1000; export async function syncPleskInstance( supabase: SupabaseLike, instance: InstanceRow, actorUserId?: string | null, action = "sync", ): Promise { const startedAtIso = new Date().toISOString(); await supabase .from("plesk_instances") .update({ status: "syncing", last_sync_error: null, }) .eq("id", instance.id) .eq("agency_id", instance.agency_id); const last = instance.last_connected_at ? new Date(instance.last_connected_at).getTime() : 0; if (last && Date.now() - last < MIN_INTERVAL_MS) { await supabase .from("plesk_instances") .update({ status: "connected", last_sync_at: startedAtIso, last_sync_status: "skipped", last_sync_error: "recently_synced", }) .eq("id", instance.id) .eq("agency_id", instance.agency_id); return { instanceId: instance.id, agencyId: instance.agency_id, skipped: true, reason: "recently_synced", subscriptionsUpserted: 0, domainsUpserted: 0, }; } try { const [subscriptionsRaw, domainsRaw] = await Promise.all([ listPleskSubscriptions({ baseUrl: instance.base_url, authType: instance.auth_type, encryptedSecret: instance.encrypted_secret, }), listPleskDomains({ baseUrl: instance.base_url, authType: instance.auth_type, encryptedSecret: instance.encrypted_secret, }), ]); const subscriptionsForUpsert = subscriptionsRaw .map((item: any) => { const sourceId = 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, status: item?.status ? String(item.status) : null, owner_login: item?.owner_login ? String(item.owner_login) : item?.owner?.login ? String(item.owner.login) : null, plan_name: item?.plan_name ? String(item.plan_name) : item?.service_plan?.name ? String(item.service_plan.name) : null, }; }) .filter(Boolean) as Array>; if (subscriptionsForUpsert.length > 0) { const { error } = await supabase .from("plesk_subscriptions") .upsert(subscriptionsForUpsert, { onConflict: "agency_id,plesk_subscription_id", }); if (error) throw new Error(error.message); } const { data: localSubscriptions, error: localSubscriptionsError } = await supabase .from("plesk_subscriptions") .select("id, plesk_subscription_id, status") .eq("agency_id", instance.agency_id) .eq("plesk_instance_id", instance.id); if (localSubscriptionsError) { throw new Error(localSubscriptionsError.message); } const subscriptionByExternalId = new Map< string, { id: string; status: string | null } >( (localSubscriptions ?? []) .filter((row: any) => row?.plesk_subscription_id && row?.id) .map((row: any) => [ String(row.plesk_subscription_id), { id: String(row.id), status: row?.status ? String(row.status) : null, }, ]), ); const domainsForUpsert = domainsRaw .map((item: any) => { const domainId = item?.id ?? item?.guid ?? item?.name; const domainName = item?.name ?? item?.domain_name ?? item?.domain; const subExternalId = item?.subscription?.id ?? item?.subscription_id ?? item?.webspace_id; const externalSubscriptionId = subExternalId ? String(subExternalId) : null; const localSubscription = externalSubscriptionId ? subscriptionByExternalId.get(externalSubscriptionId) : undefined; const rawCreated = item?.created_at ?? item?.created; const sourceCreatedAt = rawCreated ? new Date(String(rawCreated)).toISOString() : null; const aliasesCount = typeof item?.aliases_count === "number" ? item.aliases_count : Array.isArray(item?.aliases) ? item.aliases.length : null; if (!domainId || !domainName) return null; return { agency_id: instance.agency_id, plesk_instance_id: instance.id, subscription_id: localSubscription?.id ?? null, external_subscription_id: externalSubscriptionId, plesk_domain_id: String(domainId), domain_name: String(domainName), status: localSubscription?.status ?? "unknown", hosting_type: item?.hosting_type ? String(item.hosting_type) : null, source_created_at: sourceCreatedAt, aliases_count: aliasesCount, }; }) .filter(Boolean) as Array>; if (domainsForUpsert.length > 0) { const { error } = await supabase .from("plesk_domains") .upsert(domainsForUpsert, { onConflict: "agency_id,plesk_domain_id", }); if (error) throw new Error(error.message); } await supabase .from("plesk_instances") .update({ last_connected_at: new Date().toISOString(), status: "connected", error_message: null, last_sync_at: startedAtIso, last_sync_status: "success", last_sync_error: null, last_sync_subscriptions: subscriptionsForUpsert.length, last_sync_domains: domainsForUpsert.length, }) .eq("id", instance.id) .eq("agency_id", instance.agency_id); 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, status: "success", metadata: { subscriptions_seen: subscriptionsRaw.length, domains_seen: domainsRaw.length, }, }); return { instanceId: instance.id, agencyId: instance.agency_id, skipped: false, subscriptionsUpserted: subscriptionsForUpsert.length, domainsUpserted: domainsForUpsert.length, }; } catch (error) { const message = error instanceof Error ? error.message.slice(0, 1000) : "Sync failed"; await supabase .from("plesk_instances") .update({ status: "error", error_message: message, last_sync_at: startedAtIso, last_sync_status: "failed", last_sync_error: message, }) .eq("id", instance.id) .eq("agency_id", instance.agency_id); throw error; } }