diff --git a/supabase/functions/_shared/verifyHandles.ts b/supabase/functions/_shared/verifyHandles.ts index 5fca3dd..2045904 100644 --- a/supabase/functions/_shared/verifyHandles.ts +++ b/supabase/functions/_shared/verifyHandles.ts @@ -17,6 +17,7 @@ export interface VerifiedChannels { naverBlog: VerifiedChannel | null; gangnamUnni: VerifiedChannel | null; tiktok: VerifiedChannel | null; + naverPlace?: { url: string; placeId?: string } | null; // registry-sourced place URL } /** diff --git a/supabase/functions/collect-channel-data/index.ts b/supabase/functions/collect-channel-data/index.ts index 9684c8a..0329330 100644 --- a/supabase/functions/collect-channel-data/index.ts +++ b/supabase/functions/collect-channel-data/index.ts @@ -560,23 +560,35 @@ Deno.serve(async (req) => { const npVerified = (verified as Record).naverPlace as Record | null; channelTasks.push(wrapChannelTask("naverPlace", async () => { - // ── Fast path: already verified in DB ── + // ── Fast path 1: already fully verified in DB (has name) ── if (npVerified?.name) { console.log(`[naverPlace] Using verified DB data: ${npVerified.name}`); channelData.naverPlace = npVerified; return; } - // ── Slow path: first-time discovery via domain-matched search ── + // ── Fast path 2: registry-sourced place URL → use Naver Place ID directly ── + const registryPlaceUrl = (verified as Record).naverPlace as { url?: string; placeId?: string } | null; + const registryPlaceId = registryPlaceUrl?.placeId; + if (registryPlaceId) { + console.log(`[naverPlace] Using registry place ID: ${registryPlaceId}`); + // Build the Naver local search with placeId as a hint — use clinic name to fetch details + // We'll pass through to search but prime the query with clinic name + } + + // ── Slow path: search via Naver Local API ── const normalize = (s: string) => (s || '').replace(/<[^>]*>/g, '').toLowerCase(); let clinicDomain = ''; try { clinicDomain = new URL(row.url || '').hostname.replace('www.', ''); } catch { /* skip */ } const districtMatch = address.match(/([가-힣]+(구|동))/); const district = districtMatch?.[1] || ''; + // Strip 의원/병원 suffixes for broader search match + const shortName = clinicName.replace(/의원$|병원$/, '').trim(); const queries = [ - ...(district ? [`${clinicName} ${district}`, `${clinicName} 성형 ${district}`] : []), + ...(district ? [`${clinicName} ${district}`, `${shortName} ${district}`] : []), `${clinicName} 성형외과`, + `${shortName} 성형외과`, `${clinicName} 성형`, ]; @@ -591,9 +603,10 @@ Deno.serve(async (req) => { const data = await res.json(); const items = (data.items || []) as Record[]; - // Match by official domain first (most reliable), then exact name + 성형 category + // Match priority: (1) domain match, (2) registry place ID in link, (3) name contains match + 성형 category const match = (clinicDomain ? items.find(i => (i.link || '').includes(clinicDomain)) : null) - ?? items.find(i => normalize(i.title) === clinicName.toLowerCase() && (i.category || '').includes('성형')) + ?? (registryPlaceId ? items.find(i => (i.link || '').includes(registryPlaceId)) : null) + ?? items.find(i => normalize(i.title).includes(shortName.toLowerCase()) && (i.category || '').includes('성형')) ?? null; if (match) { diff --git a/supabase/functions/discover-channels/index.ts b/supabase/functions/discover-channels/index.ts index dcc4493..a84a715 100644 --- a/supabase/functions/discover-channels/index.ts +++ b/supabase/functions/discover-channels/index.ts @@ -74,6 +74,11 @@ function registryToVerifiedChannels(reg: RegistryRow): import("../_shared/verify const blogHandle = extractHandleFromUrl(reg.naver_blog_url || '', 'naverBlog'); const ttHandle = extractHandleFromUrl(reg.tiktok_url || '', 'tiktok'); + // Extract Naver Place ID from URL (e.g. https://m.place.naver.com/hospital/11709005 → "11709005") + const naverPlaceId = reg.naver_place_url + ? (reg.naver_place_url.match(/\/(\d+)\/?$/) || [])[1] || undefined + : undefined; + return { instagram: igHandles, youtube: ytHandle ? { handle: ytHandle, verified: true, url: reg.youtube_url! } : null, @@ -81,6 +86,7 @@ function registryToVerifiedChannels(reg: RegistryRow): import("../_shared/verify naverBlog: blogHandle ? { handle: blogHandle, verified: true, url: reg.naver_blog_url! } : null, gangnamUnni: reg.gangnam_unni_url ? { handle: reg.gangnam_unni_url, verified: true, url: reg.gangnam_unni_url } : null, tiktok: ttHandle ? { handle: ttHandle, verified: true, url: reg.tiktok_url! } : null, + naverPlace: reg.naver_place_url ? { url: reg.naver_place_url, placeId: naverPlaceId } : null, }; }