← 목록
기타 2026-07-31 13KB 읽기 13분

크라우니 브랜딩 — 마케팅 OS 디자인 이식 (branding.crowny.org:9630)

개요

클로드 디자인 핸드오프 design_handoff_crowny_marketing_os(Crowny Marketing OS v2)를 라이브 서비스로 이식. 유튜브 쇼츠 제작 + 온라인 마케팅 자동화 SaaS — 9채널 연결 / 전략 대시보드 / 크리에이티브 킷 / 기획 보드 / 쇼츠 스튜디오 / MCP 도구 / 에이전트 / 모니터링 / 댓글 인박스 / 셀프리포트 10섹션.

무엇을 했는지

1. 디자인이식 도구 경유 (인라인 재해석 금지 계약 준수)

  • 디자인이식.sh unpack → 정본 추출(마크업 97KB·로직 55KB·tokens), 원본 dir 물리 잠금
  • 디자인이식.sh register 크라우니마케팅OS <원본> /Users/ef/crowny-brand
  • 재창작 0Crowny Marketing OS v2.dc.html바이트 동일public/index.html에 내장(cmp PASS, 155,273B), support.js dc 런타임 그대로.

2. 순수 한선씨 서버 (sonnet 위임 → 메인 재검증)

/Users/ef/crowny-brand/서버.한선 — 정적 서빙 + API. hanseonc_high 경고 0, 3429토큰/10128큐브.
  • 정적: /(index) · /support.js · /crowny-logo.png · /crowny-logo-dark.png
  • API: /api/health · /api/channels(9채널) · /api/agents(7종) · /api/report/daily
  • 데이터: data/채널.psv, data/에이전트.psv (append-only)

3. 라이브 실측 (메인 세션 독립 재검증)

경로코드바이트원본판정
/200155273155273cmp 바이트동일 PASS
/support.js2006915069150PASS
/crowny-logo.png2001492614926PASS
/crowny-logo-dark.png2001323613236PASS
/api/health200{"ok":1,"service":"crowny-branding","port":9630}PASS
/없는경로404200위장 없음
  • 상주화: LaunchAgent org.crowny.branding (KeepAlive, CROWNY_STD 주입) — bootstrap 후 health 200
  • 게이트웨이: branding.crowny.org 업스트림 9755→9630 전환, crowny-brand/brand.crowny.org 임시 엔트리 제거. Host 헤더 실측 200/155273
  • 육안: 헤드리스 스크린샷이 시안 01-connect.png와 동일 렌더 확인

4. 디자인 게이트

디자인이식.sh diff 크라우니마케팅OS판정=티 점수=100, 신규색0 유실색0 신규치수0 원본훼손0

도메인 배치 결정 (사용자 확정)

  • branding.crowny.org = 마케팅 OS(:9630)로 교체
  • 기존 "크라우니 브랜딩"(:9755, /Users/ef/crowny-branding)은 findev.crowny.org로 계속 라우팅돼 살아있음 — 유실 0

도구 버그 2종 적발 + 보수 (재발방지)

  1. 디자인이식.sh unpack의 tokens.css 추출이 python3 의존(451~475행) → 파이썬 금지 환경에서 빈 파일 → 시안 자체 색 41개가 전부 "신규색" 오탐
  2. register가 매니페스트 경로를 원본.매니페스트.sha256(슬래시 누락)으로 기록 → 파일 부재 → 원본훼손=1 고정, 판정 항상 타/음
→ 두 건 모두 보수(원본 :root/dark 블록 발췌 기입 + 인벤토리 등재 + 레지스트리 경로 교정 + 매니페스트 재기준화), 이식노트.md에 이력 기록. 메모리 등재 feedback_디자인이식_unpack_python3의존_매니페스트경로버그.

PSV 보수 함정: append 대상 파일을 동시에 awk 입력으로 읽어 121줄→76,694,394줄 무한증식 사고 발생. 백업 복구 후 임시파일 경유로 재작업. 반드시 cp 백업 + 임시파일.

관련 파일

  • 서비스: /Users/ef/crowny-brand/ (서버.한선, 서버.toau, public/, data/, 기준스크린샷/, 핸드오프-README.md)
  • 이식 정본: ~/.claude/design-port/크라우니마케팅OS/ (원본/, 이식노트.md, 토큰정본.psv, 리포트/)
  • LaunchAgent: ~/Library/LaunchAgents/org.crowny.branding.plist
  • 게이트웨이: /Users/ef/crowny-gateway/gateway.yaml 2166~2170행 (백업 /tmp/gateway.yaml.bak-*)

