BUG ANALYSIS · 2026-06-30

자동전환 OFF 대기 중 설정 후 영상이 자동전환되는 이슈

마지막 업데이트 2026-07-29

자동전환 OFF 대기 중 설정 후 영상이 자동전환되는 이슈: 증상: 결론 — 범인부터 공개한다, 원인: 수사 일지 ③ — 범행 수법: 코드 레벨 원인, 수정·검증: 수사 일지 ⑤ — 검거 계획: 해결 방향 흐름
동작 흐름 요약
  1. 증상: 결론 — 범인부터 공개한다
  2. 원인: 수사 일지 ③ — 범행 수법: 코드 레벨 원인
  3. 수정·검증: 수사 일지 ⑤ — 검거 계획: 해결 방향

재현경로: 게스트 수업 대기(고양이 화면) → 호스트 수업 진입 → 자동전환 OFF 변경 후 대기 → 수업 시작 → 영상 종료 시 다음 스텝으로 자동 전환

결론 — 범인부터 공개한다

이 이슈의 본질은 영상 컴포넌트 자체가 OFF를 무시하는 것이 아니라, 수업 시작 전 호스트 설정 모달의 OFF 값이 게스트가 사용하는 SFU room autoTransition 상태로 전파되지 않는 상태 소스 분리다. 서버 room 기본값이 ON이기 때문에, 게스트는 승인 시 ON을 받고 영상 종료 시 정상 코드 경로대로 자동 전환한다.

문제 타이틀

자동전환 OFF가 게스트 영상 종료 로컬 전환에 반영되지 않는 상태 분리 버그

강한 원인 후보

호스트 설정 모달의 settings.autoTransitionEnabled와 SFU room의 autoTransitionEnabled가 별도 상태로 유지된다.

핵심 반례

monitor-dashboard의 useRoomAutoTransition으로 OFF하면 SFU room에 반영되어 게스트로 브로드캐스트된다.

수사 일지 ① — 사건 발생: OFF로 껐는데 화면이 넘어갔다

신고 접수

진행자는 분명 설정 모달에서 자동전환을 OFF로 바꿨다. 그런데 수업 영상이 끝나자 아동 화면이 제멋대로 다음 스텝으로 넘어갔다. 진행자 UI에는 OFF라고 표시된 채로. 먼저 사건의 정확한 재현 경로부터 확보했다.

최종 재현 경로

게스트가 /client-guest/session으로 진입하고 수업 대기(고양이 화면) 상태가 된다.
소켓 서버는 room/router를 만들 때 autoTransitionEnabled: true를 기본값으로 둔다.
호스트가 /app/main/meet/[roomId]에 들어와 설정 모달에서 자동전환을 OFF로 바꾼다.
이 설정 변경은 components/pages/host.tsx의 로컬 settings만 갱신한다. SFU room 상태에는 SET_AUTO_TRANSITION을 보내지 않는다.
호스트가 게스트 입장을 승인하면 서버는 여전히 room 기본값인 autoTransitionEnabled: trueguest-approved2 payload로 보낸다.
게스트는 이 값을 세션 상태에 저장하고, 영상 종료 시 autoTransitionEnabled === true로 판단해 goToNextStep()을 호출한다.
결과적으로 호스트 UI에서는 OFF처럼 보였지만, 게스트 로컬 영상 종료 경로에서는 ON 상태로 동작한다.

수사 일지 ② — 용의자 심문: 반증 루프

가설과 배제

가장 단순한 용의자부터 심문했다 — "영상 컴포넌트가 OFF를 무시하고 무조건 넘긴다"는 가설. 그러나 코드는 결백했다. 게이트는 있었고, 문제는 게이트에 들어오는 이었다. 심문을 거듭할수록 수사망은 "값이 어디서 갈라졌나"로 좁혀졌다.

가설검증 결과판정
영상 컴포넌트가 OFF를 무시하고 항상 goToNextStep() 한다.GuestLayoutContent는 영상 종료에서 if (autoTransitionEnabled)로 게이트한다.기각
서버가 OFF 값을 게스트에게 전송하지 않는다.SFU room 상태가 OFF라면 GUEST_APPROVED2에 OFF가 실려 간다. 다만 호스트 설정 모달 변경은 SFU room 상태를 바꾸지 않는다.부분 수정
호스트 UI의 OFF와 게스트가 보는 OFF가 서로 다른 상태이다.host.tsx 로컬 settingsrouterManager.rooms[roomId].autoTransitionEnabled가 별도로 존재한다.유지

