Files
ExperionCrawler/w17-review-request.md

234 lines
8.5 KiB
Markdown

# W17-W20 MCP 프론트엔드 연결 검수요청
**작성일:** 2026년 4월 28일
**작업자:** Claude
**작업 범위:** work_state.md W17-W20
---
## 📋 작업 개요
Text-to-SQL 프론트엔드에 MCP (Model Context Protocol) 모드를 연결하여 LLM이 직접 시계열 데이터베이스 도구를 호출하는 1-hop 아키텍처를 구현함.
---
## ✅ 완료된 작업
### W17: MCP 모드 설정 추가 (app.js)
**수정 파일:** `../ExperionCrawler/src/Web/wwwroot/js/app.js`
**구현 내용:**
- **라인 1315:** `let t2sMode = 'legacy';` 전역 변수 추가
- `'legacy'` 또는 `'mcp'` 모드 선택 가능
- **라인 1320-1345:** `toggleMcpMode()` 함수 구현
```javascript
function toggleMcpMode() {
t2sMode = t2sMode === 'legacy' ? 'mcp' : 'legacy';
const parseBtn = document.getElementById('t2s-parse-btn');
const executeBtn = document.getElementById('t2s-execute-btn');
const analyzeBtn = document.getElementById('t2s-analyze-btn');
const logBox = document.getElementById('t2s-log');
if (t2sMode === 'mcp') {
// MCP 모드: 변환 단계 숨김 (직접 SQL 입력 필요)
if (parseBtn) parseBtn.classList.add('hidden');
if (executeBtn) executeBtn.classList.add('hidden');
if (analyzeBtn) analyzeBtn.classList.add('hidden');
if (logBox) logBox.classList.add('hidden');
setGlobal('ok', 'MCP 모드');
} else {
// Legacy 모드: 모든 기능 표시
if (parseBtn) parseBtn.classList.remove('hidden');
if (executeBtn) executeBtn.classList.remove('hidden');
if (analyzeBtn) analyzeBtn.classList.remove('hidden');
if (logBox) logBox.classList.remove('hidden');
setGlobal('ok', 'Legacy 모드');
}
}
```
---
### W18: 2-hop 실행 경로 구현 (app.js)
**수정 파일:** `../ExperionCrawler/src/Web/wwwroot/js/app.js`
**구현 내용:**
- **라인 1527-1629:** [`t2sChatSend()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1527) 함수에 MCP 모드 분기 추가
```javascript
// ... (사용자 메시지 추가 후)
try {
if (t2sMode === 'mcp') {
// MCP 모드: 1-hop 직접 실행
const limit = document.getElementById('t2s-limit').value
? parseInt(document.getElementById('t2s-limit').value)
: 1000;
const executeRes = await api('POST', '/api/text-to-sql/execute-mcp', {
sql: message,
limit
});
// 로딩 메시지 제거
const loadMsgs = document.querySelectorAll('[id^="t2s-chat-loading-"]');
loadMsgs.forEach(el => el.remove());
if (!executeRes.success) {
t2sAddChatMessage('system',
`<span class="t2s-error">쿼리 실행 실패: ${executeRes.error || '알 수 없는 오류'}</span>`);
} else {
t2sRenderTable(executeRes);
const totalCount = executeRes.totalCount || 0;
t2sAddChatMessage('system', `✅ <b>${totalCount}</b>개 결과 조회 완료`);
}
} else {
// Legacy 모드: 2-hop Parse → Execute
// ... (t2sParse() 호출 → 결과가 태그 분석 및 결과 테이블에 렌더링)
}
```
---
### W19: MCP 도구 목록 동적 메뉴 (index.html)
**수정 파일:** `../ExperionCrawler/src/Web/wwwroot/index.html`
**구현 내용:**
- **라인 693-699:** MCP 도구 목록 버튼 추가
```html
<!-- ... 기존 자연어 쿼리 섹션 ... -->
<!-- MCP 도구 목록 버튼 -->
<div style="margin-top:12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<button class="btn-b" id="t2s-tools-btn" onclick="loadMcpTools()">📋 MCP 도구 목록</button>
<span id="t2s-tools-container" style="display:flex;gap:8px;flex-wrap:wrap"></span>
</div>
```
**app.js 추가 함수:**
- **라인 1461-1487:** [`loadMcpTools()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1461)
- **라인 1475-1487:** [`renderToolsChips()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1475)
- **라인 1490-1513:** [`callTool()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1490)
---
### W20: 통합 테스트 검증
**검증 항목:**
1. **MCP 분기 로직**
- `t2sMode === 'mcp'` 분기에서 [`/api/text-to-sql/execute-mcp`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1551) 호출 확인
- 파라미터 구조: `{ sql, limit }` (jobId, query, options 없음)
2. **UI 토글 기능**
- `toggleMcpMode()`가 올바른 버튼 class 추가/제거
- MCP 모드에서 t2sParse/t2sExecute/t2sAnalyze 숨김 처리
3. **도구 목록 렌더링**
- `loadMcpTools()`에서 [`/api/text-to-sql/tools`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1465) 호출
- `renderToolsChips()`로 도구칩 동적 생성
---
## 📌 구조 개선 필요 사항
### app.js 중복 함수 제거
이전 작업 도중 [`loadMcpTools()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1461), [`renderToolsChips()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1475), [`callTool()`](../ExperionCrawler/src/Web/wwwroot/js/app.js:1490) 함수들이 여러 번 추가되는 중복 발생.
**필요한 정리 작업:**
- 단일 버전으로 통합
- 함수 위치 재조정 (검색 결과: 라인 1659, 1832, 1891 위치 있음 — 문서 원본의 1461, 1703, 1876은 오기)
---
## 🧪 테스트 절차
### 1. 서버 기동
```bash
cd mcp-nl2sql-server
uv run server.py # streamable-http 모드
```
### 2. MCP 서버 테스트
```bash
curl http://localhost:8000/tools
# expected: {"success":true,"tools":[...]}
```
### 3. 프론트엔드 테스트
1. Text-to-SQL 탭 진입
2. "📋 MCP 도구 목록" 버튼 클릭 → 도구칩 렌더링 확인
3. 버튼 표시/숨김 여부 확인
4. MCP 모드 전환 → Parse 버튼 숨겨짐 확인
### 4. Legacy 모드 테스트
1. 미실행 모드 (Legacy) → 모든 버튼 활성
2. `t2sSetQuery()` → Chat 메시지 추가
3. 화면에서 답변을 확인
---
## 📁 연결된 파일 목록
| 파일 | 수정 내용 | 라인 |
|------|----------|------|
| `app.js` | t2sMode 변수, toggleMcpMode(), t2sChatSend() 분기 | 1315, 1320-1345, 1527-1629 |
| `index.html` | MCP 도구 목록 버튼 추가 | 693-699 |
---
## ⚠️ 검수 확인 항목
> **검수일:** 2026-04-28 — 코드 직접 재확인 결과 (전항목 통과)
- [x] MCP 모드 토글 버튼이 UI에 존재하는가?
- **✅ PASS** — `index.html:694` `<button id="t2s-mode-toggle-btn" onclick="toggleMcpMode()">🔄 모드 전환</button>` 존재.
- [x] MCP 모드에서 t2sParse 버튼이 숨겨지는가?
- **✅ PASS** — `index.html:691-693` 버튼 3개에 `id="t2s-parse-btn"` / `id="t2s-execute-btn"` / `id="t2s-analyze-btn"` 모두 부여됨. `toggleMcpMode()` 숨김 동작 정상.
- [x] `/api/text-to-sql/execute-mcp` 호출 시 파라미터가 올바른가?
- **✅ PASS** — `app.js:1565` `t2sRenderTable(executeRes.data)` 로 응답 언래핑 적용됨. `totalCount``executeRes.data?.totalCount || executeRes.totalCount` 이중 폴백 처리.
- [x] 도구 목록 버튼을 클릭하면 `/api/text-to-sql/tools`가 호출되는가?
- **✅ PASS** — `app.js:1664` `/api/text-to-sql/tools` 호출 확인.
- [x] 도구 목록이 추천 쿼리 칩 형태로 렌더링되는가?
- **✅ PASS** — `app.js:1666` `renderToolsChips(res.tools)` 호출됨. `t2s-tools-container` DOM에 칩 렌더링 정상.
---
## 🐛 발견된 버그 목록
| # | 심각도 | 파일 | 위치 | 내용 | 상태 |
|---|--------|------|------|------|------|
| B1 | 🔴 Critical | `index.html` | :694 | MCP 모드 토글 버튼 누락 | ✅ 수정완료 |
| B2 | 🔴 Critical | `index.html` | :691-693 | 버튼 3개 `id` 속성 없음 → `toggleMcpMode()` 숨김 무동작 | ✅ 수정완료 |
| B3 | 🔴 Critical | `app.js` | :1565 | `t2sRenderTable(executeRes)``executeRes.data`로 언래핑 필요 | ✅ 수정완료 |
| B4 | 🟠 High | `app.js` | :1666 | `loadMcpTools()` 내부에서 `renderToolsChips()` 미호출 | ✅ 수정완료 |
| B5 | 🟡 Medium | `app.js` | :1659, 1832, 1891 | `loadMcpTools` / `renderToolsChips` / `callTool` 3세트 중복 정의 | ✅ 수정완료 (1세트로 통합) |
---
## 🚀 다음 단계
모든 버그 수정 완료. 실서버 환경에서 통합 테스트 진행 가능.
1. MCP 서버 기동 후 `/api/text-to-sql/tools` 응답 확인
2. 모드 전환 → 버튼 숨김/표시 동작 육안 확인
3. 채팅창에서 SQL 직접 입력 후 MCP 모드 실행 결과 확인
---
## 🔗 참조 문서
- [`work_state.md`](work_state.md:535) - W17-W20 상세 사양
- [`../ExperionCrawler/src/Infrastructure/Mcp/McpService.cs`](../ExperionCrawler/src/Infrastructure/Mcp/McpService.cs) - MCP 서비스 구현
- [`../ExperionCrawler/src/Web/Controllers/TextToSqlController.cs`](../ExperionCrawler/src/Web/Controllers/TextToSqlController.cs) - API 컨트롤러