전체 코드 감사 — 기술부채·레거시·잠재버그 우선순위

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

전체 코드 감사 — 기술부채·레거시·잠재버그 우선순위: 입력: 이 문서는 이렇게 읽으면 됩니다, 주요 처리 단계: 5. V2 시스템 (client-guest · monitor-dashboa…, 결과: 1. 총괄 요약 흐름
동작 흐름 요약
  1. 입력: 이 문서는 이렇게 읽으면 됩니다
  2. 주요 처리 단계: 5. V2 시스템 (client-guest · monitor-dashboa…
  3. 결과: 1. 총괄 요약
문서 읽는 법 · 설명식

이 문서는 이렇게 읽으면 됩니다

전체 코드 감사 — 기술부채·레거시·잠재버그 우선순위의 핵심을 설명식으로 먼저 안내합니다. 기술적 결론과 원문 근거는 아래 본문에 보존되어 있습니다.

핵심 흐름 펼쳐 보기
  1. 비유와 핵심 질문으로 먼저 전체 구조를 잡습니다.
  2. 실제 컴포넌트·파일·데이터 흐름을 따라 내려갑니다.
  3. 코드 라인과 주의사항에서 구현 근거를 확인합니다.
  • 0. 점수 방법론
  • 1. 총괄 요약
  • 2. 보안 — 즉시 조치 무인증 API 13건
작성일 2026-07-02 대상: apps/web · apps/socket · apps/stt · packages/shared · 인프라(CI/터라폼/의존성) 방식: 탑다운(라우트 진입점 → 서브시스템 6영역 병렬 감사, grep 실증 기반)

0. 점수 방법론

각 발견 항목의 우선순위 점수 = 카테고리 가중치 × 심각도(1~5). 가중치는 목표 배분에 따름.

카테고리가중치점수 범위의미
tech-debt0.50.5 ~ 2.5기술부채 해결 — 구조·컨벤션·안전망(CI/테스트/타입) 문제
potential-bug0.30.3 ~ 1.5잠재 버그 — 특정 조건에서 장애·데이터 불일치·누수 유발
legacy0.20.2 ~ 1.0레거시/죽은 코드 제거 — 도달 불가·미사용 코드
예외: 무인증 API(보안) 발견은 점수와 무관하게 즉시 조치로 별도 분류(§2). 점수 체계는 "어떤 부채부터 갚을까"의 순서이지, 보안 노출을 뒤로 미루라는 뜻이 아님.
운영 전제(사용자 확인): V1 시스템(guest/meet P2P)은 운영 미사용. 실사용은 V2 모니터링 수업(client-guest + monitor-dashboard)main/prompt-test 두 흐름뿐. 따라서 V1의 리팩터링성 항목은 개별 수정 대신 제거로 일괄 해소(§4)하며 Top 랭킹에서 제외.

1. 총괄 요약

약 200건
전체 발견 항목 (6영역)
~14,000 LOC
V1 제거 가능 규모 (web ≈11,800 + socket 2,055)
13건
무인증 API 보안 노출 (즉시 조치)
0건
CI 품질 게이트 (타입체크·린트·테스트)

Top 우선순위 (점수순, V1 제거 대상·보안 별도)

점수분류위치내용
2.5tech-debt.github/workflows/*CI에 타입체크·린트·테스트 게이트 전무. 5개 워크플로우 모두 수동 배포 전용(workflow_dispatch), PR/push 트리거 0건 → 타입오류가 프로덕션까지 통과 가능
2.0tech-debtentities/guest-session/model/use-ai-session.ts3,119줄 god-hook. 60+ refs, 25 useEffect가 RTC·TTS·STT·turn-detection·interrupt·transcript를 한 훅에 응집. V2 핵심 경로 최대 리스크
2.0tech-debtentities/guest-page-session/model/use-guest-page-session.ts2,447줄, 32 useEffect. V2 게스트 페이지 세션 전체가 단일 훅 — 최우선 분해 대상
2.0tech-debtturbo.json:13 + 각 package.jsoncheck-types 태스크가 완전 no-op(어느 앱에도 스크립트 없음). strict:true가 어디서도 강제 안 됨
2.0tech-debtapps/web/**/*.test.ts (13개)고아 테스트 — vitest 의존성·test 스크립트·config 전무로 실행 불가능한 테스트 13개 방치
2.0tech-debtlib/utils.ts:209 외 3곳roomId 파싱 4중 중복(utils.ts 실사용 + room-id.ts 데드 + tts/authz.ts·host-intervention 로컬 복제 + shared room.ts) — 단일화 필요
2.0tech-debtapps/web/lib/api/*controller·service·dao 레이어 절반만 마이그레이션(4개 라우트만 경유, lesson/session 5개+internal은 db-queries 직접 호출) — 이중 접근 구조
2.0tech-debtapps/web/types/props/중앙 Props 컨벤션 붕괴 — 인라인 Props 204곳 vs 중앙 1개, import 0건. CLAUDE.md 규칙과 실제 괴리 → 규칙 폐기 or 복원 결정 필요
2.0tech-debtapps/stt/internal/audio/{processor,filter,limiter}.go서버측 DSP 파이프라인 ~300줄 전체가 죽은 코드(실제 필터링은 브라우저 WebAudio). Python 포팅 잔재 — 3파일 통째 삭제 가능
1.5potential-bugsocket/src/redis/room-store.ts:154 + reaper.ts:28죽은 인스턴스의 room이 reaper CAS 실패로 영구 orphan(pin TTL 90s < reap 시점 ~105s → 결정론적). 유령 room이 활성 목록에 잔존
1.5potential-bugsocket/src/redis/client.ts:163 + reaper-scheduler.ts:85Redis 순단 시 heartbeat 유실 → 살아있는 인스턴스가 reap됨(split-brain). 진행 중 수업 세션 강제 정리 가능
1.5tech-debtapps/socket/tsconfig.json:10-24strict:false + noImplicitAny:false + strictNullChecks:false — 실시간 미디어 서버의 타입 안전성 사실상 꺼짐

2. 보안 — 즉시 조치 무인증 API 13건

근본 원인 두 가지: ① 라우트에 withAuthMember 류 인증 래퍼 누락, ② lib/s3.ts 헬퍼가 사용자 제공 s3Key를 prefix 검증 없이 사용. 모범 패턴은 리포 안에 이미 존재(audio-analysis-logs/download-url의 prefix 검증, mfcc-download-url의 DB 저장 key 사용) — 동일 패턴 적용이 처방.

심각도위치내용
S5api/recording-captions/route.ts:11-53무인증 POST가 captionS3Key로 임의 S3 객체 본문 응답 — ${stage}/ice/main_key.json 주입 시 TURN API 키 유출 확정
S5api/recording-download/route.ts:7-22무인증 POST가 body.s3Key 검증 없이 signed URL 발급 — 아동 녹음/키파일 전체 다운로드 가능
S5api/session-logs/route.ts:194-235무인증 DELETE가 s3Key를 그대로 삭제 헬퍼에 전달 — 임의 S3 객체 삭제(데이터 파괴)
S4api/session-logs/route.ts:128-192POST/PATCH 무인증(GET만 인증) — 아동 대화 로그 위변조
S4api/lesson-progress/route.ts:6POST 완전 무인증 — body userId로 임의 아동 레슨 진도 조작
S4api/lessons/[userId]/[index]/sessions/route.ts:23POST 무인증 세션 레코드 주입(GET도 무인증 조회)
S4api/guest-data/route.ts:6-8무인증 GET — userId 열거로 아동 수업 PII IDOR
S4api/issue-texts/route.ts:58-173POST/PUT/DELETE/PATCH 무인증(GET만 인증)
S4api/realtime/call/route.ts:11-45무인증 POST가 OpenAI Realtime 유료 세션 생성 — 비용 남용 벡터
S3api/internal/user-profile/[userId]/route.ts:36로그인 member면 소유권 검사 없이 임의 userId 프로필 반환(IDOR)
S3api/users/route.ts:32전체 사용자 목록을 pin 등 PII 스트리핑 없이 반환(단일조회는 제거하는데 목록은 노출)
S3api/ice-servers/route.ts:14-38무인증 GET이 metered TURN 자격증명 반환 — 무단 relay 사용 가능
S3api/resources/upload-url/route.ts:8무인증 presigned upload URL(최대 100MB) — 스토리지 남용
부수: api/alimtalk/send/route.ts:130-134 — 전화번호(PII)를 평문 로깅 → Loki에 PII 적재. next.config.mjs:34 — 보안 헤더 전무(CSP/HSTS/X-Frame-Options 등).

3. 실행 로드맵 (제안)

4. V1 레거시 제거 플랜 (web ≈11,800 + socket 2,055 LOC)

V2·prompt-test는 V1 훅을 전혀 import하지 않음(grep 0건). socket 쪽도 V2가 V1 코드를 import하는 건 0건 — 얽힘은 소수 공유 컴포넌트/유틸에 국한되어 클린 제거 가능.

제거 대상 (web)

제거 대상 (socket) — 10파일 2,055줄

유지해야 하는 공유 지점 (삭제 금지)

동반 수정

판단 필요 (D): guest-entry.tsx(/guest)에 V1 소켓 플로우 + V2 리다이렉트(tryV2Flow→/client-guest)가 공존. 아동이 실제 접속하는 URL이 /guest인지 /client-guest인지 확인 후 — /client-guest면 통째 삭제, /guest(기존 QR/북마크)면 리다이렉트 스텁으로 대체. socket V1 삭제 전엔 구버전 캐시 클라이언트의 default namespace 접속 여부만 모니터링으로 사전 확인 권장.

권장 제거 순서 (저위험순)

  1. 즉시: app/guest2/**(redirect 스텁, 참조 0) · guest-monitor-view · host-chat-panel(완전 고아)
  2. app/main/meet/** + host.tsx + host 전용 UI + use-host-* 훅
  3. app/main/page.tsx 수정 후 meet.tsx + meet-*(V1 중복본)
  4. D 확인 후: app/guest 일체 + use-guest-*/use-web-rtc/use-screen-share + lib/issue-alert.ts
  5. socket V1 10파일 + server.ts 3곳 → CSS 삭제 → next build로 orphan 재검증

5. V2 시스템 (client-guest · monitor-dashboard · FSD)

점수분류위치내용
2.0tech-debtentities/guest-session/model/use-ai-session.ts3,119줄 god-hook — RTC/DataChannel/TTS/VAD·turn-detection/STT/interrupt/mic/response 큐/transcript 응집. 분리 후보: tts · stt · rtc-connection · turn-detection
2.0tech-debtentities/guest-page-session/model/use-guest-page-session.ts2,447줄, 32 useEffect, 17 useRef — V2 게스트 페이지 전체가 단일 훅
1.5tech-debtapp/monitor-dashboard/[group]/[roomId]/page.tsx1,973줄 페이지 컴포넌트(19 useEffect) — 위젯/훅 추출 필요
1.5tech-debtentities/monitor-session/model/use-monitor-session.ts1,540줄 + as any 31개 밀집(V2 최다) — transcript 타입 정의 누락
1.5tech-debtfeatures/session/ui/session-card.tsx1,303줄 "카드" 컴포넌트(12 useEffect/11 useState)
1.5tech-debtentities/monitor-controls/model/use-guest-controls.ts:5-9FSD 역방향: entities→features 런타임 값 import — 역방향 의존 중 가장 심각
1.5tech-debtfeatures/monitor/hooks/use-session-checker.ts:3 · features/session/ui/{card-toast-overlay,transcript-history}.tsxFSD 역방향: features→widgets 3건(ToastAlimtalkAction · ToastData · ScrollToBottomButton)
1.0tech-debtshared/ui/guest-layout-content.tsx:4 · entities/guest-page-session/model/use-guest-page-session.ts:4shared→entities 타입 역전 1건 + 형제 entity deep-path import(barrel 우회) 1건
1.0tech-debthooks/mediasoup/use-mediasoup-{consumer,producer}.ts:661,323(transport as any)._handler._pc — mediasoup 비공개 내부 접근, 버전업 시 RTT 수집 조용히 파손
1.0tech-debtV2 전반 (use-monitor-session 67 · consumer 57 · external-stt-observer 42 …)raw console.* 약 200개 — createLogger와 혼용, 로깅 체계 불일치(Loki 포맷 이탈)
1.0tech-debtstores/use-language-guard-settings-store.ts:216-294, 691-693수동 deep-equal(payloadEquals) drift 증거(speechOutput 중복 검사) + 모듈 최상위 hydrateFromServer() side-effect(import만 해도 fetch)
0.9potential-bughooks/mediasoup/use-mediasoup-consumer.ts:769-828removePeerStream이 setState updater 안에서 외부 배열 push(순수성 위반) — StrictMode 이중실행 시 중복 정리 + N회 렌더
0.9potential-bughooks/mediasoup/use-mediasoup-producer.ts:409-484,580-641camera/ai produce effect에 mic effect가 가진 disposed 가드 부재 — cleanup 경합 시 producer 누수
0.6potential-bughooks/mediasoup/use-mediasoup-producer.ts:90-243createTransport deps에 attemptReconnect 누락 — stale closure
0.6legacyentities/guest-session/model/{use-transcripts,use-guest-connection}.ts초기 FSD scaffolding 잔재 2파일 — import 0건, 삭제 가능
0.4legacywidgets/monitor/ui/{issue-input-panel,monitor-settings-modal}.tsx · monitor-dashboard/…/focus-toast-layer.tsx미사용 위젯/컴포넌트 3파일 — 참조 0, 삭제 가능

6. 공통 레이어 (lib · app/api · types · shared)

보안 13건은 §2로 분리. 아래는 그 외 항목.

점수분류위치내용
2.0tech-debtlib/utils.ts:209 · lib/room-id.ts:8 · lib/tts/authz.ts:141 · features/host-intervention/api/log-intervention.ts:22roomId 파싱 4중 중복 — utils.ts로 단일화, room-id.ts(전체 데드)는 삭제
2.0tech-debtlib/api/ (controllers·services·daos)레이어 마이그레이션 절반 — 4개 라우트만 경유, 나머지 5개+internal은 db-queries 직접 호출. lesson.dao vs lesson-progress.dao 중복 DAO 포함
2.0tech-debttypes/props/중앙 Props 컨벤션 붕괴(인라인 204곳 vs 중앙 1개, import 0) — CLAUDE.md와 괴리, 규칙 결정 필요
1.5tech-debtapps/web/logger.js vs packages/shared/src/utils/logger.tsLogger 이중 구현 + web logger의 프로덕션 게이팅 주석처리(#shouldLog 항상 true)
1.5tech-debtpackage.json(web)미사용 deps: mysql2 · lamejs(+고아 types/lamejs.d.ts) · @huggingface/transformers(죽은 serverExternalPackages) · react-grab(CDN 로드)
0.9potential-buglib/tts/authz.ts:40 vs lib/tts/limits.ts:27MAX_TEXT_LENGTH 2000 vs 1900 불일치 — 1901~2000자를 429(rate limit)로 오응답
0.9potential-buglib/api/services/lesson-session.service.ts:55sessionId = ${lessonIndex}#${Date.now()} — 동일 ms 재입장 충돌 가능
0.9potential-bugapi/lesson-templates/[id]/route.ts:51 · api/curriculum-categories/[id]/route.ts:28,45비트랜잭션 read-modify-write lost-update + 존재확인 없는 Update/Delete(고아 참조 유발)
0.9potential-bugnext.config.mjs:34보안 헤더 전무(CSP/HSTS/X-Frame-Options/X-Content-Type-Options) — 아동 영상 WebRTC 앱에 클릭재킹/스니핑 노출
0.9potential-bugscripts/import-activity-templates.js:52멱등성 가드 없음 — 재실행 시 전체 템플릿 중복 삽입. copy-lesson-template.js 등 prod STAGE 하드코딩+무가드 덮어쓰기
0.8legacylib/tts/openai.ts 전체 + api/tts/stream/route.tsOpenAI TTS 경로 프로덕션 도달 불가(클라이언트 3곳 모두 typecast 하드코딩) + 완전 데드 스트림 라우트 — 통째 삭제 후보
0.8legacypackages/shared/src/{types/webrtc.ts, types/session.ts 일부, utils/constants.ts 4블록}shared 대량 데드 — webrtc.ts 13개 타입 전부·WEBRTC_CONFIG 등 4블록(~150줄) 사용처 0 (SOCKET_EVENTS·MEDIASOUP_CONFIG는 실사용)
0.6potential-bugdb-queries.ts:1780 · server.js:38-42 · api/holidays/route.ts:39getUserByName 전체 테이블 Scan / 메트릭 타이머 abort 누락 / month NaN 미검증 등 소규모 버그군
0.6legacyCLAUDE.md (PWA 절)PWA 전면 제거됐으나 문서는 상세 유지(layout.tsx는 오히려 SW 등록해제 마운트) — 스테일 문서, 인수인계 오해 유발
0.5tech-debtlib/{room-id,audio-resampler,socket-debug}.tsimporter 0인 데드 파일 3개(각 16·25·38줄) + 데드 export 다수(avatar-id 3종, suggestKeyFromLabel 등)
0.4legacyapi/class-mgmt/classes/counts · api/members/[id] GET · types/db/monitoring-group.types.ts호출처 0 라우트/핸들러/타입 — 삭제 가능
0.5tech-debttypes/error/index.ts:8 vs shared · api/resources/urls/route.ts · db-queries.ts:3163SessionError 이름 충돌 중복 정의 / GET·POST presign 블록 복붙 / DEPRECATED 주석 잔재

7. Socket 서버 (mediasoup SFU · Redis · 녹음)

V1 핸들러 제거(§4)와 별개로, 운영 중인 V2 경로 자체의 안정성 이슈가 다수. 특히 Redis 2건은 결정론적/저확률-고피해 조합.

점수분류위치내용
1.5potential-bugredis/room-store.ts:154-169 + reaper.ts:28-36죽은 인스턴스 room 영구 orphan — pin TTL(90s)이 최소 reap 시점(~105s)보다 항상 먼저 만료 → REAP_ROOM_LUA skip, roomKey는 TTL 없어 영구 잔존. 결정론적 발생
1.5potential-bugredis/client.ts:163-168 + reaper-scheduler.ts:85-94heartbeat 쓰기 실패(순단+offlineQueue:false) 시 살아있는 인스턴스가 reap — 진행 중 세션 강제 정리(split-brain). two-phase가 같은 키만 재검사해 방어 불가
1.5tech-debtapps/socket/tsconfig.json:10-24strict 계열 전부 off + allowUnreachableCode:true — 단계적 strict 도입 필요
1.2potential-bugsfu-socket/handlers/room-handlers.ts:68-265GUEST_REQUEST_ENTRY 전체 try/catch 부재 — Redis 실패 시 callback 미도달 → 아동 입장 화면 무한 대기
1.2potential-bugrecording/recordingManager.ts:909-937createPlainTransportConsumer — connect/consume throw 시 PlainTransport close 없이 누수(반복 실패 시 누적)
1.2potential-bugrecording/recordingManager.ts:1493-1554, 1405-1447transcode/concat ffmpeg 타임아웃 부재 — hang 시 세마포어(max 2) 영구 점유 → 이후 모든 녹음 transcode 블록
0.9potential-bugmediasoup/routerManager.ts:137-164 · transportManager.ts:46-72, 83-86동시 createRouter 경쟁 orphan(인플라이트 캐시 없음) / setMaxIncomingBitrate 실패 orphan / transport routerclose 미구독(좀비)
1.5tech-debtmediasoup/routerManager.ts:192-214, 578-593closeRouter/closeAll이 transport 정리 미배선 — 이미 구현된 closeTransportsByRoom 등이 호출 0(dead). 배선하면 위 좀비 문제 동시 해결
0.9potential-bugrecording/recordingManager.ts:1384-1403, 1484-1489, 389-393 · udpPort.ts:7-27killFfmpeg exit 무한 대기 / stdin EPIPE 리스너 부재(uncaught) / replaceAiConsumer aiPair 덮어쓰기 누수 / TOCTOU 포트 예약
0.9potential-bugredis/peer-store.ts:58-174 · room-store.ts:35-53 · reaper-scheduler.ts:110-146peer upsert/remove 비원자(역인덱스 stale) / setRoomMeta가 HINCRBY 카운터 덮어씀 / two-phase 후 leader 재확인·재진입 가드 없음
0.9potential-bugsfu-socket/handlers/monitoring-handlers.ts:138-228 · connection-handlers.ts:34-135 · room-handlers.ts:371-398 · session-handlers.ts 다수HOST_START_MONITORING hang / JOIN_ROOM 중복정리가 redirect 판정보다 먼저(타 회기 파괴) / FORCE_KICK 1초 후 socketId 재확인 없음 / payload 권한·가드 비일관
1.0tech-debtrecording/recordingManager.ts (1,740줄)거대 클래스 — 녹음 상태·ffmpeg 수명·세그먼트·캡션 좌표 혼재. gracefulDrain/kill/stopFfmpeg 3중 중복, transitionFfmpeg ~185줄
1.0tech-debtconnection-handlers.ts:46-75 ↔ room-handlers.ts:93-118 ↔ signalingHandler.ts:83-91"중복 게스트 정리" 3중 복붙 + monitoring-handlers↔signalingHandler 순환 의존 — cleanupGuestPeer() 추출
1.0tech-debtsocket 테스트 전반테스트 8개가 순수 함수 위주 — mediasoup 생명주기·V2 핸들러·reaper/leader election·recordingManager 본체 전부 무커버
0.6potential-bugmedia-handlers.ts:99-164 · transport-handlers.ts:32,62 · room-handlers.ts:451 · settings-store.ts:38-70callback 가드 비일관 / SET_AUTO_RESPONSE await 누락 / setter만 try/catch 없음 등 S2 버그군
1.0tech-debtsfu-config.ts:54-65 · memory-only dead path · mediasoup 미사용 함수 7개 · describeError 중복 외S1~2 데드/중복 잔재군 — config.server(3002) 미사용, getRedis()===null 도달 불가 분기(CLAUDE.md 불일치), N+1 redis.exists 등

8. STT 시스템 (apps/stt Go + web 클라이언트)

점수분류위치내용
2.0tech-debtinternal/audio/{processor,filter,limiter}.go (~300줄)서버측 DSP 파이프라인 통째 데드 — 실제 HPF+Limiter는 브라우저 WebAudio에서 수행. Python 포팅 잔재, 3파일 삭제 가능
1.2potential-buginternal/handler/websocket.go:273-436conn.WriteJSON을 배치 goroutine들과 read-loop이 뮤텍스 없이 동시 호출 — gorilla/websocket 단일 writer 규약 위반 → data race, 최악 패닉
1.5tech-debtinternal/diarization/speaker.go:40-161 (~110줄)Jaro-Winkler 텍스트 유사도 화자매칭 전체 미사용(실사용은 First-Speaker Rule만) — 삭제 가능
0.9potential-buginternal/handler/websocket.go:287-316,420 + session.goAIContext/TurnIndex를 goroutine에서 락 없이 읽고 씀(session mu 우회) — data race
0.9potential-buginternal/handler/websocket.go:362-416handleProcessAIAudio가 STT API를 동기(≤10s)로 호출해 read-loop 블록 — 오디오 프레임 백프레셔/유실 위험
0.9potential-bugentities/guest-session/lib/external-stt-observer.ts:262-288WS 재연결 시 서버가 새 세션 생성 → TurnHistory/dedup 상태 전부 소실 + S3 sessionId 변경(세션 연속성 유실)
0.6legacyexternal-stt-observer.ts:175-202"monitor"/"finalized" 메시지 핸들링 — 서버는 절대 송신 안 함(batch_result/ai_stt뿐). 구 스트리밍 모드 데드 브랜치
1.0tech-debtinternal/{session,stt,audio}/* 잔여미사용 심볼군 — CommitCurrentTurn(Deprecated)·GetCombinedAudio·PCMToWAV류·Streaming config 잔재·client.Close() 미호출 / batch.go dedup 로직 인라인 중복 / chirp_3 하드코딩 이원화
0.4legacymessages.go:26-27 · use-stt-fallback.ts:57-60 · external-stt-observer.ts:151Suppressed 항상 false(미구현 잔재) / serviceURI 데드 설정(Web Speech 구식 경로) / "ppipythonstt" URL 네이밍 잔재
0.5tech-debtwebsocket.go:26-28 · external-stt-observer.ts:312CheckOrigin 항상 true / deprecated ScriptProcessorNode(→AudioWorklet 이전 권장)
양호: dedup 코어는 dedup_test.go로 잘 커버. debounce stale-drop 가드, connectionGeneration 패턴 견고. CLAUDE.md의 /api/stt-validator/는 리포에 존재하지 않음(스테일 문서).

9. 인프라 · 설정 · 의존성

점수분류위치내용
2.5tech-debt.github/workflows/* (5개)CI 품질 게이트 전무 — 전부 workflow_dispatch 배포 전용, PR/push 트리거·lint·test·tsc 실행 0건
2.0tech-debtturbo.json:13check-types 태스크 no-op(어느 앱에도 스크립트 없음)
2.0tech-debtapps/web (테스트 러너 부재)고아 테스트 13개 — vitest 의존성·스크립트·config 전무로 실행 불가
1.5tech-debtapps/socket, apps/stt (lint 부재)ESLint가 web에만 존재 — socket/stt는 turbo lint에서 조용히 스킵
0.9potential-bugapps/web/package.json:10next lint는 Next.js 16에서 제거된 명령 — 실행 시 깨질 가능성(로컬 검증 필요)
1.0tech-debtroot package.json:26 · packages/shared/package.jsonTailwind v3(root)+v4(web) 혼재, root autoprefixer 미사용 / shared의 서버 SDK mediasoup 미사용 선언 + 버전 제각각
1.0tech-debtCLAUDE.md경로 드리프트 — /main/preset·/main/template·socket/server.js·lib/openai.ts 실재하지 않음. apps/stt 앱 자체가 문서에 없음
0.4legacyroot package.json:18-20 · Dockerfile.dev · terraform/branch-deploy/userdata.sh존재하지 않는 앱 참조 dev 스크립트(client-web/server-sfu) + DEPRECATED 스텁 2파일 잔존
0.5tech-debtapps/socket/vitest.config.ts:12 · eslint.config.mjs:48 · next.config.mjs:10커버리지 범위 redis만 / react-hooks/exhaustive-deps off(위 훅 deps 버그들과 직결) / reactStrictMode:false

10. 판단 필요 사항 (사용자 결정 대기)

  1. 아동 실제 접속 URL — /guest(QR/북마크) vs /client-guest. guest-entry.tsx 삭제 방식 결정(§4 D).
  2. types/props 컨벤션 — 규칙 폐기(CLAUDE.md 수정) vs 복원. 현실은 이미 인라인 204곳.
  3. Web Speech API 폴백(use-stt-fallback) — 구식 경로지만 토글로 살아있음. 외부 Go STT 안정화 후 제거 여부.
  4. main/ 관리 페이지들(activity·class-mgmt·schedule 등) — 이번 감사에서 "사용 중"으로 간주. 미사용 페이지가 있으면 레거시 목록에 추가 가능.

관련 문서