PPI Internal Knowledge Base

PPI Docs

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

장애 분석, 코드레벨 동작 흐름, 운영 리포트, 리뷰 문서를 한 화면에서 빠르게 찾는 내부 문서 허브입니다.

-문서
-카테고리
-최근 업데이트
문서 목록 준비 중
탐색 시작점

신고 대응, 시스템 이해, 최근 변경 확인처럼 자주 쓰는 경로를 먼저 배치했습니다.

🆕
최근 추가된 문서
📅
Daily Reports 50
2026-07-22 기술이슈 일일보고 당일 수업 기록 147개에서 기술 증상 후보 97건을 6개 증상 클러스터로 정규화: AI 오인식 42건, 접속/WebRTC 29건, 자동전환/흐름 26건, 끼어들기 16건, 사운드/마이크 13건. 신규 발견 이슈 0건, 기존 이슈 재발 중심 요약. 2026-07-22 2026-07-21 기술이슈 일일보고 당일 수업 기록 173개에서 기술 증상 후보 100건을 7개 증상 클러스터로 정규화: 사운드/출력 58건, AI 맥락/반복 51건, 접속/네트워크 43건, AI 오인식 42건. 신규 발견 이슈 0건, 기존 이슈 재발 중심 요약. 2026-07-21 2026-07-20 기술이슈 일일보고 당일 수업 기록 166개에서 기술 증상 후보 86건을 7개 증상 클러스터로 정규화: AI 오인식 42건, 체크아웃/예비/자동전환 34건, 접속/네트워크 28건, AI 맥락/반복 23건. 신규 발견 이슈 0건, 기존 이슈 재발 중심 요약. 2026-07-20 2026-07-15 기술이슈 일일보고 당일 수업 기술이슈 75건을 8개 증상 클러스터로 정규화: AI 오인식/끼어들기 41건, 영상/전환 54건, 음성/사운드 31건, 접속/연결 23건(중복 유형 집계). 신규 발견 이슈 0건, 기존 이슈 재발 중심 요약. 2026-07-15 2026-07-13 기술이슈 일일보고 당일 수업 기술이슈 31건 집계: AI 응답/인식 19건, 음성/사운드 11건, 접속/연결 7건(중복 유형 집계). LogRocket MCP 403으로 SESSION_FILTERS Name 필터 검색 링크(미확인) 첨부. 2026-07-13 2026-07-12 기술이슈 일일보고 수업 이슈 채널 7/12 기록 기준 기술이슈 일일 요약 2026-07-12 2026-07-11 기술이슈 일일보고 당일 수업 기술이슈 20건 집계: AI 응답/인식 16건, 음성/사운드 10건, 실행/전환 9건(중복 유형 집계). LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-11 2026-07-09 기술이슈 일일보고 당일 수업 기술이슈 70건 집계: AI 응답/인식 50건, 음성/사운드 33건, 접속/연결 30건(중복 유형 집계). LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-09 2026-07-08 기술이슈 일일보고 당일 수업 기술이슈 72건 집계: AI 응답/인식 57건, 음성/사운드 37건, 화면/영상 23건(중복 유형 집계). LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-07 기술이슈 일일보고 당일 수업 기술이슈 68건 집계: 음성/사운드 35건, 접속/연결 19건, AI 응답/인식 9건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-06 기술이슈 일일보고 당일 수업 기술이슈 18건 집계: AI 응답/인식 8건, 음성/사운드 6건, 접속/연결 2건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-05 기술이슈 일일보고 당일 수업 기술이슈 10건 집계: AI 응답/인식 3건, 음성/사운드 4건, 접속/연결 1건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-04 기술이슈 일일보고 당일 수업 기술이슈 36건 집계: AI 응답/인식 15건, 실행/전환 6건, 접속/연결 6건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-03 기술이슈 일일보고 당일 수업 기술이슈 67건 집계: 음성/사운드 31건, 접속/연결 19건, AI 응답/인식 8건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-02 기술이슈 일일보고 당일 수업 기술이슈 55건 집계: 연결/접속 27건, 음성/사운드 17건, 실행/전환 6건. LogRocket MCP 403으로 Name 필터 검색 링크(미확인) 첨부. 2026-07-01 기술이슈 일일보고 Slack 수업 이슈 채널 7/1 기록 기준 기술이슈 일일보고. 신호등별 분류, 유형별 집계, 전일 대비 그래프, LogRocket 검색 링크 포함. 2026-06-30 기술이슈 일일보고 Slack 수업 이슈 채널 6/30 기록 기준 기술이슈 일일보고. 신호등별 분류, 유형별 집계, 전일 대비 그래프, LogRocket 검색 링크 포함. 2026-06-29 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-28 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-27 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-26 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-25 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-24 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-23 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-22 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-21 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-20 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-19 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-18 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-17 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-16 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-15 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-14 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-13 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-12 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-11 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-10 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-09 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-08 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-07 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-06 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-04 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-03 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-02 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-06-01 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-31 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-30 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-29 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-28 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-27 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크 2026-05-26 기술이슈 일일보고 당일 수업 기술이슈 요약 및 LogRocket 링크
🏗
Architecture 18
user.tagHistory — 임베딩 vs 별도 테이블 분리 데이터구조 검증 PPI-1103 음성 불가 사유 태그 변경 히스토리(tagHistory)를 별도 테이블로 분리할지 실측으로 검증. 현재는 ppi-user 아이템의 임베딩 배열(최대 200개 상한). prod scan 실측: 118명/127건, 유저당 max 3건(avg 1.1), 최대 아이템 1,847B=400KB 한도의 0.5%로 전부 4KB(1 RCU) 이내. "user 조회 시 히스토리까지 딸려온다"는 오버페치는 실재(getUser/getUsers에 ProjectionExpression 없음)하나, DynamoDB RCU는 읽은 아이템 전체 크기로 과금되고 Projection은 RCU가 아닌 페이로드만 줄인다는 사실이 경로별 판정을 가른다. GetItem 핫패스는 아이템<4KB라 히스토리 유무 무관 1 RCU 고정 → 분리 이득 0, Scan만 ~40KB/~10 RCU 미미한 오버페치. 두 경로 모두 정답은 테이블 분리가 아니라 읽기에 ProjectionExpression으로 tagHistory 제외(스키마 불변·admin 2차 쿼리 불필요). 분리는 교차 유저 audit 쿼리(changedById/changedAt GSI)라는 새 접근 패턴이 생길 때만 정당하며 아직 미발생. 판정 매트릭스·권장 코드 포함. 오디오 분석 에이전트 (오인식 감지·자동 정정) — 코드레벨 동작 흐름 & 이슈 분석 가이드 진행자 모니터 브라우저에서 아동/핑퐁이 오디오를 턴 단위 녹음(use-guest-audio-capture)→턴 완료 감지(TurnAnalysisCore: assistant 트리거·8s no-response 폴백)→blob 매칭(turn-audio-selection)→WAV 변환→Gemini/gpt-4o-audio 판정(/api/audio-analysis/analyze)→알림·자동 정정 주입(buildCorrectionText)·S3+audio_analysis 로그 3갈래. 전 단계 파일:줄 앵커 + 증상→의심 지점 디버깅 맵 포함 (이슈 수정 기준 문서). web/socket dev 배포 후 부하·병목 진단 실행 계획 web/socket dev EC2 배포 후 병목을 찾는 실행 계획. Grafana/Prometheus/Loki 기준선 수집을 먼저 하고, HTTP/API 부하 → Socket signaling 부하 → Playwright fake media 기반 WebRTC/SFU 부하로 단계적 증폭. LogRocket은 브라우저 증상 확인 보조 축으로 사용. CPU/RSS/event loop, HTTP p95/p99, web external operation, Redis op latency, mediasoup worker CPU, rooms/peers/transports/producers/consumers, ffmpeg process 회수성을 기준으로 병목을 web/socket/Redis/SFU/client로 분리하는 판정 매트릭스와 체크리스트 포함. socket 서버 CPU 100%·디스크 폭주 위험 감사 및 부하 테스트 실행 계획 PPI-1106 디스크 폭주 후속 예방 감사. socket 서버가 CPU 100%·디스크 풀·OOM으로 무너질 수 있는 로직을 코드 감사로 사전 식별. CPU 후보 5건(C1 stem ffmpeg 동시 실행 전역 상한 부재→2×녹음룸 선형 증가, C2 broadcastRoomList O(룸×peer) 재계산+io.emit 네임스페이스 전체 증폭, C3 speaking/transcript/transport hot-path logger.info 폭주, C4 워커=CPU코어 전부, C5 15s collectGauges 전체순회) + 디스크/메모리 후보 6건(D1 stem .ogg 세션중 무제한 생성, D2 Redis peer/room 키 TTL 부재, D3 인메모리 Router peerCount 드리프트 시 reaper 없이 영구잔존, D4 captionTurns 무제한 누적, D5 cleanStaleTmpFiles readdir 실패시 정리 skip, D6 startRecording 실패시 stem 미정리). 실측 prod CPU 스파이크는 C2/C3와 정합. dev(t4g.small 2vCPU) 부하테스트 S1~S5 시나리오로 붕괴 지점까지 밀어 정량 측정(미디어는 실브라우저+재접속 반복, 관측은 신규 broadcast 메트릭 포함). PPI-1106의 단일파일 무한인코딩과 다른 축(동시성·증폭·누적) 겨냥. 개선 백로그 포함. 전체 코드 감사 — 기술부채·레거시·잠재버그 우선순위 탑다운 6영역 병렬 감사(~200건, grep 실증). 우선순위 점수 = 가중치(기술부채 0.5/잠재버그 0.3/레거시 0.2)×심각도. 무인증 API 13건 즉시 조치(임의 S3 접근·TURN 키 유출·아동 PII IDOR), CI 게이트 전무(2.5점 최상위), V1 제거 플랜 ~14,000 LOC(web 11.8k+socket 2,055, 얽힘 없음 클린 제거), god-hook(use-ai-session 3,119줄), Redis reaper orphan·heartbeat split-brain(S5), STT 죽은 DSP ~300줄. 6단계 실행 로드맵 + 판단 필요 4건. 관측성 스택 — Prometheus·Loki·Grafana 코드레벨 동작 흐름 web(3000)·socket(3001)이 prom-client로 /metrics 노출 → Prometheus scrape → Grafana(버그 분석의 "ppi-socket")(백로그 P0 #7, P0 전체 완료). socket 메트릭 카탈로그(Socket.io/Mediasoup/Redis/reaper), 15초 gauge 수집(collectGauges), web 외부 operation duration(TTS), instance_id 라벨, route 정규화(카디널리티 방지), Loki JSON Lines 로깅. 함정 6가지(15초 polling·idempotent 등록·mismatch 진단 메트릭 등). STT 오디오 처리/세션 (Go) — VAD·필터·turn history 코드레벨 동작 흐름 apps/stt/internal/{audio,session} 코드레벨 문서(로드맵 P2 #26). STT 배치 서버(#4)의 하위 부품. 오디오: pcm(int16↔float64·WAV·duration), filter(Biquad 6th HPF/4th LPF Butterworth)... 호스트 모니터링 claim / 그룹 모니터링 — 코드레벨 동작 흐름 monitoring-handlers.ts 코드레벨 문서(로드맵 P2 #20). 호스트가 룸/그룹 모니터링 시 점유(claim) 관리로 중복 방지(#13 진입 게이트, #2 핸들러군)... Redis 인프라 (heartbeat·leader election·reaper) — 코드레벨 동작 흐름 redis/{client,reaper,reaper-scheduler,peer-store,key-prefix}.ts 코드레벨 문서(로드맵 P1 #16, @handover-redis). 다중 인스턴스 생존 추적+죽은 인스턴스 메타 정리(#5 Router 소유권의 짝)... Monitor 대시보드 (카드뷰·포커스뷰·통합) — 코드레벨 동작 흐름 app/monitor-dashboard + widgets + use-monitor-*-store 코드레벨 문서(로드맵 P1 #13, @handover 영역). 3계층 라우팅(홈 통합/그룹 카드뷰/roomId 포커스뷰)... Router 매니저 — 크로스인스턴스 소유권·router-sync 코드레벨 동작 흐름 routerManager.ts(657L)+room-store.ts 코드레벨 문서(로드맵 P0 #5). PPI-879 다중 인스턴스+Redis(Valkey) SoT. 메모리=캐시+owner 표지(room이 메모리에 있으면 owner), Redis=진실... STT 배치 서버 (Go) — 화자분리·dedup 코드레벨 동작 흐름 apps/stt Go 배치 서버 코드레벨 문서(로드맵 P0 #4). 3계층 STT 중 Primary External STT의 서버측(브라우저 클라는 #9 별도). WS 프로토콜(바이너리 0x00 user/0x01 ai + PCM16, finalize/process_ai_audio/reset)... 핑퐁이/아동 대화턴 녹음 흐름 (시각화) 한 대화 턴이 mp3+caption이 되기까지 전 과정 시각화. 아동 마이크(childPair)+핑퐁이(aiPair)를 ffmpeg amix로 합치는 구조. Realtime은 OpenAI server VAD가 턴 양보(AI 중단)해 무중첩, TTS(Typecast)는 양보 없어 중첩 → 녹음 amix에 child-priority sidechain ducking으로 아동 발화 중 핑퐁이 자동 감쇠(PR #786). TTS 녹음 흐름(player.stream→aiProducer), caption 좌표·aresample 정합 포함. 녹음 파이프라인 (mediasoup→ffmpeg→OGG→S3) — 코드레벨 동작 흐름 recordingManager.ts(1,653L) 코드레벨 문서(로드맵 P0 #3). 아동 mic+AI 음성을 PlainTransport(comedia:false)로 RTP 인출→ffmpeg(SDP 입력, child-priority sidechain ducking→amix→libopus 128k→OGG segment)... transcode 시 aresample=async로 갭 정합(PR #786 반영). Socket.io + mediasoup SFU 서버 — 코드레벨 동작 흐름 apps/socket 코드레벨 문서(로드맵 P0 #2). 통합 프로세스가 / (레거시 V1 P2P)와 /sfu(V2 mediasoup SFU) 두 네임스페이스 운영. 부트스트랩 순서(Redis→워커→녹음→socket.io+adapter→라우트→reaper)... 아동 알림 프리셋 — 동작 흐름 (이해용) 진행자 클릭 → 스냅샷/트리거 두 신호 → 게스트 판단 로직(이미지 동봉/매칭/race 보정) → 표시 규칙(15초·이미지 고정·재트리거 차단·X 종료)을 스윔레인+분기 다이어그램으로 시각화 PPI 아키텍처 문서 Redis 트러블슈팅 가이드 PPI-879 Redis 이관 회고
🐛
Bugs 46
MeetVideo loopback 오디오 출력 — sink 라우팅 원인 분석 및 수정 iOS 게스트에서 영상은 재생되지만 소리가 출력되지 않은 문제. loopback 전환 뒤 실제 출력자가 내부 Audio 엘리먼트인데도 sink 설정을 원본 video에만 적용한 것이 원인이며, 사용자 제스처 안에서 실제 출력 엘리먼트에 setSinkId를 적용하도록 수정한 내용과 회귀 방지 검증을 정리. TTS Blob src 교체 AbortError — AI 발화 말끊김 세션 로그 원인 분석 7/20 prod 게스트 세션에서 TTS local audio element가 2회 AbortError(“play() request was interrupted by a new load request”)를 남긴 사례. 이전 청크 재생 완료 전 새 Blob URL을 동일 audio.src에 즉시 설정해 기존 play 요청이 취소되는 직접 원인을 로그와 tts-player 코드로 대조. 청크 도착 간격은 촉발 조건일 뿐 근본 원인은 단일 엘리먼트 src 덮어쓰기 경합임을 구분하고, FIFO 재생 큐·명시적 취소·AbortError 분류를 권고안으로 정리. ai-audio SFU 송신 stall·AudioContext 출력 정지·입력 noise reduction 불일치는 별도 신호로 분리. 저사양 Android 720p 컨텐츠 DECODE_OVERLOAD — lowPerf 플래그 미배선 두 실패 모드 (정이안 3회기) 수업 중 반복 멈춤·끊김(위치 옮겨도 재발) VOC. 근본 원인: isLowPerformanceDevice가 MeetVideo/MeetImage에 배선되지 않아(guest-layout-content.tsx:203에서 아바타에만·split 모드만) 컨텐츠 영상이 2GB Android에서도 480p가 아닌 720p 원본으로 재생됨 — RESOURCE_CACHE 요청 파일명에 _480p 없음으로 확증. 720p@30=H.264 Lv3.1 한계라 프레임 31% 드롭. 두 실패 모드: ①아바타 없는 긴 영상=진행성 과부하(31% 드롭·완주), ②아바타 있는 영상=4~5초 하드 프리즈(숨겨진 아바타 동시 디코딩 가중). 진행자 녹화 멈춤은 별개 원인(버퍼 starvation, bufferedAhead 0·dropped 0, 8GB 정상 기기, kick 전 발생). 서버 녹화는 오디오 전용 mp3. 해결: MeetVideo/MeetImage에 lowPerf 플래그 배선(핵심)+아바타 full모드 480p·hidden pause. 🟡 CAUSE 영상 currentTime 앞으로 점프 (SEEK_REBUFFER) → near-end 조기 종료 52.97초 영상(video_newpingpong04_newstep_02)이 재생 시작 24.7초 만에 종료 처리된 사례(김서연 4회기, Android 10/Chrome/RAM 4GB 저사양). 재생 중 currentTime이 약 1.8s→33.8s로 순간 점프(약 32초 건너뜀)하면서 위치 시계가 끝(52.97s)에 벽시계보다 훨씬 일찍 도달, near-end fallback(currentTime≥duration−0.1)이 onEnd을 조기 호출해 다음 스텝으로 자동 전환됨. 핵심 증거: SEEK_REBUFFER 시점 totalVideoFrames=149(=30fps로 5초치 정상 디코딩)인데 currentTime=33.826 → 디코더가 아니라 위치 시계만 약 29초 앞섬 = 불연속 seek(native seeking 이벤트가 SEEK_REBUFFER로 분류된 게 그 결과). 앱/소켓/호스트 seek(guest는 monitor 전용 seek뿐, 로그 0건)·영상 파일(ffprobe 정상)·네트워크(blob 전체 버퍼링)·탭 백그라운드(visible)·메인스레드 프리즈(점프 구간에 다른 로그 정상 발생) 전부 배제. 원인은 저사양 기기 미디어 파이프라인의 clock/seek 이상이며 스텝 전환 직후 AI teardown+H264 디코드 시작 경합 정황, 세션 내 Video waiting 9건 전부 SEEK_REBUFFER. VideoEndWatchdog은 near-end에 의해 정상 disarm(오발화 아님). Watchdog DECODE_OVERLOAD 미발화 건과 정반대 실패 모드(끝에 너무 일찍 도달 vs 도달 못 함). 조기 입장(대기실) 경로에서 카메라 deviceId 유실 → 가상 카메라(Mirametrix) 캡쳐 [PPI-1138 원인 ① 수정 완료 · commit 3222e299] 조기 도착으로 미니게임 대기실을 거쳐 자동 입장한 아동(LG gram/Windows/Edge)에게서 수업 페이지가 실물 LG 카메라 대신 Mirametrix Virtual Camera(LG gram 번들 Glance 시선추적 SW의 가상 카메라)를 잡아 아동 영상이 캡쳐되지 않은 사례. 근본 원인 두 겹 — ① 대기실 자동입장 콜백 handleWaitingRoomComplete의 의존성 배열이 [roomId]뿐이라 발생하는 stale closure가, 마운트 시점(selectedVideo=null)의 tryV2Flow를 고정해 8분 뒤 카운트다운 종료 시 client-guest-device-ids.videoDeviceId를 null로 저장(그 사이 auto-select로 LG 카메라가 선택됐어도 콜백 미갱신), ② 수업 페이지는 PROBLEMATIC_CAMERAS 필터를 재적용하지 않고 deviceId가 없으면 video:true로 폴백해 OS 기본 카메라(Mirametrix)를 그대로 획득. Edge 브라우저 문제 아님, 제시간 직접 입장 경로에서는 미재현. 수정: deps에 selectedVideo/Audio/AudioOutput 추가로 원인 ① 해소(WaitingRoom effect가 onCountdownComplete를 deps에 포함해 부모·자식 조합이 올바르게 맞물림), 원인 ②(수업 페이지 label 방어막)와 극단 레이스는 이 커밋 범위 밖으로 잔존. 시간순 인과 다이어그램·코드 경로·재현 조건·수정 검증 포함. iOS WebKit clone track 무음 — 현재 상황 · 원인 · 근본 해결방안 (PPI-1121) iOS WebKit에서 MediaStreamTrack.clone()으로 만든 mic 트랙이 확률적으로 live인데 무음(zero-audio)이 되는 문제의 종합 문서. 현재 상황(관측 사례 전부 iPad, 새로고침 무효·kick만 회복), 원인(박서준 7/9 로그 대조 확진 — AI 전사로 발화 증명된 창에서 송신 outbound audioEnergyDelta=0, SFU 트랙은 WebAudio destination의 clone의 clone), WebKit 공개 이슈 대조(Bug 228255 audio clone flaky는 인접 사례이나 1:1 아님 — 우리 건은 live clone의 zero-audio 송신으로 mediacapture-main 표준 위반 동작, 단일 known bug 단정은 불가), 해결방안 3단계(① 자가회복 가드 적용 완료 60a8195c: VAD 발화 창 energy 0 → producer 재발행, micGuard 튜너블 ② producer clone 제거 실험: stopTracks:false로 clone 단계 축소 ③ 소비자별 MediaStreamDestination 분기로 clone 완전 제거). iOS 덕킹 — TTS 모드 감쇠 원인 분석 및 WebRTC loopback 우회 (PPI-1101) 같은 iPad 내장 스피커+마이크 조건인데 Realtime 모드는 감쇠가 작고 TTS 모드는 큰 이유 분석. 마이크 EC로 voice-processing(통화 세션)이 활성일 때, Realtime의 WebRTC 원격 트랙(srcObject)은 far-end 통화 음성으로 렌더되어 덕킹 면제 + AEC 레퍼런스인 반면, 기존 TTS의 Blob URL audio.src 재생은 통화 밖 "기타 미디어"로 분류되어 시스템 덕킹을 맞는다. EC OFF/마이크 OFF는 iPad EC-AGC 번들 문제와 아동 음성 전달 위험 때문에 폐기. 최신 적용안은 TTS 로컬 출력만 MediaStreamAudioDestination → local RTCPeerConnection sender/receiver → receiver ontrack remote MediaStream → audio.srcObject 경로로 바꾸는 WebRTC loopback 우회이며, 실패 시 Blob URL로 폴백한다. 아동측 미디어·세션 이상 전반 — LogRocket 원인 판별용 로깅 추가 범위 (무음 · 자동전환 멈춤 · 재접속 미디어 연결) 7/7 원준호 40회기 "접속 직후 소리 안 들림"(인트로 무음, 신고 3회·리로드 3회 끝 회복) 조사에서 드러난 관측 공백을 계기로, 아동측 반복 신고 3계열(무음·영상 종료 후 자동전환 멈춤·재접속 시 카메라/마이크 연결 문제)의 진단 로깅 범위를 정의. A~H 8개 영역: AudioContext 프로브(resume 후 currentTime 전진 = 하드웨어 클럭 신호), 신고 시점 스냅샷(GUEST_ISSUE_REPORT payload 동봉 → Loki 조회), MEET_VIDEO/AI 오디오 헬스, SFU 구간 절단용 게스트 outbound-rtp·모니터 inbound-rtp/audioEnergy(relay clone 무음 확정 판별), 자동전환 체인 보완(watchdog reset 사유·emit ack·전환적용 확인·timeupdate 스톨), 재접속 미디어 재획득(getUserMedia error.name 분류·track mute/unmute/ended 수명 추적·리로드 루프 감지·devicechange). 증상별 로그 서명 매트릭스 3종과 우선순위, createMediaElementSource 재라우팅 금지 등 제약 포함. 코드 미반영 범위 제안 문서. 녹음 post-mix 손상 stem — 14GB 거대 MP3 무한 인코딩·디스크 100% 폭주 (PPI-1106) ppi-socket-prod 루트 디스크 20GB가 단일 녹음 MP3(14GB, 계속 증가)로 100% 참. 세션 중 stem ffmpeg 재시작 SIGKILL로 finalize 안 된 2.8KB 손상 OGG가 ffprobe에서 start_time=0·duration≈17억초로 "성공적으로" 읽혀 기존 검증(size>0·duration>0·null 체크)을 전부 통과, base=min(start_time)이 0(=1970년)으로 무너지며 정상 stem들의 adelay가 epoch값 그대로(≈56년)가 됨 → amix duration=longest가 56년치 무음을 128kbps CBR(초당 16KB)로 무한 인코딩. 거대 MP3의 실체는 손상 stem 반복 병합이 아니라 정상 stem 앞에 붙은 무음 패딩. "타임스탬프 없음"과 "1970년"이 구분되지 않는 wallclock 설계의 함정 + PPI-1098 정렬 도입 이후 필연이던 스위스 치즈 사고. hotfix 4중 방어: duration 12h 상한(isPlausibleStemDurationMs), start_time 녹음시작 wallclock ±12h 범위 검사(planPostMix 순수 함수 추출), ffmpeg -t 6h 출력 상한(buildPostMixArgs), 실행 15분 타임아웃+SIGKILL. TDD 12케이스(prod 시나리오 재현), 캡션 좌표는 mp3T0Ms 경유로 함께 치유. PR #837. TTS 재생 스톨 — onended 미발생으로 인한 재생 큐 영구 블로킹 원인 분석 7/5 prod iPad 게스트 2세션(4회기·16회기)에서 핑퐁이 무반응 27~41초 → 강제 재접속의 원인 분석. TTS 요청·응답(Typecast fetch)과 OpenAI 응답 생성은 전 구간 정상이었고, 재생 중 청크의 WebAudio onended가 미발생하며 playing=true 고착 → 이후 모든 발화가 재생 큐에 블로킹. 전조로 2~3초 청크가 10초 재생(메인스레드 정지 서명: 전 로거 10초 공백 + 콜백 동시 해빙). tts-player 취약점 4종(onended 단일 의존, watchdog 부재, resume 도달 불가, iOS interrupted 미처리)과 suspended-start 변종(1.92/1.93) 관계, 로그 판별법, watchdog·statechange·start 전 상태 보장 수정 방향 정리. 영상 종료 후 자동전환 미발생 세션로그 원인 분류 및 Watchdog 분석 7개 세션 로그를 기준으로 guest-video-end emit 누락 지점을 재분류. DECODE_OVERLOAD로 media currentTime이 지연된 케이스, host step change로 watchdog이 reset된 케이스, complete force kick 선행, 탭 hidden/transport close, 외부 kick을 시각화하고 VideoEndWatchdog이 왜 발화하지 않았는지 코드 조건과 타임라인으로 정리. iPad Pro 내장 스피커/마이크 영상 오디오 감쇠 원인 분석 iPad Pro 내장 스피커+내장 마이크에서 MeetVideo Blob URL 영상 재생 중 대화인식 이벤트 발생 시 오디오가 작아지는 현상을 WebKit 캡처 세션, echo cancellation, External STT, Realtime VAD 관점에서 분석. TTS/Realtime 녹음 합본 겹침·밀림 — 원인 분석 및 최종 해결(입력별 독립 ffmpeg + 후처리 믹스) 녹음 합본에서 아동 턴이 뒤로 밀려 무음/겹침이 되거나 핑퐁이 연속 발화가 병합되던 문제. 근본 원인은 2겹 — 단일 ffmpeg가 두 RTP(child mic + ai-audio)를 함께 읽을 때 wallclock을 쓰면 조용한 입력의 read-starvation으로 아동 턴이 밀리고, 안 쓰면 무음 갭 붕괴로 AI 발화가 병합됨(한 ffmpeg론 트레이드오프 불가피). 최종 해결(PPI-1098): 입력별 독립 ffmpeg가 각 stem을 -use_wallclock_as_timestamps -copyts로 절대 start_time과 함께 기록하고, 정지 시 각 stem을 절대시각 기준 adelay로 정렬해 amix(후처리 믹스). 캡션 wallclock 전환, 종료 flush 긴 타임아웃, stem 무결성 필터(손상 stem 드롭), 교체 경계 old consumer pause(중복 기록 방지) 포함. TTS·Realtime 실측 검증 완료. 클라이언트 로컬 재생은 Blob URL 방식 유지. PR #822. 자동전환 OFF 대기 중 설정 후 영상이 자동전환되는 이슈 게스트가 먼저 수업 대기(고양이 화면)에 있고 호스트가 이후 수업 화면에서 자동전환 OFF로 변경한 뒤 시작하면 영상 종료 시 다음 스텝으로 넘어가는 이슈. 원인은 호스트 설정 모달의 로컬 settings.autoTransitionEnabled와 SFU room autoTransitionEnabled가 분리되어, 수업 시작 전 OFF가 room 상태로 전파되지 않고 서버 기본값 true가 guest-approved2 payload로 전달되는 경로. 오디오 분석 nTurns 재생 — 턴 끝부분 잘림 원인 분석 + 꼬리 마진 수정 핑퐁이 세션 로그 오디오 분석 컬럼의 nTurns 합본 음성 재생 시 각 턴 끝부분이 잘리는 VOC. 합본/인코딩 경로(combineAudioBlobsToWav·encodeWavMono)는 decodeAudioData가 컨텍스트 길이와 무관하게 전체 PCM을 반환하고 mono 전체를 복사하므로 샘플 손실 없음을 코드로 검증해 범인에서 배제. 진짜 원인은 캡처 종료 타이밍 — 발화-종료 트리거(소켓 컨트롤 채널 guest-speaking-stop/ai-speaking-stop)가 녹음 대상인 원격 WebRTC 스트림(jitter buffer 지연)보다 먼저 도착해, 꼬리 오디오가 트랙에 렌더되기 전 recorder.stop()이 동기 호출되어 매 턴 일관되게 끝부분 절단. 분석 전송용 audioBlobToWav도 같은 입력이라 LLM도 뒷부분을 못 들음. recorder.start(500) 타임슬라이스는 stop()이 flush하므로 원인 아님. 수정: use-guest-audio-capture.ts에 STOP_TAIL_MARGIN_MS=500 지연 stop 도입(flushStop/scheduleStop 분리), 마진 중 발화 재개 시 cancelScheduledStop으로 예약 취소해 한 턴 유지, 언마운트 타이머 정리. PPI-1082 로컬 적용. 아동247 24회기 — 영상 완료 자동전환 실패 2건 재현 경로 2026-06-23 prod 아동247 24회기에서 영상 재생 완료 시 자동 전환이 실패한 2건을 LogRocket 아동·진행자 세션과 Grafana ppi-socket-prod 로그로 대조. 영상 시작 이벤트(Guest video play started)는 서버에 9건 도달했지만 guest-video-end/video-end 계열은 0건, 이후 진행자 엘리스가 Host changed step으로 수동 전환한 흐름을 확정. MeetVideo.onEnded → GuestLayoutContent.handleVideoEnd → notifyVideoEnd/goToNextStep 경로와 실패 지점 포함. 녹음 캡션 위치 어긋남 — TTS 모드 아동 캡션 누락 원인 분석 "듣기 OFF + 진행자 타이핑"(=TTS/External STT) 수업에서 녹음 캡션 위치가 어긋나는 VOC. 직접 측정 결과 고장 caption.json은 user 캡션 0개(정상은 49개) — External STT가 아동 전사를 type:"text"/"stt_verified"로 보내는데 녹음 캡션 수집기는 type==="audio"만 받아 아동 전사 전량 탈락. 듣기 토글은 무관(인과 반전). 중첩 녹음은 TTS 이중출력(릴레이+스피커) acoustic echo로 핑퐁이가 ai/child 트랙 양쪽 인입(세그먼트 중첩은 반증). 추가로 wall 19분 중 3.5분이 전환 시 드롭아웃... [2026-06-25 업데이트] 후속 케이스(아동333 24회기)로 Realtime 모드(user 캡션 정상)에서도 어긋나는 별개 2차 원인 확인 — 캡션 좌표(OGG granule, 195s)와 실제 mp3(무음 붕괴, 119.8s) 타임라인 불일치. 수정 적용(PR #786): transcode aresample=async로 갭 복원·캡션 필터 확장·마이크 AEC 명시. [echo 가설 정정] AEC 배포 후 테스트 녹음도 23초+ 양방향 섞임 지속 → 동시 이중피치 분석 결과 acoustic echo가 아니라 '동시 발화 겹침'(TTS 끼어들기 미차단)이 주원인. [최종 해결] barge-in은 끼어들기 OFF와 모순·불안정으로 폐기, stem 분리는 과함 → 녹음 amix에 child sidechaincompress ducking(약 1줄) 적용해 아동 발화 중 핑퐁이 자동 감쇠 = 아동 우선 무중첩 녹음(realtime/tts 확인). PR #786. 아동005 27회기 아바타 매칭 오류 — 태양 talking 전환 시 지우 렌더 지우·태양 2아바타 회기에서, 체크아웃(끝인사) 단계의 태양(taeyang_v2) talking 전환 시 지우(jiwoo_v2) talking 영상(avatar_jiwoo_v2_talking_0.mp4)이 잠깐 렌더되는 VOC. 게스트 측에서만 발생... 아동070 1회기 — 아동 소리 안 들림 원인 분석 텍스팅 수업에서 진행자에게 아동 목소리가 전달 안 된 VOC(영상·말풍선은 정상). 전달 경로는 전부 무결 — 서버 Loki 직접 조회로 producer/consumer 34/34 매칭·transport connected(RTT 15~25ms)·pause/error/fail 0 확인... ☠️ 아동004 29회기 수업 중단 — 아동 단말 인터넷 단절 원인 분석 해골 이슈(외부 요인·코드 결함 아님). 수업 시작 2분 51초 뒤 아동 접속 끊김(08:02:51 UTC). NETWORK_QUALITY가 user-network로 진단 — gstatic·1.1.1.1·/api/health 3-프로브가 3초 타임아웃으로 동시 실패(externalLatency... 갤럭시 탭 S10 FE simulcast 인코딩 부하 검증 — 레이어별 로깅 + 1레이어 토글 S10 FE가 카메라를 simulcast 3레이어(100k·300k·900k)로 동시 인코딩할 때 실제 단말 부하가 걸리는지, 그 부하가 DECODE_OVERLOAD(영상 끊김)... 카메라 인코딩 경량화 — simulcast 고화질 레이어 낭비 개선 게스트 동시부하(영상 끊김 DECODE_OVERLOAD·오디오 끊김)의 큰 덩어리인 카메라 인코딩 경량화 방안. 아동 기기는 카메라를 simulcast 3벌(저270p·중540p·고1080p) 동시 인코딩(use-mediasoup-producer.ts:415... DECODE_OVERLOAD 발생 감소 — 인코딩 파라미터 및 lowPerf 기준 개선 full:video 게스트 실제 부하 구조 분석. 6코어/8GB 기기가 lowPerf 기준 미달로 720p(1800k)를 수신해 DECODE_OVERLOAD 발생. 개선: ①480p fps 30→24... VideoEndWatchdog DECODE_OVERLOAD 반복 stall 미발화 원인 분석 arm() 첫 tick이 예상 종료 시각에 예약 → stall-resume 반복 시 누적 지연 감지 불가. wall clock drift 체크(방안 1) 권장. 아동303 25회기·아동049 24회기·아동074 2회기 3개 세션 7회 이상 확인. 🔵 OPEN 고사양 240Hz 노트북 DECODE_OVERLOAD — 디코드가 아니라 present 파이프라인 stall VOC "영상 재생 끊김"을 MSI Vector GP66 12UEO(i7-12650H·RTX3060·QHD OLED 240Hz·8GB, 로그 hardwareConcurrency 16·deviceMemoryGB 8와 일치)에서 분석. 자동전환 미반영 — 게스트 socket.io 업링크 26초 stall 원인 분석 및 로깅 추가 핑퐁이가 자동전환 멘트("그러면 같이 한번 찾으러 가보자!")를 말해 조건 매칭됐는데 진행자 모니터가 안 넘어가고, 진행자 수동 점프·새로고침으로 개입하다 아동이 직전 활동(하랑대화1)으로 회귀한 VOC. LogRocket 아동/진행자... AI 발화 "지지직" — STT 캡처 WAV 클리핑(과레벨) 분석 핑퐁이(AI) 발화의 지지직을 STT 검증용 캡처 WAV(ai_stt_req19, 16kHz 무손실)로 분석. gpt-realtime WebRTC 정적/버징 노이즈 — 6/12 발생 원인 분석 핑퐁이(AI) 발화에 간헐적 큰 정적/크래클(라이브 수업 ~50%, 20분당 2회, gpt-realtime v1.0·WebRTC). 6/12 발생인데 RMS 립싱크(#709)는 6/14에야 운영 배포 → 배제... 아동측 영상·오디오 끊김 — 동시 인코딩 부하 분석 및 simulcast 360p 계획 활동 영상 재생 중 아동측 화면+오디오 동시 끊김(VOC). DECODE_OVERLOAD 로그는 meet-video.tsx:554 catch-all 오분류(드롭 1%·풀버퍼·고사양인데도 라벨링). 영상 파일은 무죄 — 용량(20MB/2분)·포맷·플레이어·MSE/HLS 모두 기각... ffprobe duration WARN 대량 발생 — 빈 OGG 세그먼트 / 캡션 probe 비대칭 원인 분석 ppi-socket WARN의 약 절반(ffprobe duration failed ~1,200건/24h, 대부분 End of file). 손상도 사고도 아님 — Invalid data(진짜 손상) 0건, 50개 방에 분산, 포트충돌·크래시 기여 ~8%뿐... 경과시간 09:08 → 18:03 점프 — 누적시간 이중 가산 원인 분석 모니터(호스트) 소켓의 짧은 끊김→재접속 직후 useCumulativeElapsed가 세션을 재조회하며 count 0→1. 같은 ~9분 구간을 "DB 종료세션(duration) + 살아있는 lessonStartedAt 라이브 카운터"가 이중 가산... 경과시간 03:49 → 02:29 감소 — 게스트 재접속 후 누적시간 회귀 분석 포커스뷰 헤더 타이머(useCumulativeElapsed = Σ DB세션 duration + (now − lessonStartedAt anchor))가 게스트 재접속 직후 ~80초 줄어든 현상. ✅ 코드 검증·결정론 재현으로 02:29 확정. 누적시간 회귀 03:49→02:29 — 재현 경로 파악 과정 (repro-path) 위 회귀를 repro-path 스킬(인테이크→코드검증→반증루프→결정론 재현)로 재현한 전 과정 메타 문서. 원본 1차 가설("anchor 재설정이 원인")을 코드 실행으로 부분 정정: 회귀의 게이트는 anchor 재스탬프가 아니라 hasLiveCurrentRecord=false(라이브 세션 레코드 부재) 창이며,... 누적시간 — 이탈시간 30초 규칙 적용 + 재접속 경과시간 회귀 수정 ✅ 적용 완료. 재접속 이탈 시간 누적 규칙(≤30초 포함 / >30초 제외)을 코드에 반영 + 긴 단절 재접속 시 경과시간 회귀(03:49→02:29) 차단. 변경①(서버... 아동 알림 프리셋 트리거 race · 이미지 동기화 수정 스냅샷이 트리거보다 늦게 도착하는 race로 첫 트리거 누락·표시 중 이미지 교체·host/guest 이미지 불일치 → 첫 트리거 버퍼 재평가 + 표시 중 이미지 고정(seq) + 표시 중 진행자 재트리거 차단 + 트리거에 이미지 동봉으로 항상 일치 녹음 후처리 CPU Spike 분석 및 큐 처리 개선 mediasoup 녹음 activity 전환 끊김 원인 분석 노트북/데스크탑 DECODE_OVERLOAD 해결 영상 종료 이벤트 미발생 & NAVER 인앱 브라우저 분석 OpenAI Realtime 세션 시작 실패 원인 분석 PLC 기계음 오탐지 원인 분석 및 해결 setSinkId 시스템볼륨 우회 분석 사운드 이슈 종합 분석 모니터 측 게스트 마이크/AI 오디오 무음 원인 분석 아동274 아동 3회 접속 실패 — 마이크 무음 입력 / 영상 다운로드 실패 원인 분석 LogRocket 3세션 분석: 패드 마이크 무음 캡처 + 노트북 영상 fetch 실패, AI 출력은 정상 httpbin.org 503 / CORS 콘솔 에러 — 네트워크 품질 체크 원인 분석 외부 무료 서비스 503 다운이 원인, try/catch로 흡수되는 콘솔 노이즈. 리소스/AI/미디어 영향 0, 죽은 데이터라 외부 체크 제거로 정리
Features 41
영상 오디오 WebRTC loopback + EC 스텝 토글 제거 — iOS 덕킹 회피 (PPI-1121) iOS 게스트에서 full:video 오디오를 MediaElementAudioSourceNode → 로컬 RTCPeerConnection 쌍 → remote 트랙 srcObject(통화 카테고리, 덕킹 면제)로 로컬 출력하고, 사이드 이펙트(EC OFF 고착→에코 전사, voice-processing 재구성→clone 무음)의 근원이던 PPI-1097 EC/NS/AGC 스텝 토글을 완전 제거해 EC 세션 상시 ON으로 전환한 구현 문서. TTS loopback 협상 로직을 공용 유틸(webrtc-audio-loopback)로 추출해 전송/정책 계층 분리, 폴백은 ctx.destination 직결(무음 구간 0 원칙, 3회 재협상). iPad 실기기에서 확인된 재생 속도 출렁임(NetEQ 적응)은 jitterBufferTarget 150ms 고정 + Opus CBR/DTX off SDP 패치 + contentHint=music으로 억제. 런타임 튜너블(videoLoopbackGain/videoLoopbackJbt/videoLoopback=off)과 로그 시그니처, 출력 경로별 덕킹 매트릭스 포함. 2026-07-13 iPad 실기기 작동 확인 완료. 프롬프트 변수 시스템 — instruction-variables 코드레벨 동작 흐름 AI 지시문 변수 치환 엔진(백로그 P0 #6). 네 문법 — #{}(DB 전역 프롬프트 변수), @{}(아동·핑퐁이 정체성 + 한국어 조사 자동), ${}(활동 커스텀), {{}}(대화 흐름). replaceAllVariables 3단 펼침(#{}→@{}/${}→{{}}), getKoreanParticle 받침 판정(아/야·랑/이랑), 끝→앞 역순 치환, 미해결 토큰 원문 유지, 중첩 금지(NESTED). openai-create-call이 런타임에 finalInstruction 생성. 함정 6가지. 알림톡 (NCP SENS) — 발송·템플릿 코드레벨 동작 흐름 아동 미접속 시 보호자에게 카카오 알림톡 발송(백로그 P0 #5). 두 층 — 로컬 템플릿 설정(DynamoDB CRUD: channelId/templateCode/순서)과 발송(/api/alimtalk/send: NCP에서 본문 fetch→#{} 치환→전송). NCP SENS HmacSHA256 서명, 템플릿 5분 메모리 캐시, 전화번호 82 정규화, 진행자 확인식(미접속 5/10분 토스트→클릭 발송). 함정 6가지(로컬 vs NCP 템플릿 2종, 캐시 stale, 서명 query 일치 등). TTS 모드 & 합성 API — Typecast/OpenAI 코드레벨 동작 흐름 Realtime 음성 vs TTS 모드(speechOutput.mode="tts": Realtime은 텍스트만, 클라가 /api/tts/synthesize로 외부 TTS 합성 → 발화·자막 일치)(백로그 P0 #4). 서버 흐름: 인증→authz 3중 검증(게스트 room·activity·avatar)→in-flight 예약(typecast 15/room 2/session 1)→provider fetch(Typecast ssfm-v30/OpenAI gpt-4o-mini-tts)→buffered+WAV 검증→완성 반환, transient 1회 재시도. RPM 미사용·핸들러 2개·streaming WAV 0xffffffff placeholder 등 함정 7가지. 원본 docs/realtime-tts.md 통합. PPI-API 데이터 보강 — plannedStartTime·completionStatus 코드레벨 동작 흐름 DynamoDB Lesson(진도·세션·예외시간) ↔ ppi-api classes(정규 스케줄·상태·담당자·그룹)를 join해 plannedStartTime·completionStatus·groupId를 계산(백로그 P0 #2). 세 경로 — 단일 아동(enrichUserLessonsWithPpiApiData, missingTodayClasses), 관리자(enrichLessonsWithPpiApiData, synthetic lesson·batchGetLessons), 모니터 대시보드. resolvePlannedClass의 그룹/1:1 시각 분기, KST 고정, local 우선 병합, user/admin 상태 소스 차이(effective vs raw) 등 함정 6가지. 누적 경과시간 추적 — 세션 합산·단조 클램프 코드레벨 동작 흐름 회기(userId+lessonIndex) 내 여러 입·퇴장의 시간을 한 번만 누적(백로그 P0 #3). 서버 createSession/endSession이 LessonSession 레코드+sessionSummary.totalDuration 집계, 클라 useCumulativeElapsed가 종료 세션 합+라이브 앵커 구간을 매초 합산. 회귀 가드: 단조 클램프(finalize), anchor-이전-구간만 더하는 이중가산 방지, 라이브 앵커 게이트, MAX 3600초 캡. currentSessionId 정밀(게스트)/느슨(모니터) 매칭, 입장 1시간 한도(P0 #1)의 기준. 누적시간 버그 4건과 가드 대응. 수업 입장 제어 — 시간 검증·can-enter 코드레벨 동작 흐름 아동 입장 성공/실패의 근원(백로그 P0 #1). 세 검증 경로 — A. /api/validate-lesson(validateLessonTime 상태머신: 첫입장 −15분~+30분·재입장 20분·하드컷 60분, plannedStartTime 기준), B. canEnterLesson(회차 게이트: 완료·중복접속·누적 1시간), C. validateLessonGap(예외시간 8시간 간격). enrichUserLessonsWithPpiApiData의 ppi-api 병합·LESSON_NOT_PROVISIONED·NORMAL/TEMP/FORCED 모드, tenMinutesAfter=실제 30분 등 함정 7가지. 클래스 관리/스케줄링 — 코드레벨 동작 흐름 class-mgmt + class-group-utils + scheduled-lessons 코드레벨 문서(로드맵 P2 #27). 치료사-아동 배정·수업/그룹 편성·예약 수업 관리(대부분 Next BFF가 ppi-api 프록시)... 게스트 입장 플로우 (디바이스·네트워크·can-enter) — 코드레벨 동작 흐름 guest-entry.tsx + use-device-manager + use-guest-entry-socket 코드레벨 문서(로드맵 P2 #25). 아동 입장 게이트: 카카오 인앱 브라우저 가드→디바이스 선택(enumerateDevices, PROBLEMATIC_CAMERAS 필터... 언어 가드 설정 스토어 (draft/save) — 코드레벨 동작 흐름 use-language-guard-settings-store.ts 코드레벨 문서(로드맵 P2 #24). 영어 발화 감지(stt/audio/transcript)·MFCC 패턴·끼어들기 허용시간·아바타 RMS·오탐체크 전역 설정(GLOBAL 1건) Zustand 스토어... Auth / 세션 / TURN·ICE 발급 — 코드레벨 동작 흐름 session/auth-refresh/members·users auth/ice-servers 코드레벨 문서(로드맵 P2 #23). 치료사(member)·아동(child) PIN 로그인을 Next BFF가 외부 ppi-api로 중계... 리소스 캐싱/프리캐시/SW — 코드레벨 동작 흐름 use-resource-cache.ts 코드레벨 문서(로드맵 P2 #22). 활동 리소스를 입장 전 Cache Storage에 프리캐시, 재생 시 캐시 사용, 실패 시 입장 차단(#15). 버전 캐시 키 https://dubu-cache/{fileName}?v={updatedAt}로 자동 무효화... 화면 공유 (host→guest) — 코드레벨 동작 흐름 use-screen-share.ts 코드레벨 문서(로드맵 P2 #21). 치료사 화면을 아동에게 실시간 공유(host 전용 시작, V1 P2P #11 connectionId=screen-share 재사용)... WebRTC 모니터링/통계 (getStats) — 코드레벨 동작 흐름 use-webrtc-monitoring.ts 코드레벨 문서(로드맵 P2 #19). RTCPeerConnection 연결 상태 전이+getStats 통계 수집·로깅, 게스트는 소켓 송출. 공용 훅(#1 OpenAI WebRTC, #11 V1 P2P)... STT 폴백 (Web Speech API) — 코드레벨 동작 흐름 use-stt-fallback.ts 코드레벨 문서(로드맵 P2 #18). 3계층 STT 최후 폴백 — OpenAI/External STT 실패 시 브라우저 네이티브 SpeechRecognition(ko-KR, continuous, interim, maxAlternatives 3)... 볼륨 증폭기 (마이크 auto-gain) — 코드레벨 동작 흐름 use-volume-amplifier.ts 코드레벨 문서(로드맵 P2 #17). 입력 작은 내장 마이크 자동 게인(세션 매니저 createMediaStream에서 내장 마이크일 때만, 처리 체인 #7 앞단). 그래프 source→analyser→gainNode→destination... Meet/룸 + 호스트 세션 라이프사이클 + 입장 승인 — 코드레벨 동작 흐름 socketSfu + use-host-entry-socket + lesson-session.service 코드레벨 문서(로드맵 P1 #15). 수업 진입~종료 오케스트레이션(roomId={userId}_{lessonIndex})... 세션 로그 시스템 (stt_dedup·MFCC·캡션) — 코드레벨 동작 흐름 session-log.types + use-session-logs + api/session-logs 코드레벨 문서(로드맵 P1 #14). 한 수업의 모든 상호작용을 단일 SessionLog 스트림(DynamoDB)으로 저장... Activity 시스템 (템플릿·step·jumpConfig·auto-finish) — 코드레벨 동작 흐름 activity.types + activity-utils/spare-content-utils/lesson-utils + use-session-auto-finish 코드레벨 문서(로드맵 P1 #12). 수업=Activity[]×Step[], priority 순서... V1 레거시 P2P WebRTC (use-web-rtc) — 코드레벨 동작 흐름 use-web-rtc.ts 코드레벨 문서(로드맵 P1 #11). V1 P2P 1:1 연결 기반 훅(V2는 mediasoup #10). connectionId로 용도 분리(session-audio 릴레이/host-audio 미디어/screen-share)... mediasoup 클라이언트 (producer/consumer·simulcast) — 코드레벨 동작 흐름 use-mediasoup-{producer,consumer,device}.ts 코드레벨 문서(로드맵 P1 #10). V2 SFU 클라이언트 미디어 송수신(서버측 #2). Device.load(rtpCapabilities)→send/recv transport... External STT 클라이언트 (WS·prebuffer) — 코드레벨 동작 흐름 external-stt-observer.ts + use-external-stt.ts 코드레벨 문서(로드맵 P1 #9). 아동 마이크를 16kHz Int16로 가공해 Go STT 서버(wss /ws/stt)로 스트리밍하는 브라우저 WS 클라이언트(서버측은 #4, OpenAI와 병렬)... AI 오디오 노이즈 가드 (버징/정적/하드클리핑 탐지) — 코드레벨 동작 흐름 use-ai-audio-noise-guard.ts 코드레벨 문서(로드맵 P1 #8). 핑퐁이 출력 음성의 기계음/버징/정적/지지직을 Web Audio analyser로 실시간 탐지(탐지만, 억제 X — onNoiseDetected 콜백). 같은 50ms 루프(analyzeFrame)... 오디오 처리 체인 (Gate→EQ→Comp→Limiter) — 코드레벨 동작 흐름 use-audio-processing-chain.ts 코드레벨 문서(로드맵 P1 #7). 아동 마이크를 OpenAI 송출 전 가공하는 Web Audio DSP 체인(세션 매니저 createMediaStream에서 항상 적용)... 세션 릴레이 (게스트→호스트 핑퐁이 음성) — 코드레벨 동작 흐름 use-guest/host-session-relay.ts 코드레벨 문서(로드맵 P1 #6). 핑퐁이 세션은 아동측에서만 돌고, 게스트가 AI 음성+상태를 호스트로 중계(V1 P2P 경로, V2는 SFU producer #2)... OpenAI Realtime 세션 매니저 — 코드레벨 동작 흐름 use-session-manager.ts 코드레벨 문서(로드맵 P0 #1). 브라우저↔OpenAI Realtime WebRTC 세션 1개의 전 생명주기: 마이크 캡처(getUserMedia→증폭→DSP→addTrack)... 회기 보고서 — 회기 템플릿 보고서 항목 추가 및 보고서 페이지 신설 회기 템플릿에 sessionReport(오늘 수업/연습한 대화 기술/함께 해볼 활동) 추가(1부) + 학습플랜 선택 시 회기별 보고서를 표로 보는 /main/report 페이지 신설·admin/developer 역할 가드(2부) 아바타 RMS 립싱크(canvas) — 코드 레벨 동작 흐름 AI 발화 음량(RMS)으로 입모양을 연속 제어 — taeyang.html 방식 canvas 합성 전환 + 아바타별 on/off + 전역 9개 파라미터 + 발화종료 fade-out. 데이터 배선→rAF 루프 6단계를 파일:라인으로 따라가는 코드 워크스루 오디오 분석 에이전트 — 통합 코드 레벨 문서 nTurns 기준 실제 오디오 blob 선택·합본 WAV 저장·분석 모델 전달 흐름 통합 문서. nTurns=2는 대상 아동 발화 기준 직전 핑퐁→아동 2턴이며, Typecast/Realtime TTS 모두 role/time 메타로 매칭하고 stt_verified는 실제 raw audio blob으로 해소한다. 아동 알림 프리셋 생성·관리 도입 및 개별 ON/OFF 토글 변경 하드코딩 {{환경소음}} 토큰 → 프리셋 CRUD 구조 전환(1부) + "항상 1개만 활성" 단일활성 → 프리셋별 개별 ON/OFF·전역 OFF 시 화면 숨김·이미지 깜빡임 제거(2부) WebRTC 연결 진단 페이지 구현 플랜 diagnosis.ovice.com 대체 — 마이크/카메라/STUN·TURN/RTT 진단을 웹앱 내부에 구현 (기존 훅 ~80% 재사용, 인프라 추가 불필요) 리소스 다운로드 HTTP Range 이어받기 네트워크 실패 시 받은 바이트 보존 후 Range로 이어받기 + 지수 백오프 재시도 (fetchResumable) 리소스 다운로드 재시도 실패 처리 이어받기로도 못 받으면 입장 차단 + 아동/호스트 알림 + 재접속 복구 (fail-fast, GUEST_RESOURCE_LOAD_FAILED) 아바타 입모양 Mouth Layer 개선 검토 기계음 영어 발화 감지 로직 분석 첫 발화 한국어 유도 개선 가이드 MFCC 튜닝 변천사 카드뷰 세션 변천사
📚
Reference 15
영문 숏컷 프롬프팅 치트시트 반복되는 한글 개발 지시를 짧은 영문 숏컷으로 대체하기 위한 매핑표. Claude Code 세션 325개의 실제 요청 860건을 빈도 분석해 6개 군(Git 82회, 진행 제어 61회, 조사·디버깅 50회, 리뷰·요약 45회, 문서화 29회, 기타)으로 정리. commit / go / review / tldr / add to ppidocs / show in vscode 등 2~5단어 명령형 + 파일명·티켓번호·아동이름 한/영 혼용 원칙. 뉘앙스 지시·고유명사는 한글 유지 권장. 증상별 트러블슈팅 매트릭스 장애 신고가 들어왔을 때 증상 → 즉시 확인 신호(LogRocket·Grafana Loki) → 의심 원인 → 코드/문서로 곧장 진입하는 트리아지 색인. bugs/ 32개 분석을 증상 축으로 재배열. 11개 증상군(소리·마이크 무음, AI 발화 음질·노이즈, DECODE_OVERLOAD/영상 끊김, 자동전환 실패, 누적시간 회귀, 녹음·캡션 STT, 녹음 후처리 부하, 아바타 매칭, 네트워크 단절, 알림 프리셋, AI 세션 시작 실패)을 5열 표(증상/즉시 확인/의심 원인/코드 위치:라인/분석 문서)로 정리. 표에 없는 신규 신고는 /repro-path로 연결. 운영·관리·인프라 문서화 백로그 — 갭 트래커 코드레벨 문서화 로드맵(실시간 코어 28/28)의 짝. ppi 모노레포 전수 조사로 그 범위 밖 미문서 영역을 추적 — 운영/관리 백오피스(수업 입장 제어·PPI-API 데이터 보강·누적 경과시간), 알림톡(NCP SENS)·프롬프트 변수·이슈 알림·발화 알림 규칙, 인증/권한 RBAC, TTS 모드, 관측성(Prometheus·Loki·Grafana), CI/CD·Terraform 인프라, 그리고 V1_V2 가이드·Jacob 인수인계 등 ppi 내부 문서 이관까지. P0 7·P1 11·P2 9 + 이관, 진행 0/27. PPI 재현 경로 파악 흐름 시각화 이슈 수신부터 LogRocket/Grafana 관찰, 코드 라인 검증, 반증 루프, 최소 재현 조건, E2E 레시피 산출까지 ppi-bug-tracer가 재현 경로를 좁히는 전체 흐름을 한눈에 보는 시각화 문서. 증상별 코드 지도(AI 오디오, 활동 영상, SFU/WebRTC, 입장/승인, 타이머, 채팅/API), 자료 수집 통로, 확정/강한 후보/보류 판정 기준, 재현 경로 파악 요청 예시, 최종 산출물 템플릿 포함. Hermes ppi-bug-tracer — PPI 버그 재현 경로 분석 에이전트 PPI 버그·이슈를 입력받아 코드를 직접 탐색하고 재현 경로를 단계별로 파악하는 로컬 LLM 에이전트. qwen3.6:latest(Ollama) 기반. SOUL.md로 PPI 프로젝트 컨텍스트(게스트/호스트 흐름, session-manager, WebRTC, Socket.io... 재현 경로 파악 에이전트 설계 "아동070 1회기 / 진행자 측에 아동 소리 안 들림" 같은 단발 증상 신고를 동일 증상이 재현되는 단계별 경로 + 근거 타임라인으로 자동 환원하는 반복 재사용 에이전트 설계. 에이전트 선택(Claude Code vs Hermes·Codex·openclaw 비교 — LogRocket MCP 기연결... Hermes 완결형 지시 템플릿 Hermes 에이전트에게 이슈 분석·코드 수정·검증까지 한 번에 맡기기 위한 실전 지시 템플릿. 핵심은 "무엇이 문제인지"보다 "무엇이 완료 상태인지"를 전달하는 것. 완결형 지시의 기본 구조(목표/완료 조건/제약/검증), 바로 복붙 가능한 템플릿, PPI 실전 예시(아바타 영상 매칭... PPI 프로젝트 이슈 요청 가이드 버그·성능 문제·배포 실패·WebRTC 이상처럼 원인 분석과 해결이 필요한 요청을 AI에게 정확히 전달하는 방법. "무엇이 문제인지"보다 "어떤 결과를 원하는지"를 함께 전달하는 것이 핵심. 포함하면 좋은 정보(증상/대상(guest·host·socket·web·배포... 고주사율 노트북 60Hz 변경 가이드 (영상 끊김 응급 조치) 240Hz OLED 노트북(예: MSI Vector GP66, Windows) 사용 아동의 활동 영상 끊김 VOC 임시 응급 조치. 디스플레이를 60Hz로 낮춰 합성 마감(4.17ms→16.67ms, 4배 여유)·합성 횟수(1/4) 부담을 줄임... Shared 패키지 상수/타입 (이벤트·mediasoup config) — 코드레벨 동작 흐름 packages/shared 코드레벨 문서(로드맵 P2 #28, 마지막). @ppi/shared는 web/socket 공유 SSOT — 이벤트명 drift 차단. 상수(constants.ts): MEDIASOUP_CONFIG(코덱·포트 40000-40099·대역폭), WEBRTC_CONFIG... 코드레벨 문서화 로드맵 — 기능별 백로그 / 진행 트래커 PPI 모노레포 주요 기능을 코드레벨 동작 흐름으로 문서화하기 위한 마스터 백로그 겸 진행 트래커(0/28). 기존 코드레벨 문서(아바타 RMS·오디오 분석 에이전트·MFCC·리소스 다운로드 등)는 중복 제외. P0(세션매니저·SFU서버·녹음·STT배치·Router매니저), P1(세션릴레이... PO Translator — 기획자 요구사항 번역기 LogRocket MCP 이슈 조회 요청 Best Practice 저사양 기기 분류 기준 Claude Code 깔때기 패턴
🔍
PR Review 7
보고서 도구 확장 — 리포트 프롬프트 & JSON→Notion 테스트 (1d3172a0) PR #911 (feat, 14 files, +3,253/−238). /main/report 페이지를 회기별 편집 테이블 하나에서 탭 3개(회기 보고서 세팅·프롬프트 테스트·JSON 노션 테스트)로 재구성. 실제 AI 보고서 생성은 외부 Gemini 서버가 맡고 web은 인증·키 은닉 프록시 / JSON→Notion 문서 변환·발행(report-document.ts 741줄, report-json-notion.ts) / 학습플랜 프롬프트 저장 / 테스트 UI·폴링을 담당하는 오케스트레이션 계층. DB는 기존 ppi-curriculum 아이템에 optional 속성 2개(reportCommonPrompt·reportSessionPrompts 회차맵)만 얹어 마이그레이션·백필 불필요. 신규 env 6개(DPP_REPORT_TEST_URL/SERVICE_KEY, NOTION_API_KEY, NOTION_REPORT_TEST_CONTAINER_ID + 선택 2). 관전 포인트 6건: 두 curriculum 라우트의 parseReport* 검증기 복붙, 테스트 탭 dev 우회(prod만 프록시 경유)와 json 탭의 경로 비대칭, updateCurriculum이 항상 SET(||null)이라 API 머지로만 데이터 소실 방어, NOTION_APP_WORKSPACE_SLUG 기본값 하드코딩, json-test의 엄격 파서(규격 외 키 시 400 전체 실패). 신규 API 4개 모두 admin/dev 전용. PR #889 전사 파이프라인의 후속. 회기 보고서 전사 파이프라인 — 기획과 구현 (75282732) PR #889 (feat, 51 files, +4,633/−529). 수업 완료 → MP3 시각순 결합·16kHz mono FLAC 표준화 → GCS 업로드 → Google STT V2 Chirp3 배치 전사(화자분리 2인) → 보고서 생성 → Notion 문서까지의 end-to-end 파이프라인. 진행 상태는 기존 Lesson 데이터에 reportTranscription·reportGeneration으로 얹어 저장하고, 보고서탭(일별 진행 현황·회기 보고서 세팅)과 세션 로그 전사 탭에서 조회(관리자/개발자, 진행자 차단). 기획 문제·목표·권한부터 7단계 파이프라인, 기획 세부작업↔구현 매핑표, 핵심 diff 4곳, 레이어별 요약, 관전 포인트 6건(전사 큐잉 비원자적·화자분리 켰는데 segments 빔·폴링 무기한·Chirp2는 env 전환·local 공유디렉터리 전제), TC1~16 대비 테스트 커버리지까지. 완료 상태는 '리포트 생성 완료'이며 알림·메시지 발송은 범위 밖. LiveKit 도입 — voice-agent 추상화 전체 플로우 (9fc5b813) PR #821→revert #873→reapply #875→#878의 순변경(150 files, +22,919/−1,800) 코드레벨 리뷰. 게스트 음성 세션에 voice-agent transport 추상화를 도입해 OpenAI Realtime 직결 외 self-hosted LiveKit+Python agent(ECS) 경로를 추가. 기본 대화 방식이 livekit으로 전환(typecast 보이스 아바타 한정), 세션 시작이 ppi.agent_ready 10초 하드 의존, "듣기 OFF"가 트랙 mute 대신 agent RPC 게이팅으로 바뀐 점 등 P1 6건 포함 12개 관전 포인트. 세션 시작·agent 수명주기·설정→런타임·배포 4개 플로우와 웹↔agent data channel/RPC 계약 표 정리. 미지원 기기/브라우저 접속 제한 안내 (PPI-1085) — 커밋 리뷰 (43623131) PR #802. 미지원 기기/브라우저 입장 시 이동 전 확인 모달로 안내하는 기능(+584/−11, 9 files). 기존 language-guard-settings draft/save 패턴 재사용, enabled 기본값 false. 부수적으로 parseBrowser의 Samsung/Opera 오인식 순서 버그를 고쳐 진행자 모니터 표시에도 자동 반영됨. 메시지 탭 '오인식 판별 (AI)' 섹션 제거 — 커밋 리뷰 (24c6c14a) PR #808. 메시지 탭의 MfccFalsePositiveCheckSection UI만 제거하고 mfccFpCheck의 store·API·런타임 사용부는 그대로 남긴 chore. UI는 없어졌지만 전용 API 라우트와 store 액션이 편집 창구 없이 고아 상태로 남는 점을 관전 포인트로 짚음. 1:1 호스트 포커스뷰 TTS 단독 테스트 패널 제거 — 커밋 리뷰 (e6fcb942) PR #807. 포커스뷰에 남아있던 Typecast TTS 단독 테스트 패널(282줄)을 컴포넌트·2단 배럴 export·페이지 진입점까지 통째로 제거하는 순수 삭제 chore. 브랜치 전체 재검색으로 dangling 참조 없음을 확인, 런타임 TTS 합성 경로와는 상태를 공유하지 않아 영향 없음. 오인식(high) 감지 시 직전 인식 정정 자동 주입 — 커밋 리뷰 (bb04ee93) 기획자 요구사항을 Claude Code로 코드레벨 반영한 커밋의 개발자 리뷰 보조 문서. 오디오 분석 에이전트가 오인식 probability=high를 출력하면 설정 ON 시 직전 인식 정정 문구를 게스트 Realtime 세션에 자동 주입(host.tsx·session-card.tsx·monitor-dashboard 3곳에 동일 로직 복제). 설정 경로(관리자 UI→PUT→DynamoDB→GET→훅)와 런타임 주입 경로를 단계별로 정리하고, host.tsx에만 있는 sessionRelay.isActive 가드 비대칭·buildCorrectionText의 무검증 빈 문자열 치환 등 리뷰 관전 포인트 4가지를 짚음.

검색 결과가 없습니다.

본문 색인 중...

PPI Internal Docs · Dobraindev