# LLM 검색 패널 리팩토링: SQL 파서를 걷어내고 conditions 기반으로
## 상황 파악
Response 데이터엔 conditions가 12개 들어있다. 즉 `hasStructuredConditions = true`이고, 이론상 구조화된 렌더링 경로로 가야 한다. 그런데 실제로는 SQL 파싱 경로로 빠진다.
### 왜 SQL 파싱 경로로 가는가
`mergedConditions`가 label 기준으로 merge하는데, 스크린샷 시점의 item 데이터를 보면 DB에서 로드된 이전 턴 아이템 중 `rawJson`/`conditions`가 없는 케이스이거나, `item.response`에 conditions가 없는 형태로 저장된 케이스일 가능성이 있다.
다만 그 근본 원인을 추적하는 것보다, 구조 자체를 단순화하는 게 핵심이다. SQL 파서가 존재하는 한 "구조화 데이터가 있는데도 파서로 빠지는" 분기 자체가 계속 버그의 온상이 된다.
### Response 데이터에서 확인된 문제
SQL WHERE 절에는 `OOO = '숏폼'` 조건이 있지만 conditions 배열에는 빠져 있다. 프롬프트 단에서 조건 누락이 발생하고 있다는 신호다.
---
## 수정 계획
### 1. 프롬프트 수정 (`creatorOOO.js`) — 소규모
`REFINE_OUTPUT_FORMAT`의 conditions label 규칙 부분에 한 줄 보강:
> SQL WHERE 절에 있는 모든 조건(LIKE, =, IN, IS NULL 포함)을 conditions에 포함. OOO 등 누락 없이 전부 반환.
이 한 줄이면 충분하다.
### 2. API 수정 — 없음
### 3. `LlmOOO.jsx` — 대규모 리팩토링
#### 제거
- SQL 파서 함수 전체 (`parseSqlToGroups`, `splitTopLevel`, `stripOuterParens`, `buildGroupedSimpleConditions`)
- `SQL_COLUMN_LABEL` 상수
- `shouldRenderSqlGroups`, `hasSqlGroups`, `sqlGroups`, `hasRealConditions` 관련 변수 및 렌더링 블록
#### 추가: 추정 키워드 컬럼 상수
```js
const ESTIMATED_KEYWORD_COLUMNS = new Set([
'OOO', 'OOO', 'OOO', 'OOO',
'OOO', 'OOO',
'OOO', 'OOO',
'OOO', 'OOO',
]);
```
#### 핵심 로직: conditions를 두 그룹으로 분리
```js
// 1. 추정 키워드 컬럼에 해당하는 conditions → 값 전체 dedup 후 단일 그룹으로
const estimatedColumnConditions = parsed.conditions.filter(
c => ESTIMATED_KEYWORD_COLUMNS.has(c.column)
);
const appliedEstimatedKeywords = [...new Set(
estimatedColumnConditions.flatMap(
c => c.value.split(',').map(v => v.trim()).filter(Boolean)
)
)];
const hasAppliedEstimated = appliedEstimatedKeywords.length > 0;
// 2. 나머지 → label 기준 merge
const regularConditions = parsed.conditions
.filter(c => !ESTIMATED_KEYWORD_COLUMNS.has(c.column))
.reduce((acc, c) => { /* 기존 mergedConditions 로직 */ }, []);
const hasRegularConditions = regularConditions.length > 0;
// 3. 헤더 표시 기준
const showHeader = hasRegularConditions || hasAppliedEstimated || hasPendingKeywords;
```
#### 렌더링 3타입 — 기존 디자인 그대로 재활용
| 타입 | 조건 | UI | 데이터 소스 |
|---|---|---|---|
| 일반 검색 조건 | `hasRegularConditions` | 회색 뱃지 `label: 값1 값2` | `regularConditions` |
| 추정 키워드 검색 적용됨 | `hasAppliedEstimated && isExecuted` | 보라색 실선 뱃지 `추정 키워드: 배그 PUBG ...` | `appliedEstimatedKeywords` |
| 추정 키워드 제안 중 | `hasPendingKeywords` | 기존 보라색 박스 "함께 검색할까요?" | `pendingKeywords` (기존 그대로) |
#### Response 예시 기준 결과물
```
[일반 조건]
라이브 플랫폼: SP CZ AND 숏폼 활성: 활성 AND 지향형: 숏폼
[추정 키워드 — 검색 적용됨]
추정 키워드: 배그 배틀그라운드 PUBG 슈팅 FPS 배틀로얄 배그플레이 배그광고
```
---
## 변경 파일 요약
| 파일 | 규모 |
|---|---|
| `lib/ai/creatorOOO.js` | 소 — conditions 누락 방지 문구 1~2줄 추가 |
| `LlmOOO.jsx` | 대 — SQL 파서 약 200줄 제거, conditions 기반 렌더링 교체 |
일반 조건 컬럼(`OOO` 등)도 `regularConditions`에 포함되어 `지향형: 숏폼` 형태로 출력된다.