/* GUARDiA 고객 포털 JS */ let currentSrId = null; let selectedStar = 0; let pollTimer = null; const STATUS_LABEL = { RECEIVED: "접수됨", PARSED: "분석 중", PENDING_APPROVAL: "승인 대기", APPROVED: "승인됨", IN_PROGRESS: "처리 중", PENDING_PM_VALIDATION: "PM 검증", COMPLETED: "처리 완료", FAILED_ROLLBACK: "처리 실패", REJECTED: "반려", }; const ACTION_LABEL = { CMDB_CHECK: "🔍 자산 확인", SSH_CONNECT: "🔗 서버 접속", SSH_EXEC: "⚡ 명령 실행", SOURCE_MOD: "📦 파일 배포", HEALTH_CHECK: "💓 헬스 체크", RESULT: "📋 결과 기록", COMPLETE: "✅ 완료 처리", }; /* ── 폼 제출 ── */ document.getElementById("sr-form").addEventListener("submit", async e => { e.preventDefault(); const btn = document.getElementById("submit-btn"); const label = document.getElementById("submit-label"); const spinner = document.getElementById("submit-spinner"); btn.disabled = true; label.textContent = "등록 중…"; spinner.classList.remove("hidden"); const fd = new FormData(e.target); const payload = Object.fromEntries(fd.entries()); if (!payload.description) delete payload.description; if (!payload.target_server) delete payload.target_server; try { const res = await fetch("/api/tasks", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (!res.ok) throw new Error((await res.json()).detail || "오류 발생"); const sr = await res.json(); currentSrId = sr.sr_id; document.getElementById("result-sr-id").textContent = sr.sr_id; document.getElementById("section-form").classList.add("hidden"); document.getElementById("section-result").classList.remove("hidden"); await refreshStatus(); pollTimer = setInterval(refreshStatus, 5000); // 5초마다 갱신 } catch (err) { alert("요청 등록 실패: " + err.message); btn.disabled = false; label.textContent = "요청 등록하기"; spinner.classList.add("hidden"); } }); /* ── 상태 폴링 ── */ async function refreshStatus() { if (!currentSrId) return; const [srRes, workRes, ratingRes] = await Promise.all([ fetch(`/api/tasks/${currentSrId}`).then(r => r.ok ? r.json() : null), fetch(`/api/work/${currentSrId}`).then(r => r.ok ? r.json() : []), fetch(`/api/rating/${currentSrId}`).then(r => r.ok ? r.json() : null).catch(() => null), ]); if (!srRes) return; /* 상태 배지 */ document.getElementById("status-badge-row").innerHTML = `${STATUS_LABEL[srRes.status] || srRes.status}`; /* 작업 타임라인 */ const tl = document.getElementById("work-timeline"); if (workRes.length) { tl.innerHTML = workRes.map(w => `