BLUF
WS-E(M6 direct-callcenter 데이터 이관) 완료 기준 전부 충족, PR #7 생성(머지는 PM 순서 조정 대기). https://github.com/shinjadong/callcenter-os/pull/7
소스 판정 (1순위 산출물 — docs/handoff/WS-E-source-audit.md)
ljiam(direct-callcenter)이 단일 진실 소스.
- akahc(대시보드 하드코딩 추정 대상): 실체는 customer_status 단 1테이블(6,421행), 2026-06-01 이후 정지 → '실기록 대상' 가설 기각
- metqz↔ljiam call_recordings 552행: md5 집계 해시 완전 일치(전사·등급까지 동일 사본)
- akahc/metqz customer_status 샘플 60/60이 ljiam에 존재+payment_status 일치 → 부분집합 증명
- leads 9,596·memos 5,128·dc_* 테이블은 ljiam 단독 보유, 데이터는 2026-06-11 이후 동결
- 원본 3곳 읽기 전용 SELECT/GET만 수행(무수정·무삭제), ljiam 키 값은 어떤 산출물에도 미기재
구현 (core/scripts/migrate_dc.py, TDD)
- 상태 매핑: paid 최우선→개통완료 / consulting→처리중 / converted→개통완료 / failed→실패(사유미상). 원본 값은 Lead.custom dc_* 키로 무손실 보존
- 녹취: recording_date UTC→KST(+09:00, M3 filename_parser 계약), call_reviews→manual_grade/manual_note 병합
- 멱등: Lead=(tenant,phone)·Recording=(tenant,file_name) — 재실행 시 기존 행 스킵
- 검증 내장: 건수 대조표 + 무작위 20건 필드 대조 자동 출력(불일치 시 exit≠0)
검증 증거
- 단위테스트 8개(가짜 fixture, 실 Supabase 불필요) + 전체 회귀 백엔드 110 passed·프론트 54 passed·build OK
- 실드라이런(스크래치 sqlite): ljiam 전량 22,002행 페치(SQL 실측과 건수 정확 일치) → 10,286 리드+552 녹취 적재, 무작위 20/20 필드 일치, 재실행 시 신규 0건(멱등 증명), 스킵 4건(정규화 후 중복)만
관찰·후속
- 소스 recording_date가 전부 일괄 임포트 시각(2026-05-26)이고 실통화 일시는 file_name에만 존재 → 보정은 후속 결정(audit §6)
- metqz·ljiam public 테이블 다수 RLS 비활성(anon 키 전면 노출) — 컷오버 후 원본 접근 차단 시 정리 권장
- dashboard v2 처분·컷오버는 자동님 결정 대기(이관과 독립)
[full report: /home/tlswk/projects/callcenter-os/.worktrees/ws-e/docs/handoff/WS-E-source-audit.md]