GET/sxe/analysis
analysis_id → {incident_uid, affected_hosts} (index-pm external_ref pull 백필, #189)
index-pm 백필 진입점 (sit #189, 2026-06-29).
목적(왜 존재): external_ref=sxe:<analysis_id> 만 가진 index-pm issue 가 incident_uid 와
affected_hosts 를 한 번에 pull 하도록 analysis_id → {incident_uid, affected_hosts} 를 반환.
index-pm 인입 시 incident_uid 누락(결손) 보정 + 호스트 동시 채움(멱등 백필).
배경(실측 2026-06-29): SEE sxe.analyses 는 incident_uid NULL 이 0건 — 즉 index-pm 의 '222건
incident_uid 없음'은 SEE 결손이 아니라 index-pm 인입 누락이다. analysis_id PK 로 역조회하면
incident_uid 가 항상 나온다(이 라우트가 그 역조회를 노출).
공통화: 호스트 복원은 기존 /sxe/analysis/{uid} 핸들러(sxe_load_analysis)를 그대로 호출 → 로직 드리프트 0.
라우트 주의: /sxe/analysis/{incident_uid:path} 보다 먼저 선언해야 한다(쿼리형 vs 경로형 구분).
@param analysis_id: sxe.analyses PK (external_ref 의 sxe:<NNN> 의 NNN)
@returns: {found, analysis_id, incident_uid, source, affected_hosts:[str], affected_hosts_detail:[{...}]}.
미존재=found:false. 호스트 미복원이면 affected_hosts=[] (정직 빈 — 가짜 0 금지).
Query parameters
analysis_idintegerrequired
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X GET https://see.in-bridge.com/sxe/analysis?analysis_id=0
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analysis", {
method: "GET"
});
const data = await res.json();
POST/sxe/analysis
Sxe Save Analysis
UI Phase 9 done 직후 또는 wrapper 가 분석 결과 저장.
같은 UID 여러 분석 가능 (이력 추적). 자동 집계 컬럼은 raw_phases 에서 추출.
G0: body.analysis_id 가 있으면 그 row 를 UPDATE(early-save 갱신) — INSERT 안 함(중복 방지).
Request body
incident_uidstringrequired
incident_namestring | null
completed_atstring | null
measurement_enabledboolean
total_cost_usdnumber | null
phase_reachedinteger | null
analysis_idinteger | null
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X POST https://see.in-bridge.com/sxe/analysis \
-H "Content-Type: application/json" \
-d '{"incident_uid":"string","source":"string","incident_name":"string","started_at":"string","completed_at":"string","invoked_by":"string","measurement_enabled":true,"raw_phases":null,"errors":[null],"total_cost_usd":0,"config_hash":"string","phase_reached":0}'
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analysis", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"incident_uid": "string",
"source": "string",
"incident_name": "string",
"started_at": "string",
"completed_at": "string",
"invoked_by": "string",
"measurement_enabled": true,
"raw_phases": null,
"errors": [
null
],
"total_cost_usd": 0,
"config_hash": "string",
"phase_reached": 0
})
});
const data = await res.json();
GET/sxe/analysis/{incident_uid}
Sxe Load Analysis
캐시 load — 같은 UID 의 최근 분석 1건 + 전체 이력 목록.
latest=true (default) → 정규화 reconstitute 한 raw_phases 포함.
analysis_id 지정 시 그 분석의 raw_phases.
Path parameters
incident_uidstringrequired
Query parameters
analysis_idinteger | null
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X GET https://see.in-bridge.com/sxe/analysis/{incident_uid}?latest=true&with_raw=true&analysis_id=0
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analysis/{incident_uid}", {
method: "GET"
});
const data = await res.json();
GET/sxe/analysis_state/{incident_uid}
Sxe Analysis State
단일 진실 분석 (M2) — 한 incident_uid 의 현재 상태 통합 조회.
state ∈ {before, queued, running, done}
done : PG sxe.analyses 에 row 존재 → 캐시된 분석 결과 사용. analysis_id + verdict + severity 반환.
running : 최근 ~30s 안에 session_id=incident_uid 의 feed 이벤트 → live watch mode 진입.
phases_seen / current_phase / last_event_ago_sec 포함.
queued : _pending_analysis_queue 에 있고 아직 worker 가 처리 안함.
before : 그 외 — 정적 incident 상세 (lab OS) 표시 + [분석 시작] 버튼.
먼저 running 체크 → queued → done → before 순서로 평가.
이유: 같은 UID 의 과거 분석 row 가 PG 에 있어도 (e.g. 3일 전 결과), 지금 새 분석이 진행 중이면
그쪽이 사용자가 보고 싶은 화면임. running 을 우선시함.
단일 진실 = 어느 페이지/브라우저에서 같은 UID 로 접속해도 같은 화면을 봐야 한다 (사용자 2026-05-28).
Path parameters
incident_uidstringrequired
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X GET https://see.in-bridge.com/sxe/analysis_state/{incident_uid}
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analysis_state/{incident_uid}", {
method: "GET"
});
const data = await res.json();
POST/sxe/analysis_progress
Sxe Analysis Progress
Request body
incident_uidstringrequired
phase_reachedinteger | null
stall_reasonstring | null
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X POST https://see.in-bridge.com/sxe/analysis_progress \
-H "Content-Type: application/json" \
-d '{"incident_uid":"string","phase_reached":0,"status":"string","stall_reason":"string","ts":0}'
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analysis_progress", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"incident_uid": "string",
"phase_reached": 0,
"status": "string",
"stall_reason": "string",
"ts": 0
})
});
const data = await res.json();
POST/sxe/analyze
프런트 직접 분석 트리거 (비동기 잡 A) — 즉시반환, 진행=WS, 결과=GET /sxe/analysis/{uid}
#118 동기 분석 API (설계 A=비동기 잡). 러너 ~4분이라 블로킹하지 않고 worker 큐에 넣고 즉시 반환.
왜 enqueue 인가: enrich 는 컨테이너(node 없음) → 러너(node) 직접 spawn 불가.
host worker(systemd, BACKEND_RUNNER)가 pop→spawn 하므로 큐가 유일·견고한 경로.
진행: WS `/sxe/feed/ws` (phase 브로드캐스트, 기존 인프라 재사용).
결과: `GET /sxe/analysis/{uid}` · 상태: `GET /sxe/analysis_state/{uid}`.
중복가드: 이미 처리(running/done)·큐대기면 재enqueue 안 함(현재 status 반환). options.force=true 면 우회.
side-effects: _pending_analysis_queue append, feed 이벤트 발행.
Request body
incident_uidstringrequired
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X POST https://see.in-bridge.com/sxe/analyze \
-H "Content-Type: application/json" \
-d '{"incident_uid":"string","source":"string","options":null}'
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/analyze", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"incident_uid": "string",
"source": "string",
"options": null
})
});
const data = await res.json();
GET/sxe/lab/incidents_page
Sxe Lab Incidents Page
dashboard-v2 #incidents 의 모든 데이터 한 번에.
- KPI (severity 4 + status 5)
- MITRE Top 5/5 (Tactic + Technique)
- 시간별 분포 (24h)
- 심각도 동향 (7d)
- 최근 인시던트 10건
- 인시던트 카드 grid (limit 건)
sxe.analyses 의 분석 결과 join (verdict / elapsed / processed_at).
Responses
200 Successful Response422 Validation Error
object
cURLcurl -X GET https://see.in-bridge.com/sxe/lab/incidents_page?limit=0&range_hours=0
JavaScriptconst res = await fetch("https://see.in-bridge.com/sxe/lab/incidents_page", {
method: "GET"
});
const data = await res.json();