whale-code 6.5.8 → 6.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/cli/services/agent-loop.js +26 -2
  2. package/dist/cli/services/agent-loop.js.map +1 -1
  3. package/dist/cli/services/hooks.js +2 -1
  4. package/dist/cli/services/hooks.js.map +1 -1
  5. package/dist/cli/services/telemetry-spans.js +1 -0
  6. package/dist/cli/services/telemetry-spans.js.map +1 -1
  7. package/dist/cli/services/telemetry.d.ts +23 -0
  8. package/dist/cli/services/telemetry.js +45 -1
  9. package/dist/cli/services/telemetry.js.map +1 -1
  10. package/dist/server/handlers/__test-utils__/test-db.d.ts +17 -3
  11. package/dist/server/handlers/__test-utils__/test-db.js +113 -14
  12. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -1
  13. package/dist/server/handlers/affiliates.d.ts +9 -0
  14. package/dist/server/handlers/affiliates.js +197 -0
  15. package/dist/server/handlers/affiliates.js.map +1 -0
  16. package/dist/server/handlers/api-docs.d.ts +4 -2
  17. package/dist/server/handlers/api-docs.js +204 -1681
  18. package/dist/server/handlers/api-docs.js.map +1 -1
  19. package/dist/server/handlers/campaigns.d.ts +9 -0
  20. package/dist/server/handlers/campaigns.js +237 -0
  21. package/dist/server/handlers/campaigns.js.map +1 -0
  22. package/dist/server/handlers/catalog-schemas.js +9 -9
  23. package/dist/server/handlers/catalog-schemas.js.map +1 -1
  24. package/dist/server/handlers/catalog.js +1 -1
  25. package/dist/server/handlers/catalog.js.map +1 -1
  26. package/dist/server/handlers/comms-documents.js +28 -2
  27. package/dist/server/handlers/comms-documents.js.map +1 -1
  28. package/dist/server/handlers/comms-pdf-generation.js +25 -3
  29. package/dist/server/handlers/comms-pdf-generation.js.map +1 -1
  30. package/dist/server/handlers/comms-pdf-helpers.js +4 -4
  31. package/dist/server/handlers/comms-pdf-helpers.js.map +1 -1
  32. package/dist/server/handlers/comms.d.ts +100 -0
  33. package/dist/server/handlers/comms.js +146 -12
  34. package/dist/server/handlers/comms.js.map +1 -1
  35. package/dist/server/handlers/coupons.d.ts +9 -0
  36. package/dist/server/handlers/coupons.js +220 -0
  37. package/dist/server/handlers/coupons.js.map +1 -0
  38. package/dist/server/handlers/embeddings.js +1 -1
  39. package/dist/server/handlers/embeddings.js.map +1 -1
  40. package/dist/server/handlers/enrichment.js +2 -622
  41. package/dist/server/handlers/enrichment.js.map +1 -1
  42. package/dist/server/handlers/fulfillment.d.ts +9 -0
  43. package/dist/server/handlers/fulfillment.js +209 -0
  44. package/dist/server/handlers/fulfillment.js.map +1 -0
  45. package/dist/server/handlers/google-ads.d.ts +24 -0
  46. package/dist/server/handlers/google-ads.js +2199 -0
  47. package/dist/server/handlers/google-ads.js.map +1 -0
  48. package/dist/server/handlers/invoices.d.ts +9 -0
  49. package/dist/server/handlers/invoices.js +252 -0
  50. package/dist/server/handlers/invoices.js.map +1 -0
  51. package/dist/server/handlers/loyalty.d.ts +9 -0
  52. package/dist/server/handlers/loyalty.js +197 -0
  53. package/dist/server/handlers/loyalty.js.map +1 -0
  54. package/dist/server/handlers/meta-ads-graph-api.js +18 -3
  55. package/dist/server/handlers/meta-ads-graph-api.js.map +1 -1
  56. package/dist/server/handlers/phone.d.ts +9 -0
  57. package/dist/server/handlers/phone.js +197 -0
  58. package/dist/server/handlers/phone.js.map +1 -0
  59. package/dist/server/handlers/pipeline.d.ts +9 -0
  60. package/dist/server/handlers/pipeline.js +277 -0
  61. package/dist/server/handlers/pipeline.js.map +1 -0
  62. package/dist/server/handlers/qr-codes.d.ts +9 -0
  63. package/dist/server/handlers/qr-codes.js +198 -0
  64. package/dist/server/handlers/qr-codes.js.map +1 -0
  65. package/dist/server/handlers/reviews.d.ts +9 -0
  66. package/dist/server/handlers/reviews.js +171 -0
  67. package/dist/server/handlers/reviews.js.map +1 -0
  68. package/dist/server/handlers/segments.d.ts +9 -0
  69. package/dist/server/handlers/segments.js +229 -0
  70. package/dist/server/handlers/segments.js.map +1 -0
  71. package/dist/server/handlers/social.d.ts +9 -0
  72. package/dist/server/handlers/social.js +81 -0
  73. package/dist/server/handlers/social.js.map +1 -0
  74. package/dist/server/handlers/tax.d.ts +9 -0
  75. package/dist/server/handlers/tax.js +182 -0
  76. package/dist/server/handlers/tax.js.map +1 -0
  77. package/dist/server/handlers/wallet.d.ts +9 -0
  78. package/dist/server/handlers/wallet.js +203 -0
  79. package/dist/server/handlers/wallet.js.map +1 -0
  80. package/dist/server/handlers/webhooks-mgmt.d.ts +9 -0
  81. package/dist/server/handlers/webhooks-mgmt.js +181 -0
  82. package/dist/server/handlers/webhooks-mgmt.js.map +1 -0
  83. package/dist/server/handlers/wholesale.d.ts +9 -0
  84. package/dist/server/handlers/wholesale.js +219 -0
  85. package/dist/server/handlers/wholesale.js.map +1 -0
  86. package/dist/server/index.js +20 -9
  87. package/dist/server/index.js.map +1 -1
  88. package/dist/server/lib/clickhouse-buffer.js +1 -0
  89. package/dist/server/lib/clickhouse-buffer.js.map +1 -1
  90. package/dist/server/lib/coa-renderer.d.ts +1 -1
  91. package/dist/server/lib/coa-renderer.js +32 -10
  92. package/dist/server/lib/coa-renderer.js.map +1 -1
  93. package/dist/server/server-worker.d.ts +1 -0
  94. package/dist/server/server-worker.js +464 -3
  95. package/dist/server/server-worker.js.map +1 -1
  96. package/dist/server/tool-router.js +118 -4
  97. package/dist/server/tool-router.js.map +1 -1
  98. package/package.json +26 -3
  99. package/vendor/ink/package.json +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"enrichment.js","names":["getSecret","sb","name","storeId","data","error","rpc","p_name","p_store_id","nowISO","Date","toISOString","handleEnrichment","args","sid","action","success","customerId","customer_id","apiKey","params","email","phone","first_name","last_name","linkedin_url","profile","location","Object","keys","length","queryString","URLSearchParams","toString","resp","fetch","method","headers","ok","text","catch","status","substring","pdlData","json","store_id","enrichment_source","enrichment_data","enriched_at","updated_at","full_name","job_title","job_company_name","company","location_name","gender","birth_year","existing","from","select","eq","maybeSingle","result","update","id","single","created_at","insert","message","err","msg","Error","String","linkedinUrl","datasetId","Authorization","body","JSON","stringify","input","url","bdResult","profileData","Array","isArray","position","current_company","headline","encodeURIComponent","Accept","total_breaches","breaches","xonData","ExposedBreaches","breaches_details","inserted","breach","record","breach_name","breach_domain","domain","breach_date","xposed_date","date","data_classes","xposed_data","split","map","s","trim","breach_source","raw_data","discovered_at","push","new_breaches","risk_metrics","BreachMetrics","Name","Domain","BreachDate","DataClasses","description","Description","is_verified","IsVerified","query","page","size","wildcard","regex","de_dupe","entries","entry","database_name","obtained_date","type","total_results","stored","q","order","ascending","source","limit","count","records","source_name","broker","scan_type","scan_data","broker_count","exposure_count","scan_id","file_path","sourceName","updates","source_url","data_types_exposed","_note","source_type","first_seen_at","exposureId","exposure_id","removed_at","brokerName","broker_name","removal_method","request_data","submitted_at","confirmation_id","exposuresResult","breachesResult","removalsResult","Promise","all","exposures","removals","score","activeExposures","filter","e","removedExposures","completedRemovals","r","Math","max","min","riskLevel","riskRecord","overall_score","risk_level","factors","active_exposures","removed_exposures","completed_removals","pending_removals","calculated_at"],"sources":["../../../src/server/handlers/enrichment.ts"],"sourcesContent":["// server/handlers/enrichment.ts — Customer enrichment, breach checking, and data protection CRUD\n// Integrates with PDL (Person Enrichment), Bright Data (LinkedIn), HIBP (Breach Check),\n// DeHashed, and xonPlus (real-time breach monitoring).\n// All external API keys are fetched via decrypt_secret RPC from encrypted store secrets.\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\n// ---- Helpers ----\n\nasync function getSecret(sb: SupabaseClient, name: string, storeId: string): Promise<string | null> {\n const { data, error } = await sb.rpc(\"decrypt_secret\", { p_name: name, p_store_id: storeId });\n if (error || !data) return null;\n return data as string;\n}\n\nfunction nowISO(): string {\n return new Date().toISOString();\n}\n\n// ---- Main Handler ----\n\nexport async function handleEnrichment(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<{ success: boolean; data?: unknown; error?: string; count?: number; note?: string }> {\n const sid = storeId as string;\n const action = args.action as string;\n\n if (!action) {\n return { success: false, error: \"action is required\" };\n }\n\n switch (action) {\n\n // ---- ENRICH_PERSON: PDL Person Enrichment API ----\n case \"enrich_person\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n const apiKey = await getSecret(sb, \"pdl_api_key\", sid);\n if (!apiKey) return { success: false, error: \"PDL API key not configured. Add 'pdl_api_key' to store secrets.\" };\n\n // Build PDL query params from available identifiers\n const params: Record<string, string> = {};\n if (args.email) params.email = args.email as string;\n if (args.phone) params.phone = args.phone as string;\n if (args.first_name) params.first_name = args.first_name as string;\n if (args.last_name) params.last_name = args.last_name as string;\n if (args.linkedin_url) params.profile = args.linkedin_url as string;\n if (args.location) params.location = args.location as string;\n\n if (Object.keys(params).length === 0) {\n return { success: false, error: \"At least one identifier required: email, phone, first_name+last_name, or linkedin_url\" };\n }\n\n try {\n const queryString = new URLSearchParams(params).toString();\n const resp = await fetch(`https://api.peopledatalabs.com/v5/person/enrich?${queryString}`, {\n method: \"GET\",\n headers: {\n \"X-Api-Key\": apiKey,\n \"Accept\": \"application/json\",\n },\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n if (resp.status === 404) {\n return { success: true, data: null, error: \"No enrichment data found for this person\" };\n }\n return { success: false, error: `PDL API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const pdlData = await resp.json();\n\n // Store enrichment profile\n const profile: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n enrichment_source: \"pdl\",\n enrichment_data: pdlData,\n enriched_at: nowISO(),\n updated_at: nowISO(),\n };\n\n // Extract common fields if present\n if (pdlData.full_name) profile.full_name = pdlData.full_name;\n if (pdlData.job_title) profile.job_title = pdlData.job_title;\n if (pdlData.job_company_name) profile.company = pdlData.job_company_name;\n if (pdlData.linkedin_url) profile.linkedin_url = pdlData.linkedin_url;\n if (pdlData.location_name) profile.location = pdlData.location_name;\n if (pdlData.gender) profile.gender = pdlData.gender;\n if (pdlData.birth_year) profile.birth_year = pdlData.birth_year;\n\n // Upsert — update if already exists for this customer+store\n const { data: existing } = await sb.from(\"customer_enrichment_profiles\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .maybeSingle();\n\n let result;\n if (existing) {\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .update(profile)\n .eq(\"id\", existing.id)\n .select()\n .single();\n result = { data, error };\n } else {\n profile.created_at = nowISO();\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .insert(profile)\n .select()\n .single();\n result = { data, error };\n }\n\n if (result.error) return { success: false, error: `Failed to store enrichment: ${result.error.message}` };\n return { success: true, data: result.data };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `PDL enrichment failed: ${msg}` };\n }\n }\n\n // ---- ENRICH_LINKEDIN: Bright Data LinkedIn scraper ----\n case \"enrich_linkedin\": {\n const customerId = args.customer_id as string;\n const linkedinUrl = args.linkedin_url as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!linkedinUrl) return { success: false, error: \"linkedin_url is required\" };\n\n const apiKey = await getSecret(sb, \"brightdata_api_key\", sid);\n if (!apiKey) return { success: false, error: \"Bright Data API key not configured. Add 'brightdata_api_key' to store secrets.\" };\n\n const datasetId = await getSecret(sb, \"brightdata_dataset_id\", sid) || \"gd_l1viktl72bvl7bjuj0\";\n\n try {\n // Bright Data Scraper API — synchronous LinkedIn profile collection\n const resp = await fetch(`https://api.brightdata.com/datasets/v3/scrape?dataset_id=${datasetId}&notify=false&include_errors=true`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ input: [{ url: linkedinUrl }] }),\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n if (resp.status === 404) {\n return { success: true, data: null, error: \"No LinkedIn profile found at this URL\" };\n }\n return { success: false, error: `Bright Data API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const bdResult = await resp.json();\n // Bright Data returns an array of results\n const profileData = Array.isArray(bdResult) ? bdResult[0] : bdResult;\n\n if (!profileData || profileData.error) {\n return { success: true, data: null, error: profileData?.error || \"No data returned for this profile\" };\n }\n\n // Store as enrichment profile with source=brightdata\n const profile: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n enrichment_source: \"brightdata\",\n enrichment_data: profileData,\n enriched_at: nowISO(),\n updated_at: nowISO(),\n };\n\n // Extract common fields from Bright Data response\n if (profileData.name || profileData.full_name) profile.full_name = profileData.name || profileData.full_name;\n if (profileData.position || profileData.job_title) profile.job_title = profileData.position || profileData.job_title;\n if (profileData.current_company || profileData.company) profile.company = profileData.current_company || profileData.company;\n if (profileData.headline) profile.headline = profileData.headline;\n if (profileData.location) profile.location = profileData.location;\n profile.linkedin_url = linkedinUrl;\n\n // Upsert — update if already exists for this customer+store+source\n const { data: existing } = await sb.from(\"customer_enrichment_profiles\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .eq(\"enrichment_source\", \"brightdata\")\n .maybeSingle();\n\n let result;\n if (existing) {\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .update(profile)\n .eq(\"id\", existing.id)\n .select()\n .single();\n result = { data, error };\n } else {\n profile.created_at = nowISO();\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .insert(profile)\n .select()\n .single();\n result = { data, error };\n }\n\n if (result.error) return { success: false, error: `Failed to store enrichment: ${result.error.message}` };\n return { success: true, data: result.data };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `Bright Data enrichment failed: ${msg}` };\n }\n }\n\n // ---- CHECK_XONPLUS: xonPlus real-time breach monitoring ----\n case \"check_xonplus\": {\n const customerId = args.customer_id as string;\n const email = args.email as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!email) return { success: false, error: \"email is required\" };\n\n const apiKey = await getSecret(sb, \"xonplus_api_key\", sid);\n if (!apiKey) return { success: false, error: \"xonPlus API key not configured. Add 'xonplus_api_key' to store secrets.\" };\n\n try {\n const resp = await fetch(`https://api.xposedornot.com/v1/check-email/${encodeURIComponent(email)}`, {\n method: \"GET\",\n headers: {\n \"x-api-key\": apiKey,\n Accept: \"application/json\",\n },\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n if (resp.status === 404) {\n return { success: true, data: { email, total_breaches: 0, breaches: [] } };\n }\n return { success: false, error: `xonPlus API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const xonData = await resp.json();\n const breaches = (xonData.breaches || xonData.ExposedBreaches?.breaches_details || []) as Record<string, unknown>[];\n\n // Store each breach record\n const inserted: unknown[] = [];\n for (const breach of breaches) {\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n breach_name: breach.breach || breach.name || \"unknown\",\n breach_domain: breach.domain || null,\n breach_date: breach.xposed_date || breach.date || null,\n data_classes: breach.xposed_data ? (breach.xposed_data as string).split(\",\").map((s: string) => s.trim()) : null,\n breach_source: \"xonplus\",\n raw_data: breach,\n discovered_at: nowISO(),\n created_at: nowISO(),\n };\n\n // Deduplicate by customer_id + breach_name + breach_source\n const { data: existing } = await sb.from(\"customer_breach_records\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"breach_name\", record.breach_name as string)\n .eq(\"breach_source\", \"xonplus\")\n .maybeSingle();\n\n if (!existing) {\n const { data, error } = await sb.from(\"customer_breach_records\")\n .insert(record)\n .select()\n .single();\n if (!error && data) inserted.push(data);\n }\n }\n\n return {\n success: true,\n data: {\n email,\n total_breaches: breaches.length,\n new_breaches: inserted.length,\n risk_metrics: xonData.BreachMetrics || null,\n breaches: inserted.length > 0 ? inserted : breaches,\n },\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `xonPlus breach check failed: ${msg}` };\n }\n }\n\n // ---- CHECK_BREACHES: HIBP Breach Check ----\n case \"check_breaches\": {\n const customerId = args.customer_id as string;\n const email = args.email as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!email) return { success: false, error: \"email is required\" };\n\n const apiKey = await getSecret(sb, \"hibp_api_key\", sid);\n if (!apiKey) return { success: false, error: \"HIBP API key not configured. Add 'hibp_api_key' to store secrets.\" };\n\n try {\n const resp = await fetch(`https://haveibeenpwned.com/api/v3/breachedaccount/${encodeURIComponent(email)}?truncateResponse=false`, {\n method: \"GET\",\n headers: {\n \"hibp-api-key\": apiKey,\n \"User-Agent\": \"WhaleTools-DataProtection\",\n Accept: \"application/json\",\n },\n });\n\n let breaches: unknown[] = [];\n if (resp.status === 404) {\n // No breaches found — that's good\n breaches = [];\n } else if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n return { success: false, error: `HIBP API error ${resp.status}: ${text.substring(0, 500)}` };\n } else {\n breaches = await resp.json();\n }\n\n // Store each breach record\n const inserted: unknown[] = [];\n for (const breach of breaches as Record<string, unknown>[]) {\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n breach_name: breach.Name,\n breach_domain: breach.Domain,\n breach_date: breach.BreachDate,\n data_classes: breach.DataClasses,\n description: breach.Description,\n is_verified: breach.IsVerified,\n breach_source: \"hibp\",\n discovered_at: nowISO(),\n created_at: nowISO(),\n };\n\n // Upsert by customer_id + breach_name to avoid duplicates\n const { data: existing } = await sb.from(\"customer_breach_records\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"breach_name\", breach.Name as string)\n .maybeSingle();\n\n if (!existing) {\n const { data, error } = await sb.from(\"customer_breach_records\")\n .insert(record)\n .select()\n .single();\n if (!error && data) inserted.push(data);\n }\n }\n\n return {\n success: true,\n data: {\n email,\n total_breaches: breaches.length,\n new_breaches: inserted.length,\n breaches: inserted.length > 0 ? inserted : breaches,\n },\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `HIBP breach check failed: ${msg}` };\n }\n }\n\n // ---- CHECK_DEHASHED: DeHashed credential exposure search ----\n case \"check_dehashed\": {\n const customerId = args.customer_id as string;\n const email = args.email as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!email) return { success: false, error: \"email is required\" };\n\n const apiKey = await getSecret(sb, \"dehashed_api_key\", sid);\n if (!apiKey) return { success: false, error: \"DeHashed API key not configured. Add 'dehashed_api_key' to store secrets.\" };\n\n try {\n const resp = await fetch(\"https://api.dehashed.com/v2/search\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"DeHashed-Api-Key\": apiKey,\n },\n body: JSON.stringify({\n query: `email:\"${email}\"`,\n page: 1,\n size: 100,\n wildcard: false,\n regex: false,\n de_dupe: true,\n }),\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n return { success: false, error: `DeHashed API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const result = await resp.json();\n const entries = (result.entries || []) as Record<string, unknown>[];\n\n // Store each as a breach record with source=dehashed\n const inserted: unknown[] = [];\n for (const entry of entries) {\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n breach_name: entry.database_name || \"unknown\",\n breach_domain: entry.domain || null,\n breach_date: entry.obtained_date || null,\n data_classes: entry.type ? [entry.type] : null,\n breach_source: \"dehashed\",\n raw_data: entry,\n discovered_at: nowISO(),\n created_at: nowISO(),\n };\n\n const { data, error } = await sb.from(\"customer_breach_records\")\n .insert(record)\n .select()\n .single();\n if (!error && data) inserted.push(data);\n }\n\n return {\n success: true,\n data: {\n email,\n total_results: entries.length,\n stored: inserted.length,\n entries: inserted,\n },\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `DeHashed check failed: ${msg}` };\n }\n }\n\n // ---- GET_ENRICHMENT: Read enrichment profiles ----\n case \"get_enrichment\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n let q = sb.from(\"customer_enrichment_profiles\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"enriched_at\", { ascending: false });\n\n if (args.source) q = q.eq(\"enrichment_source\", args.source as string);\n\n const limit = args.limit as number || 10;\n q = q.limit(limit);\n\n const { data, error } = await q;\n return error\n ? { success: false, error: error.message }\n : { success: true, data: { count: data?.length, records: data } };\n }\n\n // ---- GET_BREACHES: Read breach records ----\n case \"get_breaches\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n let q = sb.from(\"customer_breach_records\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"discovered_at\", { ascending: false });\n\n if (args.source) q = q.eq(\"breach_source\", args.source as string);\n\n const limit = args.limit as number || 50;\n q = q.limit(limit);\n\n const { data, error } = await q;\n return error\n ? { success: false, error: error.message }\n : { success: true, data: { count: data?.length, records: data } };\n }\n\n // ---- GET_EXPOSURES: Read broker exposures ----\n case \"get_exposures\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n let q = sb.from(\"customer_exposures\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"first_seen_at\", { ascending: false });\n\n if (args.status) q = q.eq(\"status\", args.status as string);\n if (args.source_name || args.broker) q = q.eq(\"source_name\", (args.source_name || args.broker) as string);\n\n const limit = args.limit as number || 50;\n q = q.limit(limit);\n\n const { data, error } = await q;\n return error\n ? { success: false, error: error.message }\n : { success: true, data: { count: data?.length, records: data } };\n }\n\n // ---- GET_REMOVAL_STATUS: Read removal requests ----\n case \"get_removal_status\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n let q = sb.from(\"customer_removal_requests\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"created_at\", { ascending: false });\n\n if (args.status) q = q.eq(\"status\", args.status as string);\n\n const limit = args.limit as number || 50;\n q = q.limit(limit);\n\n const { data, error } = await q;\n return error\n ? { success: false, error: error.message }\n : { success: true, data: { count: data?.length, records: data } };\n }\n\n // ---- GET_RISK_SCORE: Read latest risk score ----\n case \"get_risk_score\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n const { data, error } = await sb.from(\"customer_risk_scores\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"calculated_at\", { ascending: false })\n .limit(1)\n .maybeSingle();\n\n return error\n ? { success: false, error: error.message }\n : { success: true, data };\n }\n\n // ---- STORE_SCAN_RESULTS: Insert scan results ----\n case \"store_scan_results\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n scan_type: args.scan_type || \"discovery\",\n scan_data: args.scan_data || {},\n broker_count: args.broker_count ?? 0,\n exposure_count: args.exposure_count ?? 0,\n status: args.status || \"completed\",\n created_at: nowISO(),\n };\n\n if (args.scan_id) record.scan_id = args.scan_id;\n if (args.file_path) record.file_path = args.file_path;\n\n const { data, error } = await sb.from(\"customer_scan_results\")\n .insert(record)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to store scan results: ${error.message}` }\n : { success: true, data };\n }\n\n // ---- STORE_EXPOSURE: Insert a broker exposure ----\n case \"store_exposure\": {\n const customerId = args.customer_id as string;\n const sourceName = (args.source_name || args.broker) as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!sourceName) return { success: false, error: \"source_name is required\" };\n\n // Check for existing exposure to avoid duplicates\n const { data: existing } = await sb.from(\"customer_exposures\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .eq(\"source_name\", sourceName)\n .maybeSingle();\n\n if (existing) {\n // Update existing record\n const updates: Record<string, unknown> = {};\n if (args.source_url) updates.source_url = args.source_url;\n if (args.data_types_exposed) updates.data_types_exposed = args.data_types_exposed;\n if (args.status) updates.status = args.status;\n\n const { data, error } = await sb.from(\"customer_exposures\")\n .update(updates)\n .eq(\"id\", existing.id)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to update exposure: ${error.message}` }\n : { success: true, data: { ...data, _note: \"Updated existing exposure record\" } };\n }\n\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n source_name: sourceName,\n source_type: args.source_type || \"data_broker\",\n status: args.status || \"found\",\n first_seen_at: nowISO(),\n created_at: nowISO(),\n };\n\n if (args.source_url) record.source_url = args.source_url;\n if (args.data_types_exposed) record.data_types_exposed = args.data_types_exposed;\n if (args.scan_id) record.scan_id = args.scan_id;\n\n const { data, error } = await sb.from(\"customer_exposures\")\n .insert(record)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to store exposure: ${error.message}` }\n : { success: true, data };\n }\n\n // ---- UPDATE_EXPOSURE_STATUS: Update exposure status ----\n case \"update_exposure_status\": {\n const exposureId = args.exposure_id as string;\n if (!exposureId) return { success: false, error: \"exposure_id is required\" };\n\n const updates: Record<string, unknown> = {};\n if (args.status) updates.status = args.status;\n\n if (args.status === \"removed\") {\n updates.removed_at = nowISO();\n }\n\n const { data, error } = await sb.from(\"customer_exposures\")\n .update(updates)\n .eq(\"id\", exposureId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to update exposure: ${error.message}` }\n : { success: true, data };\n }\n\n // ---- STORE_REMOVAL_REQUEST: Insert a removal request ----\n case \"store_removal_request\": {\n const customerId = args.customer_id as string;\n const brokerName = (args.broker_name || args.source_name || args.broker) as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!brokerName) return { success: false, error: \"source_name is required\" };\n\n const record: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n broker_name: brokerName,\n removal_method: args.removal_method || args.method || \"manual\",\n status: args.status || \"pending\",\n created_at: nowISO(),\n updated_at: nowISO(),\n };\n\n if (args.exposure_id) record.exposure_id = args.exposure_id;\n if (args.request_data) record.request_data = args.request_data;\n if (args.submitted_at) record.submitted_at = args.submitted_at;\n if (args.confirmation_id) record.confirmation_id = args.confirmation_id;\n\n const { data, error } = await sb.from(\"customer_removal_requests\")\n .insert(record)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to store removal request: ${error.message}` }\n : { success: true, data };\n }\n\n // ---- CALCULATE_RISK_SCORE: Compute and store a risk score ----\n case \"calculate_risk_score\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n // Gather data for risk calculation\n const [exposuresResult, breachesResult, removalsResult] = await Promise.all([\n sb.from(\"customer_exposures\")\n .select(\"id, source_name, status\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid),\n sb.from(\"customer_breach_records\")\n .select(\"id, breach_name, data_classes, is_verified\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid),\n sb.from(\"customer_removal_requests\")\n .select(\"id, status, broker_name\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid),\n ]);\n\n const exposures = exposuresResult.data || [];\n const breaches = breachesResult.data || [];\n const removals = removalsResult.data || [];\n\n // Score calculation:\n // - Each active exposure: +10 points\n // - Each removed exposure: -5 points (still contributes slightly)\n // - Each breach: +15 points\n // - Each sensitive breach: +25 points (instead of 15)\n // - Each verified breach: +5 bonus\n // - Each completed removal: -8 points\n // - Base floor: 0, cap: 100\n\n let score = 0;\n\n // Exposure scoring\n const activeExposures = exposures.filter((e: Record<string, unknown>) => e.status !== \"removed\");\n const removedExposures = exposures.filter((e: Record<string, unknown>) => e.status === \"removed\");\n score += activeExposures.length * 10;\n score += removedExposures.length * 2;\n\n // Breach scoring\n for (const breach of breaches) {\n score += 15;\n if (breach.is_verified) {\n score += 5;\n }\n }\n\n // Removal credit\n const completedRemovals = removals.filter((r: Record<string, unknown>) => r.status === \"completed\" || r.status === \"confirmed\");\n score -= completedRemovals.length * 8;\n\n // Clamp to 0-100\n score = Math.max(0, Math.min(100, score));\n\n // Determine risk level\n let riskLevel: string;\n if (score >= 75) riskLevel = \"critical\";\n else if (score >= 50) riskLevel = \"high\";\n else if (score >= 25) riskLevel = \"medium\";\n else riskLevel = \"low\";\n\n const riskRecord: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n overall_score: score,\n risk_level: riskLevel,\n factors: {\n active_exposures: activeExposures.length,\n removed_exposures: removedExposures.length,\n total_breaches: breaches.length,\n completed_removals: completedRemovals.length,\n pending_removals: removals.filter((r: Record<string, unknown>) => r.status === \"pending\").length,\n },\n calculated_at: nowISO(),\n created_at: nowISO(),\n };\n\n const { data, error } = await sb.from(\"customer_risk_scores\")\n .insert(riskRecord)\n .select()\n .single();\n\n return error\n ? { success: false, error: `Failed to store risk score: ${error.message}` }\n : { success: true, data };\n }\n\n default:\n return {\n success: false,\n error: `Unknown enrichment action: ${action}. Valid: enrich_person, enrich_linkedin, check_breaches, check_dehashed, check_xonplus, get_enrichment, get_breaches, get_exposures, get_removal_status, get_risk_score, store_scan_results, store_exposure, update_exposure_status, store_removal_request, calculate_risk_score`,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"enrichment.js","names":["getSecret","sb","name","storeId","data","error","rpc","p_name","p_store_id","nowISO","Date","toISOString","handleEnrichment","args","sid","action","success","customerId","customer_id","apiKey","params","email","phone","first_name","last_name","linkedin_url","profile","location","Object","keys","length","queryString","URLSearchParams","toString","resp","fetch","method","headers","ok","text","catch","status","substring","pdlData","json","store_id","enrichment_source","enrichment_data","enriched_at","updated_at","full_name","job_title","job_company_name","company","location_name","gender","birth_year","existing","from","select","eq","maybeSingle","result","update","id","single","created_at","insert","message","err","msg","Error","String","linkedinUrl","datasetId","Authorization","body","JSON","stringify","input","url","bdResult","profileData","Array","isArray","position","current_company","headline","q","order","ascending","source","limit","count","records"],"sources":["../../../src/server/handlers/enrichment.ts"],"sourcesContent":["// server/handlers/enrichment.ts — Customer enrichment via PDL and Bright Data LinkedIn.\n// All external API keys are fetched via decrypt_secret RPC from encrypted store secrets.\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\n// ---- Helpers ----\n\nasync function getSecret(sb: SupabaseClient, name: string, storeId: string): Promise<string | null> {\n const { data, error } = await sb.rpc(\"decrypt_secret\", { p_name: name, p_store_id: storeId });\n if (error || !data) return null;\n return data as string;\n}\n\nfunction nowISO(): string {\n return new Date().toISOString();\n}\n\n// ---- Main Handler ----\n\nexport async function handleEnrichment(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<{ success: boolean; data?: unknown; error?: string; count?: number; note?: string }> {\n const sid = storeId as string;\n const action = args.action as string;\n\n if (!action) {\n return { success: false, error: \"action is required\" };\n }\n\n switch (action) {\n\n // ---- ENRICH_PERSON: PDL Person Enrichment API ----\n case \"enrich_person\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n const apiKey = await getSecret(sb, \"pdl_api_key\", sid);\n if (!apiKey) return { success: false, error: \"PDL API key not configured. Add 'pdl_api_key' to store secrets.\" };\n\n // Build PDL query params from available identifiers\n const params: Record<string, string> = {};\n if (args.email) params.email = args.email as string;\n if (args.phone) params.phone = args.phone as string;\n if (args.first_name) params.first_name = args.first_name as string;\n if (args.last_name) params.last_name = args.last_name as string;\n if (args.linkedin_url) params.profile = args.linkedin_url as string;\n if (args.location) params.location = args.location as string;\n\n if (Object.keys(params).length === 0) {\n return { success: false, error: \"At least one identifier required: email, phone, first_name+last_name, or linkedin_url\" };\n }\n\n try {\n const queryString = new URLSearchParams(params).toString();\n const resp = await fetch(`https://api.peopledatalabs.com/v5/person/enrich?${queryString}`, {\n method: \"GET\",\n headers: {\n \"X-Api-Key\": apiKey,\n \"Accept\": \"application/json\",\n },\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n if (resp.status === 404) {\n return { success: true, data: null, error: \"No enrichment data found for this person\" };\n }\n return { success: false, error: `PDL API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const pdlData = await resp.json();\n\n // Store enrichment profile\n const profile: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n enrichment_source: \"pdl\",\n enrichment_data: pdlData,\n enriched_at: nowISO(),\n updated_at: nowISO(),\n };\n\n // Extract common fields if present\n if (pdlData.full_name) profile.full_name = pdlData.full_name;\n if (pdlData.job_title) profile.job_title = pdlData.job_title;\n if (pdlData.job_company_name) profile.company = pdlData.job_company_name;\n if (pdlData.linkedin_url) profile.linkedin_url = pdlData.linkedin_url;\n if (pdlData.location_name) profile.location = pdlData.location_name;\n if (pdlData.gender) profile.gender = pdlData.gender;\n if (pdlData.birth_year) profile.birth_year = pdlData.birth_year;\n\n // Upsert — update if already exists for this customer+store\n const { data: existing } = await sb.from(\"customer_enrichment_profiles\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .maybeSingle();\n\n let result;\n if (existing) {\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .update(profile)\n .eq(\"id\", existing.id)\n .select()\n .single();\n result = { data, error };\n } else {\n profile.created_at = nowISO();\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .insert(profile)\n .select()\n .single();\n result = { data, error };\n }\n\n if (result.error) return { success: false, error: `Failed to store enrichment: ${result.error.message}` };\n return { success: true, data: result.data };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `PDL enrichment failed: ${msg}` };\n }\n }\n\n // ---- ENRICH_LINKEDIN: Bright Data LinkedIn scraper ----\n case \"enrich_linkedin\": {\n const customerId = args.customer_id as string;\n const linkedinUrl = args.linkedin_url as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n if (!linkedinUrl) return { success: false, error: \"linkedin_url is required\" };\n\n const apiKey = await getSecret(sb, \"brightdata_api_key\", sid);\n if (!apiKey) return { success: false, error: \"Bright Data API key not configured. Add 'brightdata_api_key' to store secrets.\" };\n\n const datasetId = await getSecret(sb, \"brightdata_dataset_id\", sid) || \"gd_l1viktl72bvl7bjuj0\";\n\n try {\n // Bright Data Scraper API — synchronous LinkedIn profile collection\n const resp = await fetch(`https://api.brightdata.com/datasets/v3/scrape?dataset_id=${datasetId}&notify=false&include_errors=true`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ input: [{ url: linkedinUrl }] }),\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n if (resp.status === 404) {\n return { success: true, data: null, error: \"No LinkedIn profile found at this URL\" };\n }\n return { success: false, error: `Bright Data API error ${resp.status}: ${text.substring(0, 500)}` };\n }\n\n const bdResult = await resp.json();\n // Bright Data returns an array of results\n const profileData = Array.isArray(bdResult) ? bdResult[0] : bdResult;\n\n if (!profileData || profileData.error) {\n return { success: true, data: null, error: profileData?.error || \"No data returned for this profile\" };\n }\n\n // Store as enrichment profile with source=brightdata\n const profile: Record<string, unknown> = {\n customer_id: customerId,\n store_id: sid,\n enrichment_source: \"brightdata\",\n enrichment_data: profileData,\n enriched_at: nowISO(),\n updated_at: nowISO(),\n };\n\n // Extract common fields from Bright Data response\n if (profileData.name || profileData.full_name) profile.full_name = profileData.name || profileData.full_name;\n if (profileData.position || profileData.job_title) profile.job_title = profileData.position || profileData.job_title;\n if (profileData.current_company || profileData.company) profile.company = profileData.current_company || profileData.company;\n if (profileData.headline) profile.headline = profileData.headline;\n if (profileData.location) profile.location = profileData.location;\n profile.linkedin_url = linkedinUrl;\n\n // Upsert — update if already exists for this customer+store+source\n const { data: existing } = await sb.from(\"customer_enrichment_profiles\")\n .select(\"id\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .eq(\"enrichment_source\", \"brightdata\")\n .maybeSingle();\n\n let result;\n if (existing) {\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .update(profile)\n .eq(\"id\", existing.id)\n .select()\n .single();\n result = { data, error };\n } else {\n profile.created_at = nowISO();\n const { data, error } = await sb.from(\"customer_enrichment_profiles\")\n .insert(profile)\n .select()\n .single();\n result = { data, error };\n }\n\n if (result.error) return { success: false, error: `Failed to store enrichment: ${result.error.message}` };\n return { success: true, data: result.data };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, error: `Bright Data enrichment failed: ${msg}` };\n }\n }\n\n // ---- GET_ENRICHMENT: Read enrichment profiles ----\n case \"get_enrichment\": {\n const customerId = args.customer_id as string;\n if (!customerId) return { success: false, error: \"customer_id is required\" };\n\n let q = sb.from(\"customer_enrichment_profiles\")\n .select(\"*\")\n .eq(\"customer_id\", customerId)\n .eq(\"store_id\", sid)\n .order(\"enriched_at\", { ascending: false });\n\n if (args.source) q = q.eq(\"enrichment_source\", args.source as string);\n\n const limit = args.limit as number || 10;\n q = q.limit(limit);\n\n const { data, error } = await q;\n return error\n ? { success: false, error: error.message }\n : { success: true, data: { count: data?.length, records: data } };\n }\n\n default:\n return {\n success: false,\n error: `Unknown enrichment action: ${action}. Valid: enrich_person, enrich_linkedin, get_enrichment`,\n };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,9 @@
1
+ import type { SupabaseClient } from "@supabase/supabase-js";
2
+ type Result = {
3
+ success: boolean;
4
+ data?: unknown;
5
+ error?: string;
6
+ [key: string]: unknown;
7
+ };
8
+ export declare function handleFulfillment(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
9
+ export {};
@@ -0,0 +1,209 @@
1
+ // server/handlers/fulfillment.ts — Fulfillment creation, shipment tracking, status updates
2
+
3
+ export async function handleFulfillment(sb, args, storeId) {
4
+ const sid = storeId;
5
+ switch (args.action) {
6
+ // ---- LIST: list fulfillments for an order or store ----
7
+ case "list":
8
+ {
9
+ let q = sb.from("fulfillments").select("*, items:fulfillment_items(id, order_item_id, quantity, picked_at, packed_at)").order("created_at", {
10
+ ascending: false
11
+ });
12
+ if (args.order_id) q = q.eq("order_id", args.order_id);
13
+ if (args.status) q = q.eq("status", args.status);
14
+ if (args.type) q = q.eq("type", args.type);
15
+ q = q.limit(args.limit || 50);
16
+ const {
17
+ data,
18
+ error
19
+ } = await q;
20
+ return error ? {
21
+ success: false,
22
+ error: error.message
23
+ } : {
24
+ success: true,
25
+ count: data?.length,
26
+ data
27
+ };
28
+ }
29
+
30
+ // ---- GET: get a single fulfillment with items ----
31
+ case "get":
32
+ {
33
+ const fulfillmentId = args.fulfillment_id;
34
+ if (!fulfillmentId) return {
35
+ success: false,
36
+ error: "fulfillment_id is required"
37
+ };
38
+ const {
39
+ data,
40
+ error
41
+ } = await sb.from("fulfillments").select("*, items:fulfillment_items(*, order_item:order_items(product_name, quantity, unit_price))").eq("id", fulfillmentId).single();
42
+ return error ? {
43
+ success: false,
44
+ error: error.message
45
+ } : {
46
+ success: true,
47
+ data
48
+ };
49
+ }
50
+
51
+ // ---- CREATE: create a fulfillment for an order ----
52
+ case "create":
53
+ {
54
+ const orderId = args.order_id;
55
+ const fulfillmentType = args.type;
56
+ if (!orderId || !fulfillmentType) {
57
+ return {
58
+ success: false,
59
+ error: "order_id and type are required"
60
+ };
61
+ }
62
+
63
+ // Verify order belongs to this store
64
+ const {
65
+ data: order
66
+ } = await sb.from("orders").select("id").eq("id", orderId).eq("store_id", sid).single();
67
+ if (!order) return {
68
+ success: false,
69
+ error: "Order not found in this store"
70
+ };
71
+ const record = {
72
+ order_id: orderId,
73
+ type: fulfillmentType,
74
+ status: "pending"
75
+ };
76
+ if (args.delivery_location_id) record.delivery_location_id = args.delivery_location_id;
77
+ if (args.delivery_address) record.delivery_address = args.delivery_address;
78
+ if (args.carrier) record.carrier = args.carrier;
79
+ if (args.tracking_number) record.tracking_number = args.tracking_number;
80
+ if (args.tracking_url) record.tracking_url = args.tracking_url;
81
+ if (args.shipping_service) record.shipping_service = args.shipping_service;
82
+ if (args.shipping_cost !== undefined) record.shipping_cost = args.shipping_cost;
83
+ const {
84
+ data,
85
+ error
86
+ } = await sb.from("fulfillments").insert(record).select().single();
87
+ if (error) return {
88
+ success: false,
89
+ error: error.message
90
+ };
91
+
92
+ // Add fulfillment items if provided
93
+ const items = args.items;
94
+ if (items && Array.isArray(items) && items.length > 0) {
95
+ const itemRecords = items.map(item => ({
96
+ fulfillment_id: data.id,
97
+ order_item_id: item.order_item_id,
98
+ source_location_id: item.source_location_id,
99
+ quantity: item.quantity
100
+ }));
101
+ await sb.from("fulfillment_items").insert(itemRecords);
102
+ }
103
+ return {
104
+ success: true,
105
+ data
106
+ };
107
+ }
108
+
109
+ // ---- UPDATE_STATUS: update fulfillment status and timestamps ----
110
+ case "update_status":
111
+ {
112
+ const fulfillmentId = args.fulfillment_id;
113
+ const status = args.status;
114
+ if (!fulfillmentId || !status) {
115
+ return {
116
+ success: false,
117
+ error: "fulfillment_id and status are required"
118
+ };
119
+ }
120
+ const updates = {
121
+ status
122
+ };
123
+ const now = new Date().toISOString();
124
+
125
+ // Set appropriate timestamps based on status
126
+ switch (status) {
127
+ case "allocated":
128
+ updates.allocated_at = now;
129
+ break;
130
+ case "picked":
131
+ updates.picked_at = now;
132
+ break;
133
+ case "packed":
134
+ updates.packed_at = now;
135
+ break;
136
+ case "shipped":
137
+ updates.shipped_at = now;
138
+ break;
139
+ case "delivered":
140
+ updates.delivered_at = now;
141
+ break;
142
+ case "cancelled":
143
+ updates.cancelled_at = now;
144
+ break;
145
+ }
146
+ if (args.carrier) updates.carrier = args.carrier;
147
+ if (args.tracking_number) updates.tracking_number = args.tracking_number;
148
+ if (args.tracking_url) updates.tracking_url = args.tracking_url;
149
+ const {
150
+ data,
151
+ error
152
+ } = await sb.from("fulfillments").update(updates).eq("id", fulfillmentId).select().single();
153
+ if (error) return {
154
+ success: false,
155
+ error: error.message
156
+ };
157
+
158
+ // If shipped or delivered, update the order's fulfillment_status
159
+ if (status === "shipped" || status === "delivered") {
160
+ const orderId = data.order_id;
161
+ await sb.from("orders").update({
162
+ fulfillment_status: status === "delivered" ? "delivered" : "shipped"
163
+ }).eq("id", orderId).eq("store_id", sid);
164
+ }
165
+ return {
166
+ success: true,
167
+ data
168
+ };
169
+ }
170
+
171
+ // ---- ADD_TRACKING: add tracking info to an existing fulfillment ----
172
+ case "add_tracking":
173
+ {
174
+ const fulfillmentId = args.fulfillment_id;
175
+ if (!fulfillmentId) return {
176
+ success: false,
177
+ error: "fulfillment_id is required"
178
+ };
179
+ const updates = {};
180
+ if (args.carrier) updates.carrier = args.carrier;
181
+ if (args.tracking_number) updates.tracking_number = args.tracking_number;
182
+ if (args.tracking_url) updates.tracking_url = args.tracking_url;
183
+ if (args.shipping_label_url) updates.shipping_label_url = args.shipping_label_url;
184
+ if (Object.keys(updates).length === 0) {
185
+ return {
186
+ success: false,
187
+ error: "At least one tracking field is required (carrier, tracking_number, tracking_url)"
188
+ };
189
+ }
190
+ const {
191
+ data,
192
+ error
193
+ } = await sb.from("fulfillments").update(updates).eq("id", fulfillmentId).select().single();
194
+ return error ? {
195
+ success: false,
196
+ error: error.message
197
+ } : {
198
+ success: true,
199
+ data
200
+ };
201
+ }
202
+ default:
203
+ return {
204
+ success: false,
205
+ error: `Unknown fulfillment action: ${args.action}. Valid: list, get, create, update_status, add_tracking`
206
+ };
207
+ }
208
+ }
209
+ //# sourceMappingURL=fulfillment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fulfillment.js","names":["handleFulfillment","sb","args","storeId","sid","action","q","from","select","order","ascending","order_id","eq","status","type","limit","data","error","success","message","count","length","fulfillmentId","fulfillment_id","single","orderId","fulfillmentType","record","delivery_location_id","delivery_address","carrier","tracking_number","tracking_url","shipping_service","shipping_cost","undefined","insert","items","Array","isArray","itemRecords","map","item","id","order_item_id","source_location_id","quantity","updates","now","Date","toISOString","allocated_at","picked_at","packed_at","shipped_at","delivered_at","cancelled_at","update","fulfillment_status","shipping_label_url","Object","keys"],"sources":["../../../src/server/handlers/fulfillment.ts"],"sourcesContent":["// server/handlers/fulfillment.ts — Fulfillment creation, shipment tracking, status updates\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleFulfillment(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list fulfillments for an order or store ----\n case \"list\": {\n let q = sb.from(\"fulfillments\")\n .select(\"*, items:fulfillment_items(id, order_item_id, quantity, picked_at, packed_at)\")\n .order(\"created_at\", { ascending: false });\n if (args.order_id) q = q.eq(\"order_id\", args.order_id as string);\n if (args.status) q = q.eq(\"status\", args.status as string);\n if (args.type) q = q.eq(\"type\", args.type as string);\n q = q.limit(args.limit as number || 50);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get a single fulfillment with items ----\n case \"get\": {\n const fulfillmentId = args.fulfillment_id as string;\n if (!fulfillmentId) return { success: false, error: \"fulfillment_id is required\" };\n const { data, error } = await sb.from(\"fulfillments\")\n .select(\"*, items:fulfillment_items(*, order_item:order_items(product_name, quantity, unit_price))\")\n .eq(\"id\", fulfillmentId)\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- CREATE: create a fulfillment for an order ----\n case \"create\": {\n const orderId = args.order_id as string;\n const fulfillmentType = args.type as string;\n if (!orderId || !fulfillmentType) {\n return { success: false, error: \"order_id and type are required\" };\n }\n\n // Verify order belongs to this store\n const { data: order } = await sb.from(\"orders\")\n .select(\"id\")\n .eq(\"id\", orderId)\n .eq(\"store_id\", sid)\n .single();\n if (!order) return { success: false, error: \"Order not found in this store\" };\n\n const record: Record<string, unknown> = {\n order_id: orderId,\n type: fulfillmentType,\n status: \"pending\",\n };\n if (args.delivery_location_id) record.delivery_location_id = args.delivery_location_id;\n if (args.delivery_address) record.delivery_address = args.delivery_address;\n if (args.carrier) record.carrier = args.carrier;\n if (args.tracking_number) record.tracking_number = args.tracking_number;\n if (args.tracking_url) record.tracking_url = args.tracking_url;\n if (args.shipping_service) record.shipping_service = args.shipping_service;\n if (args.shipping_cost !== undefined) record.shipping_cost = args.shipping_cost;\n\n const { data, error } = await sb.from(\"fulfillments\")\n .insert(record)\n .select()\n .single();\n if (error) return { success: false, error: error.message };\n\n // Add fulfillment items if provided\n const items = args.items as Array<{ order_item_id: string; source_location_id: string; quantity: number }> | undefined;\n if (items && Array.isArray(items) && items.length > 0) {\n const itemRecords = items.map(item => ({\n fulfillment_id: (data as any).id,\n order_item_id: item.order_item_id,\n source_location_id: item.source_location_id,\n quantity: item.quantity,\n }));\n await sb.from(\"fulfillment_items\").insert(itemRecords);\n }\n\n return { success: true, data };\n }\n\n // ---- UPDATE_STATUS: update fulfillment status and timestamps ----\n case \"update_status\": {\n const fulfillmentId = args.fulfillment_id as string;\n const status = args.status as string;\n if (!fulfillmentId || !status) {\n return { success: false, error: \"fulfillment_id and status are required\" };\n }\n\n const updates: Record<string, unknown> = { status };\n const now = new Date().toISOString();\n\n // Set appropriate timestamps based on status\n switch (status) {\n case \"allocated\": updates.allocated_at = now; break;\n case \"picked\": updates.picked_at = now; break;\n case \"packed\": updates.packed_at = now; break;\n case \"shipped\": updates.shipped_at = now; break;\n case \"delivered\": updates.delivered_at = now; break;\n case \"cancelled\": updates.cancelled_at = now; break;\n }\n\n if (args.carrier) updates.carrier = args.carrier;\n if (args.tracking_number) updates.tracking_number = args.tracking_number;\n if (args.tracking_url) updates.tracking_url = args.tracking_url;\n\n const { data, error } = await sb.from(\"fulfillments\")\n .update(updates)\n .eq(\"id\", fulfillmentId)\n .select()\n .single();\n\n if (error) return { success: false, error: error.message };\n\n // If shipped or delivered, update the order's fulfillment_status\n if (status === \"shipped\" || status === \"delivered\") {\n const orderId = (data as any).order_id;\n await sb.from(\"orders\")\n .update({ fulfillment_status: status === \"delivered\" ? \"delivered\" : \"shipped\" })\n .eq(\"id\", orderId)\n .eq(\"store_id\", sid);\n }\n\n return { success: true, data };\n }\n\n // ---- ADD_TRACKING: add tracking info to an existing fulfillment ----\n case \"add_tracking\": {\n const fulfillmentId = args.fulfillment_id as string;\n if (!fulfillmentId) return { success: false, error: \"fulfillment_id is required\" };\n const updates: Record<string, unknown> = {};\n if (args.carrier) updates.carrier = args.carrier;\n if (args.tracking_number) updates.tracking_number = args.tracking_number;\n if (args.tracking_url) updates.tracking_url = args.tracking_url;\n if (args.shipping_label_url) updates.shipping_label_url = args.shipping_label_url;\n\n if (Object.keys(updates).length === 0) {\n return { success: false, error: \"At least one tracking field is required (carrier, tracking_number, tracking_url)\" };\n }\n\n const { data, error } = await sb.from(\"fulfillments\")\n .update(updates)\n .eq(\"id\", fulfillmentId)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n default:\n return { success: false, error: `Unknown fulfillment action: ${args.action}. Valid: list, get, create, update_status, add_tracking` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Google Ads Handler — campaign/ad group/ad/keyword CRUD + publish to Google Ads API v23.
3
+ *
4
+ * Mirrors the Meta Ads handler pattern:
5
+ * - Draft objects stored in Supabase with local UUIDs
6
+ * - Publish pushes drafts to Google Ads API
7
+ * - Sync pulls metrics from Google Ads into local DB
8
+ * - GAQL queries for custom reporting
9
+ *
10
+ * Actions:
11
+ * create_campaign, list_campaigns, get_campaign, update_campaign, delete_campaign,
12
+ * create_ad_group, list_ad_groups, get_ad_group, update_ad_group,
13
+ * create_ad, list_ads, get_ad, update_ad,
14
+ * create_keyword, list_keywords, update_keyword, delete_keyword,
15
+ * publish, sync, search (GAQL), list_accessible_customers,
16
+ * keyword_ideas, create_conversion_action, list_conversion_actions,
17
+ * create_audience, list_audiences, pause, enable
18
+ */
19
+ import type { SupabaseClient } from "@supabase/supabase-js";
20
+ export declare function handleGoogleAds(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<{
21
+ success: boolean;
22
+ data?: unknown;
23
+ error?: string;
24
+ }>;