수사 일지 ③ — 범행 수법: 코드 레벨 원인

범행 경로 복원

살아남은 가설은 하나 — "호스트가 본 OFF와 게스트가 받은 ON은 애초에 다른 상태다". 이제 그 두 상태가 어디서 태어나 어디서 갈라지는지, 코드로 범행 경로를 복원했다. 서버 기본값(A)에서 출발해 게스트로 전달되는 payload(B), 어디에도 닿지 않는 호스트 설정(C), 그리고 최종 범행 현장인 영상 종료 게이트(D)까지.

A. 서버 room 기본값은 ON

apps/socket/src/mediasoup/routerManager.ts:24-34
room = {
  ...,
  autoTransitionEnabled: true, // default: true for new system
}

getAutoTransitionEnabled()도 room이 없으면 true를 반환한다(routerManager.ts:140-142). 따라서 명시적으로 SFU room 상태를 OFF로 바꾸지 않으면 게스트가 받는 값은 ON이다.

B. 게스트 입장/승인 시 서버 값이 전달된다

apps/socket/src/sfu-socket/handlers/room-handlers.ts:171-184
const autoTransitionEnabled = routerManager.getAutoTransitionEnabled(roomId);
socket.to(guestId).emit(SOCKET_EVENTS.GUEST_APPROVED2, {
  resourceFileNames,
  autoTransitionEnabled,
  externalSttEnabled,
});

게스트는 이 값으로 pendingAutoTransitionEnabled와 세션 상태를 세팅한다.

apps/web/entities/guest-socket/model/use-guest-socket.ts:97-101
setPendingAutoTransitionEnabled(data.autoTransitionEnabled ?? true);
apps/web/entities/guest-page-session/model/use-guest-page-session.ts:625-635
setAutoTransitionEnabled(enabled);
aiSessionRef.current.updateAutoTransitionEnabled(enabled);

C. 호스트 설정 모달은 로컬 settings만 바꾼다

apps/web/components/pages/host.tsx:984-1012
const handleSettingsConfirm = (newSettings) => {
  ...
  setSettings(newSettings);
  ...
}

여기에는 SOCKET_EVENTS.SET_AUTO_TRANSITION, sessionRelay.toggleAutoTransition(), 또는 SFU room 상태 갱신 호출이 없다. 즉 “수업 시작 전 자동전환 OFF”가 게스트가 참조하는 room 상태와 분리된다.

D. 영상 종료 시 게스트 로컬 전환은 게스트 상태를 기준으로 한다

apps/web/shared/ui/guest-layout-content.tsx:113-118
props.session.notifyVideoEnd();
if (autoTransitionEnabled) {
  props.session.goToNextStep();
}

따라서 게스트가 승인 payload에서 true를 받으면, 호스트 로컬 설정이 OFF여도 영상 종료 순간 게스트는 다음 스텝으로 이동한다.

수사 일지 ④ — 결정적 대조: 정상/반례 경로

알리바이 대조

범행 수법을 확정하려면 "같은 OFF인데 정상 동작하는 경로"와 나란히 놓고 대조해야 한다. monitor-dashboard 경로와 세션 릴레이 토글은 모두 room 상태(또는 게스트 세션)에 실제로 닿는다 — 닿지 않는 것은 수업 시작 전 설정 모달뿐이었다.

증거물 목록 — 의심 파일/라인

수사 일지 ⑤ — 검거 계획: 해결 방향

체포 영장

범인은 "두 개의 진실"을 허용한 상태 분리다. 검거는 호스트 설정 모달의 OFF가 게스트가 참조하는 단일 source of truth(room 상태)에 반드시 닿게 만드는 것이다.

  1. 권장: handleSettingsConfirm에서 autoTransitionChanged가 true면 SFU room에도 SOCKET_EVENTS.SET_AUTO_TRANSITION을 emit한다. 그러면 대기 중인 게스트에게도 AUTO_TRANSITION_UPDATED가 브로드캐스트된다.
  2. 보완: GUEST_APPROVED2 payload 기준도 호스트 로컬 설정이 아니라 단일 source of truth인 room 상태로 유지하되, 호스트 설정 UI가 반드시 그 상태를 갱신하게 만든다.
  3. 검증: 재현 경로에서 OFF 변경 직후 게스트 콘솔에 Auto-transition updated { enabled:false }가 찍히고, 영상 종료 후 Notifying video ended는 찍히되 Moving to next step이 없어야 한다.