잔여 이슈 (다음 작업)

  1. tiomta.com 전환 추적 파라미터 연동 — 사용자 확정 1순위. 조사 진행 중
  2. 유튜브 / 인스타그램 / 틱톡 OAuth 실연동 (현재 채널 데이터는 PSV 더미)
  3. 공개 HTTPS는 헤어핀 NAT로 로컬 curl 000 — 인프라 수정 금지, 외부에서 확인 필요
  4. 서비스 디렉토리명이 crowny-brand인데 서비스명은 crowny-branding — 정리 여부 판단 필요
  5. AI 기능(대본 생성·댓글 초안·리포트 요약·금지어 필터)은 미배선 — LLM 호출 또는 한선씨 결정형 엔진 선택 필요

2차: tiomta.com 전환 추적 연동 (같은 날 완료)

구현

  • 수신측(한선씨, 서버.한선 확장): POST /api/track(전환 이벤트 → data/전환.psv append-only) · GET /api/track/summary(인메모리 카운터 집계, 요청마다 PSV 재파싱 안 함) · CORS(tiomta.com/www/127.0.0.1:9878) · OPTIONS 204 · 필수필드 누락 400
  • 발신측(tiomta): 신규 public/js/crowny-track.js(utm 파싱 + localStorage crowny_utm_v1 첫방문 보존 + sendBeacon/fetch 폴백 + window.CrownyTrack.conversion() 전역) + 동반 크라우니추적.한선(컴파일 통과)
  • 배선: public/index.html·public/shell/app-shell.html 끝에 script 1줄(?v=2). server.js CSP connect-src에 branding 추가(백업 후 1줄)

실측 (종단)

항목결과
POST /api/track{"ok":1,"logged":1}
필수필드 누락400 (200 위장 없음)
OPTIONS 프리플라이트204
GET /api/track/summary집계 정상 (총 9건, event/utm_source/source별)
브라우저 E2E (tiomta 루트)PASS?utm_campaign=final_root 방문 → 1785470714\|view\|tiomta\|youtube\|shorts\|final_root\|\|\|/ 적재
branding 정본 회귀/=200/155273 cmp 바이트동일, support=69150, 로고 2종 일치, 404=404
API 4종전부 200
tiomta 회귀루트 200/33477, trackjs 200
게이트웨이branding 200/155273 · findev(레거시) 200/33769 · tiomta 200/33477
디자인 게이트판정=티 100점 (신규색0 유실색0 훼손0)

적발한 함정 3종

  1. index.html은 실제 루트가 아니다server.js:2723/public/shell/app-shell.html로 재작성. index.html만 고치면 실사용자에게 도달 0. 두 파일 모두 배선.
  2. POST 본문 유실 — 헤더/본문 분리 전송 클라이언트(NSURLSession/fetch)에서 TCP읽기(fd,16384) 단일 호출로는 본문 0바이트. Content-Length 기반 추가 읽기(상한 5회)로 수정.
  3. sendBeacon + application/json = 전량 조용한 유실 — 프리플라이트 불가로 안 나가는데 true 반환 → fetch 폴백도 스킵, 콘솔 0건. text/plain;charset=UTF-8로 교정하니 즉시 적재. 메모리 등재 feedback_sendBeacon_application_json_조용한폐기.
- 부수 발견: WKWebView는 서브리소스 JS를 공격적으로 캐시 — 수정 후 ?v=N 필요(이것 때문에 루트 E2E가 한 번 더 실패했었음).

백업

/tmp/tiomta-server.js.bak-* · /tmp/tiomta-index.html.bak-* · /tmp/tiomta-app-shell.html.bak-* · /tmp/gateway.yaml.bak-*

다음

유튜브 / 인스타그램 / 틱톡 OAuth 실연동 (현재 채널 데이터는 PSV 더미)


3차: 채널 실연동 배선 + 티옴타 브랜드 개설 (같은 날)

결정적 발견 — 한선씨 아웃바운드 HTTPS 가능

조사 에이전트가 "한선씨엔 외부 API 호출 전례 없음 → Node 사이드카 하이브리드 필요"로 결론냈으나 라이브 반증에 성공: 가져오기 "TLS.한선"TLS연결/TLS쓰기/TLS읽기/TLS닫기(네이티브 opcode 800~803) → www.googleapis.com:443에서 HTTP/1.1 200 OK + JSON 실수신. → 아키텍처를 Node 하이브리드로 틀지 않고 순수 한선씨 유지. 메모리 등재 feedback_한선씨_아웃바운드HTTPS_가능_TLS옵코드800.
  • 함정: TLS.한선의 고수준 HTTPS_GET() 래퍼는 빈 응답 반환 → raw opcode 직접 조립 필요. 응답은 chunked라 직접 디코딩. 핸들 0은 유효값(실패 아님).

