MCPcopy Create free account
hub / github.com/adcontextprotocol/adcp / createProspect

Function createProspect

server/src/services/prospect.ts:67–230  ·  view source on GitHub ↗
(
  input: CreateProspectInput
)

Source from the content-addressed store, hash-verified

65 * Auto-enriches the organization if a domain is provided.
66 */
67export async function createProspect(
68 input: CreateProspectInput
69): Promise<CreateProspectResult> {
70 const pool = getPool();
71
72 if (!workos) {
73 return {
74 success: false,
75 error: 'WorkOS not configured',
76 };
77 }
78
79 const name = input.name.trim();
80
81 // Validate prospect_status if provided
82 if (input.prospect_status && !VALID_PROSPECT_STATUSES.includes(input.prospect_status as typeof VALID_PROSPECT_STATUSES[number])) {
83 return {
84 success: false,
85 error: `Invalid prospect_status. Must be one of: ${VALID_PROSPECT_STATUSES.join(', ')}`,
86 };
87 }
88
89 // Normalize domain to lowercase
90 const normalizedDomain = input.domain?.trim().toLowerCase() || null;
91
92 // Check if domain resolves to an existing organization (exact, alias, sub-brand, or redirect)
93 if (normalizedDomain) {
94 const resolved = await resolveOrgByDomain(normalizedDomain);
95 if (resolved) {
96 const isAlias = resolved.matchedDomain !== normalizedDomain;
97 logger.info({ domain: normalizedDomain, matchedDomain: resolved.matchedDomain, method: resolved.method, orgId: resolved.orgId },
98 isAlias ? 'Domain resolves to existing org via alias' : 'Domain already tracked');
99
100 // Fetch actual org details so callers have useful info
101 const orgRow = await pool.query<{ name: string; prospect_status: string | null }>(
102 `SELECT name, prospect_status FROM organizations WHERE workos_organization_id = $1`,
103 [resolved.orgId]
104 );
105 const orgName = orgRow.rows[0]?.name ?? resolved.matchedDomain;
106 return {
107 success: false,
108 error: isAlias ? `Domain resolves to ${orgName} via ${resolved.method}` : `Domain already tracked (${orgName})`,
109 alreadyExists: true,
110 organization: {
111 workos_organization_id: resolved.orgId,
112 name: orgRow.rows[0]?.name ?? resolved.matchedDomain,
113 prospect_status: orgRow.rows[0]?.prospect_status ?? '',
114 },
115 };
116 }
117 }
118
119 // Check for existing organization with same name
120 const existing = await pool.query(
121 `SELECT workos_organization_id, name FROM organizations
122 WHERE LOWER(name) = LOWER($1) AND is_personal = false`,
123 [name]
124 );

Callers 4

setupEnrichmentRoutesFunction · 0.85
setupAccountRoutesFunction · 0.85
triageAndCreateProspectFunction · 0.85
createAdminToolHandlersFunction · 0.85

Calls 8

getPoolFunction · 0.85
resolveOrgByDomainFunction · 0.85
researchDomainFunction · 0.85
trackBackgroundFunction · 0.85
queryMethod · 0.80
createOrganizationMethod · 0.80
warnMethod · 0.80
trimMethod · 0.65

Tested by

no test coverage detected