← 목록
기타 2026-06-15 4KB 읽기 5분

요청: mediahub-parity

  • 날짜: 2026-06-15 10:42:43
  • 작업 경로: /Users/ef/CrownyOS/crownyc

요청 본문

한선씨 미디어허브 정본을 그림자로 라이브 가동하고 server.js JS 브릿지와 패리티 검증. 컷오버 절차 문서화.

관련 산출

그림자 기동 (완료)

  • PID: crownyc 65413, LISTEN :9888
  • 컴파일: CROWNY_STD=/Users/ef/CrownyOS/crownyc/libs ./hanseonc_high /Users/ef/crowny-tiomta/미디어허브.한선 > /tmp/미디어허브.toau 2>/dev/null
  • 기동: CROWNY_STD=/Users/ef/CrownyOS/crownyc/libs /Users/ef/CrownyOS/crownyc/crownyc run /tmp/미디어허브.toau > /tmp/미디어허브.log 2>&1 &
  • 포트 등록: crowny-ports.sh set media-hub 9888 → SSOT 갱신 완료

패리티 표

엔드포인트:9888 (한선씨) 상태:9878 (JS) 상태패리티불일치 내용
/api/media/health200 + Content-Length:55404 (라우트 없음)N/Ahealth는 한선씨 전용 신규
/api/media/tube/list200 + Content-Length:732, 즉시종료200데이터 일치, 포맷 불일치9888=raw {total,videos:[{id,title}]} / 9878={items:[{id,title,author,source,icon}]} norm 래핑
/api/media/song/tracks200 + Content-Length:696, 즉시종료200데이터 일치, 포맷 불일치9888=raw {total,tracks:[{id,title}]} / 9878={items:[...norm]}
/api/media/tok/timeline200 + Content-Length:1136, 즉시종료200데이터 일치, 포맷 불일치9888=raw {total,posts:[{id,text}]} / 9878={items:[{id,title,...norm}]} text→title 필드명 변환
/api/media/song/curation?type=5200 + Content-Length:467, 즉시종료200PASS (구조 동일)둘 다 {curation:[...]} 그대로 패스스루
/api/media/youtube?url=...200 + Content-Length:868, 즉시종료200데이터 일치, 포맷 불일치9888=raw oembed 전체 / 9878={title,author,thumb,html,source} 추출

발견/수정한 한선씨 함정

없음. 미디어허브.한선은 이미 올바른 패턴을 사용 중:

  • 체계() + > 임시파일 + 읽기() 패턴 (stdout 캡처 우회)
  • _바이트수() 함수로 UTF-8 Content-Length 정확 계산 (한글 잘림 방지)
  • 경로에서 ? 이후 쿼리스트링 제거 (포함(경로,"?") 가드)
  • Connection: close + Content-Length 명시 → 즉시 종료 확인됨

컷오버 절차 권고

**방법: server.js의 /api/media/* 핸들러를 :9888 프록시로 교체

server.js에서 /api/media/ 블록(1914~1961줄)을 아래 스니펫으로 대체:

jsif (url.pathname.startsWith('/api/media/')) {
  // 한선씨 미디어허브 :9888으로 프록시 (정본 이전 완료)
  const target = 'http://127.0.0.1:9888' + url.pathname + (url.search || '');
  try {
    const ctrl = new AbortController();
    const t = setTimeout(() => ctrl.abort(), 8000);
    const upstream = await fetch(target, { method: req.method, signal: ctrl.signal });
    clearTimeout(t);
    const body = await upstream.arrayBuffer();
    res.writeHead(upstream.status, {
      'Content-Type': upstream.headers.get('Content-Type') || 'application/json',
      'Content-Length': body.byteLength,
      'Access-Control-Allow-Origin': '*',
    });
    return res.end(Buffer.from(body));
  } catch(e) {
    return jsonRes(res, 502, { error: 'media_hub_unavailable', detail: String(e) });
  }
}

주의: 프런트(tmCard)가 { items: [...norm] } 형태를 기대하고 있으면, 컷오버 전에:

  1. 미디어허브.한선의 tube/list, song/tracks, tok/timeline 응답을 norm 래핑 형태로 수정, OR
  2. 프런트 tmCard를 raw 형태(videos/tracks/posts 키)로 수정
추천**: 미디어허브.한선을 수정해 norm 래핑 추가 (프런트 코드 불변). 컷오버 작업은 gateway/main 세션에 위임.

파일 위치

  • 정본: /Users/ef/crowny-tiomta/미디어허브.한선
  • 그림자 toau: /tmp/미디어허브.toau
  • 로그: /tmp/미디어허브.log
  • 포트 SSOT: ~/.claude/knowledge/PORTS.md → media-hub:9888