fix: 플로우 테스터 API 로그 오류 카운트 로직 수정

- 오류 카운트 기준: HTTP 상태 → 스텝 실패 여부로 변경
- expect로 4xx 기대하고 성공한 경우 오류로 카운트 안 함
- HTTP 4xx/5xx 응답은 주황색(amber)으로 시각적 구분

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 17:00:41 +09:00
parent 88089aabae
commit 20d92ea51b

View File

@@ -72,7 +72,7 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
</div>
<!-- 플로우 목록 -->
<div class="bg-white rounded-lg shadow-sm overflow-hidden">
<div class="bg-white rounded-lg shadow-sm overflow-x-auto">
@if($flows->isEmpty())
<div class="text-center py-12 text-gray-500">
<svg class="w-16 h-16 mx-auto mb-4 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -580,7 +580,7 @@ function showResultModal(data) {
</div>
` : ''}
${getApiLogSummary(result.apiLogs)}
${getApiLogSummary(result.apiLogs, result.executionLog)}
<div class="flex gap-3">
<button onclick="this.closest('.fixed').remove(); location.reload();"
@@ -599,22 +599,27 @@ class="flex-1 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-center rou
}
// API 로그 요약 생성
function getApiLogSummary(apiLogs) {
// executionLog: 스텝 실행 결과 (성공 여부 판단 기준)
function getApiLogSummary(apiLogs, executionLog = []) {
if (!apiLogs || apiLogs.length === 0) {
return '';
}
// Request/Response 분리 및 에러 카운트
// 실행 로그에서 실패한 스텝만 추출 (스텝이 실패한 경우만 진짜 오류)
const failedSteps = (executionLog || []).filter(step => !step.success && !step.skipped);
const actualErrorCount = failedSteps.length;
const hasErrors = actualErrorCount > 0;
// Request/Response 분리
const requests = apiLogs.filter(l => l.type === 'request');
const responses = apiLogs.filter(l => l.type === 'response');
const errors = responses.filter(l => (l.status || 0) >= 400 || l.success === false);
const hasErrors = errors.length > 0;
// 최대 3개만 표시
const displayLogs = apiLogs.slice(0, 6);
const logItems = displayLogs.map(log => {
const isRequest = log.type === 'request';
const isError = !isRequest && ((log.status || 0) >= 400 || log.success === false);
// HTTP 4xx/5xx는 시각적으로 구분하되, 스텝이 성공이면 경고(주황) 표시
const isHttpError = !isRequest && (log.status || 0) >= 400;
if (isRequest) {
return `<div class="flex items-center gap-2 py-1 text-sm">
@@ -622,11 +627,13 @@ function getApiLogSummary(apiLogs) {
<code class="text-gray-700 text-xs">${log.method || ''} ${log.uri || ''}</code>
</div>`;
} else {
return `<div class="flex items-center gap-2 py-1 text-sm ${isError ? 'text-red-600' : ''}">
<span class="px-1.5 py-0.5 text-xs font-medium ${isError ? 'bg-red-100 text-red-700' : 'bg-green-100 text-green-700'} rounded">RES</span>
<span class="px-1.5 py-0.5 text-xs font-medium ${isError ? 'bg-red-600' : 'bg-green-600'} text-white rounded">${log.status || '-'}</span>
// 스텝 성공 여부와 관계없이 HTTP 상태만 시각적으로 표시
const statusColor = isHttpError ? 'bg-amber-500' : 'bg-green-600';
const badgeColor = isHttpError ? 'bg-amber-100 text-amber-700' : 'bg-green-100 text-green-700';
return `<div class="flex items-center gap-2 py-1 text-sm">
<span class="px-1.5 py-0.5 text-xs font-medium ${badgeColor} rounded">RES</span>
<span class="px-1.5 py-0.5 text-xs font-medium ${statusColor} text-white rounded">${log.status || '-'}</span>
<code class="text-gray-500 text-xs truncate">${log.uri || ''}</code>
${isError && log.message ? `<span class="text-red-500 text-xs">${log.message}</span>` : ''}
</div>`;
}
}).join('');
@@ -638,7 +645,7 @@ function getApiLogSummary(apiLogs) {
<h4 class="text-sm font-medium text-gray-700 mb-2 flex items-center gap-2">
API 로그
<span class="text-xs font-normal text-gray-400">(${responses.length}개 응답)</span>
${hasErrors ? `<span class="px-1.5 py-0.5 text-xs font-medium bg-red-100 text-red-700 rounded">${errors.length} 오류</span>` : ''}
${hasErrors ? `<span class="px-1.5 py-0.5 text-xs font-medium bg-red-100 text-red-700 rounded">${actualErrorCount} 오류</span>` : ''}
</h4>
<div class="${hasErrors ? 'bg-red-50 border border-red-200' : 'bg-gray-50'} rounded-lg p-3 max-h-32 overflow-y-auto">
${logItems}