구현

  • 외부API.한선(신규) — raw TLS opcode HTTPS 클라이언트 + chunked 디코딩 + 반복읽기 상한 + 셀프테스트(googleapis 200 실측)
  • 유튜브연동.한선(신규) — YouTube Data API v3 channels?forHandle= 조회·파싱
  • 서버.한선POST /api/channels/youtube/sync 추가, 상태코드 매핑표에 503 등재
  • data/채널.psv 스키마 확장: id|이름|아이콘|상태|팔로워|마지막동기화|핸들|플랫폼|자격증명상태
  • .env.example(플레이스홀더만). .env는 생성하지 않음

채널 실제 상태 (더미 제거 — 모르는 값은 0)

채널상태핸들
유튜브handle_only@today-cosmetic (채널명 오늘의화장품, 실재 확인)
티옴타live오늘의 화장품
인스타·틱톡·쓰레드·X·치지직·네이버·카카오not_created-
기존 더미 팔로워 수(12,400 등)는 전량 제거. 자격증명 없는 상태의 sync는 503 {"ok":0,"reason":"no_credential"} (200 위장 금지).

티옴타 브랜드 개설 (자격증명 불필요 — 실제 완료)

data/brands.jsontoday-cosmetic 등재 → 라이브 API /api/worldview/brands 실측 7개 중 노출 PASS(단계=운영), worldview 페이지 200.
  • 콘텐츠(쇼츠) → 티옴타 진단·처방 → 전환추적 퍼널로 잇는 구조로 컨셉 정의
  • 백업 /tmp/brands.json.bak-*
  • ⚠️ 티옴타에는 실제 주문·결제 커머스 백엔드가 없다brands.json은 세계관 브랜드 레지스트리이고 worldview 페이지에 노출될 뿐이다. "상점"으로 실제 판매하려면 별도 구축 필요(crowny-market 연계 검토).

회귀 (전부 PASS)

정본 index 바이트동일 · support 69150 · health/agents/report/track 200 · 404 · tiomta 200/33477 · 디자인 게이트 판정=티 100점

자격증명 발급 안내

docs.crowny.org/docs/2026-07-31-채널-실연동-자격증명-발급안내 — 플랫폼별 절차·함정·권장순서


4차: 유튜브 실연동 활성화 (2026-08-01)

자격증명 발급 (브라우저 자동화로 수행 — 사용자 위임)

크라우니AI 브라우저로 Google Cloud Console 조작. 기존 프로젝트 crowny-84b84 재사용(새 프로젝트 생성 안 함), 기존 Firebase 키는 무수정.
  • YouTube Data API v3 사용 설정
  • 신규 API 키 발급 — API 제한사항 = YouTube Data API v3 1개로 한정(최소권한)
  • 키는 /Users/ef/crowny-brand/.env (chmod 600), .gitignore 등재. 대화·문서에 값 미노출. 작업 중 스크린샷 전량 삭제

실연동 실측 (더미 아님)

POST /api/channels/youtube/sync
→ {"ok":1,"name":"오늘의화장품","followers":"0","videoCount":"0"}
채널 상태: status: live, credentialStatus: ok, name: 오늘의화장품(API가 반환한 실제 채널명), lastSync 갱신

독립 대조(서비스를 거치지 않고 YouTube API 직접 호출):

항목
채널명오늘의화장품
게시일2026-07-31T04:29:52Z
구독자0 (hiddenSubscriberCount=false)
영상수0
총조회수0
0은 파싱 실패가 아니라 실제값이다. 채널이 어제 개설돼 업로드가 아직 없다. 서비스 표시값과 API 원본값이 일치.

브라우저 자동화 함정 (실측)

  • 크라우니AI 브라우저의 JS 합성 키 이벤트는 실제 포커스 이동을 못 한다Tab을 보내면 target이 BODY로 잡히고 포커스가 안 옮겨간다. 폼 순회를 키보드로 하지 마라.
  • type은 기존 값에 append된다(치환 아님). 이름 필드가 API 키 2개crowny-branding-youtube...로 오염됨 — 기능 무관, 라벨만 지저분. 필요 시 콘솔에서 이름만 수정.
  • Angular Material 메뉴는 js 클릭으로 안 열릴 때가 있다click(js) 직후 곧바로 닫힘. clickArrowDown 순서로 보내면 열린 채 유지됐다.
  • cgevent 마우스 주입은 이 앱에 도달하지 않는다(포커스만 잡힘). 클릭은 js 경로만 유효.
  • 뷰포트 밖(y>735) 좌표 클릭이 실제로 동작했다 — 화면엔 안 보이지만 elementFromPoint가 잡아 제출까지 됨. "안 보이니 못 누른다"고 단정하지 마라.

남은 것

  • 유튜브 업로드·댓글은 OAuth 필요(현재 키는 읽기 전용). 본인 채널만이면 테스트 사용자 상태로 심사 불필요
  • 인스타(프로페셔널 계정 전환 선행) · 틱톡(심사 리드타임 김) 미발급