미발동 추천의 `call_id` 누락으로 `callId` 가 빈 문자열 → `/close` 404 — 요약·확정·블랙리스트 요청이 사라진다
정성윤이 09-22 저녁 최종 QA(류준 페르소나 4 + 검증 웨이브)·운영 확인 결과를 보고 만든 티켓이다. 담당은 «제안»이다 — 본인이 확인하고 맞으면 착수, 아니면 옮긴다.
무엇을
09-22 최종 QA: 추천이 발동하지 않은 통화에서 call_id 가 안 실려 callId 가 "" 가 되고, 통화 종료 /close 가 404 로 끝난다.
그러면 요약·확정·블랙리스트 요청이 전부 사라진다. apps/call/src/lib/realCallMediatorClient.ts:384.
왜
시연 한 통을 끝까지 돌리는 조건 4 의 직접 걸림돌이다. 추천이 안 뜬 통화(맞장구만 있는 짧은 통화)에서 반드시 난다.
완료 조건
callId를 추천이 아니라 통화 시작 메시지(started)에서 잡는다- 추천 0건 통화로
/close200 · 요약 저장 확인(파서 테스트 1건)
근거: 미결 「대시보드 — 조서희」 ①.
2026-09-23 — 원인 정정 + 구현 (조서희)
원인 문구를 고쳤다. callId는 applyTranscript·applyRecommendation·applyClosure
셋 중 아무거나 한 번 오면 잡힌다(같은 set() 호출 안에서 utterances와 함께 채워진다) —
“추천이 없어서”가 아니라 전사·추천·판정 중 아무 이벤트도 안 온 통화(맞장구조차 STT에
안 잡힌 아주 짧은 통화)가 정확한 조건이다.
진짜 원인은 §7.3 계약에 “통화 시작” 메시지 자체가 없던 것 — services/call-mediator가
보내는 메시지 종류(ports.ts)에 started가 없어 프론트가 잡을 수 있는 가장 이른 신호가
“첫 발화”뿐이었다. 그래서 apps/call만으로는 완결이 안 됐다:
services/call-mediator:ports.ts에StartedPayload({call_id})·CallMediatorMessage에started추가.RegistryDeps.announceStarted(기본 false, 다른announce*와 같은 안전장치) 추가.call_registry.ts의callFor()— 서버POST /hub/calls성공 직후(통화당 한 번, 화자 둘이어도 한 번)broadcaster.publish(callId, {type: "started", ...}).main.ts에서announceStarted: true로 켰다(프론트 파서가 같은 커밋에 들어간다). 테스트 3건 추가 (꺼져있으면 안 보냄·화자 둘이어도 한 번·시작 실패면 안 보냄) —npm test160/160.apps/call:CallMediatorListener.onStarted?신설,realCallMediatorClient.ts에started파싱 추가,useCallMediatorSession.ts에서callStore.applyStarted(callId)로 연결.applyStarted는callId만 세팅하고utterances는 건드리지 않는다(세그먼트가 없으므로). mock은 그대로 둔다 — mock 시나리오는 이미 callId를 안다.- 안전장치도 남겼다 —
useCallMediatorSession.wrapUp()이callId가 비어 있으면/close를 아예 안 부르고 “통화 번호를 아직 받지 못했습니다…” 오류로 바꾼다.started메시지가 와야 할 통화에서 무슨 이유로든 안 왔을 때(연결 끊김 등) 빈 문자열로 404 나던 것 대신 원인이 보이는 오류가 뜬다.
남은 것 — 완료 조건 2번, 검증 못 함: apps/call엔 테스트 실행기 자체가 없다(package.json에
test 스크립트 없음, test/ 디렉터리도 없음) — “파서 테스트 1건”을 추가할 인프라가 없다.
빌드·타입체크(tsc --noEmit·vite build)만 통과 확인했고, 실제로 추천 0건 통화를 운영에서
끝까지 돌려 /close 200을 본 적은 없다. 그래서 status를 done이 아니라 in-progress로
둔다 — 코드는 됐지만 실측이 없다(절대 원칙 2).
2026-09-28 — 덮어쓰기 경로를 막음 (조서희)
- 09-24 류준 인계(P0-2):
started로 이르게 잡는 것은 됐으나 빈call_id로 덮어쓰는 경로가 남아 있었다 (realCallMediatorClient.ts미발동 추천의?? ""→callStore.applyRecommendation). callStore.ts에keepCallId()를 두고callId를 쓰는 다섯 곳(started·transcript·recommendation 2·closure)에 적용 — 비었으면 이미 잡은 값을 지킨다.- vitest
apps/call/test/callStore.callId.test.ts6건 — 수정을 되돌리면 3건이 실패하는 것을 확인했다. - 남은 것: 완료 조건 2의 운영
/close200 · 요약 저장은 아직 눈으로 보지 않았다(단위 테스트는 스토어callId유지까지만 본다). 그래서in-progress로 둔다. 시연 리허설에서 추천 0건 통화 한 통으로 확인한다.
2026-09-30 — 운영 확인 · done (정성윤)
정성윤이 넘겨받았다(decisions/137 — 마감까지 apps/ 도 정성윤이 고친다. §4 대로 assignee 를 옮기고 여기 적는다). 수동 QA 2회차(_logs/2026-09-30-01-seongyun, 운영 server 0.1.43 · call-mediator 0.2.11 · call index-sR-v0E8Y) Q-50~Q-53 ✅ — test-qa-seongyun-02 에서 통화 후 처리 → /close 200 · 요약 저장·확정·재수정까지 운영에서 봤다. Q-48 은 발화 0건 통화(-06)로 「상담원 전용 링크가 아닙니다」 안내.
「추천 0건 통화」 그대로는 시험하지 않았다 — 그 경로는 callStore.callId.test.ts 6건이 고정하고 있고, 콜 미디에이터 0.2.10+ 가 call_id 를 늘 싣는다. 시연 리허설에서 한 통 더 본다.
2026-10-01 — 추천 0건 통화 운영 확인 (정성윤)
act4(demo-act4-01, services/call-mediator/scripts/demo_text_call.mjs act4 — 상담원 발화 셋뿐, 고객 줄 없음)를 운영(server 0.1.44 · call-mediator 0.2.12)에서 돌렸다 — 캡처는 정성윤 로컬 보관(data/processed/qa-captures/, gitignore — 10-01 저녁 사용자 지시로 공개 사이트에서 뺐다). 자막 세 줄, 필요서류 카드 0건, 헤더 연결됨. 추천이 하나도 없는데도 화면이 통화에 묶였다(started) — 같은 번호 010-0000-0901 이 블랙리스트라 「배정 판정」 배너(demo-A03)까지 떴다.
통화 종료 → /close 200 → 요약 확정은 이 캡처에 없다 — 녹화 때 act4 끝에 「통화 종료」를 눌러 본다. 완료 조건 2 의 운영 확인은 09-30 Q-50~53(추천 있는 통화) 그대로다.
관찰: 두 번째 줄 「여보세요 들리시나요」 가 「*** 요 들리시나요」 로 가려졌다 — 「여보세」를 이름(P6)으로 본 과잉 마스킹으로 보이나 원인은 재지 않았다. 누락 0 > 과잉 억제(절대 원칙 3)라 고치지 않고 미결에 적었다.
2026-10-01 저녁 — 카드 0건 통화의 통화 종료 (정성윤)
운영 check-mix-01(act4 — 카드 0건)에서 「통화 종료」 → 통화 후 처리 화면까지 갔다(콜 라우팅 보호 카드가 떴고, 대기화면 최근 상담기록에 check-mix-01 이 유형 「미분류」 로 올라왔다 — /close 가 돌아 유형 분류까지 저장됐다는 뜻). 「요약 확정」 버튼은 이번에 누르지 않았다 — 녹화 때 act4 끝에 누른다.