diff --git a/backend/src/services/festival/index.js b/backend/src/services/festival/index.js index 5901096..62b366a 100644 --- a/backend/src/services/festival/index.js +++ b/backend/src/services/festival/index.js @@ -93,19 +93,32 @@ async function festivalBotPlugin(fastify, opts) { /** * 카카오맵 장소 검색 (실패 시 이름만 가진 venue 반환) + * 서술형 장소명("캐리비안 베이 야외 파도풀 특설무대")은 검색이 안 되므로 + * 뒤 단어부터 하나씩 줄이며 재시도. 축약 매칭 시 표시명은 원본을 유지하고 좌표만 사용. */ async function resolveVenue(query) { - let venue = query ? { name: query } : null; - if (!query) return venue; - try { - const docs = await searchKakaoPlace(query); - if (docs.length > 0) { - venue = kakaoToVenue(docs[0]); + if (!query) return null; + const fallback = { name: query }; + const words = query.trim().split(/\s+/); + for (let n = words.length; n >= 1; n--) { + const q = words.slice(0, n).join(' '); + let docs; + try { + docs = await searchKakaoPlace(q); + } catch (err) { + fastify.log.warn(`[festival] 장소 검색 실패 (${q}): ${err.message}`); + return fallback; + } + if (docs.length > 0) { + const venue = kakaoToVenue(docs[0]); + if (n < words.length) { + venue.name = query; // 더 구체적인 원본 이름 유지 + fastify.log.info(`[festival] 장소 축약 매칭: "${query}" → "${q}" (${docs[0].place_name})`); + } + return venue; } - } catch (err) { - fastify.log.warn(`[festival] 장소 검색 실패 (${query}): ${err.message}`); } - return venue; + return fallback; } /**