# INFINITH — 데이터셋 정의서 **Version:** 1.0 | **Updated:** 2026-03-30 | **Status:** Mock → Real 전환 설계 현재 프론트엔드 데모에서 사용 중인 모든 데이터를 정리하고, 실제 서비스 구현 시 각 데이터의 **수집 소스**, **수집 방법**, **우선순위**를 명시한다. --- ## 목차 1. [데이터 흐름 개요](#1-데이터-흐름-개요) 2. [Report 데이터 (MarketingReport)](#2-report-데이터-marketingreport) 3. [Plan 데이터 (MarketingPlan)](#3-plan-데이터-marketingplan) 4. [Studio 데이터 (Content Studio)](#4-studio-데이터-content-studio) 5. [수집 소스별 분류](#5-수집-소스별-분류) 6. [AI 생성 데이터](#6-ai-생성-데이터) 7. [데이터 의존 관계](#7-데이터-의존-관계) 8. [Firecrawl 수집 검증 결과](#8-firecrawl-수집-검증-결과) --- ## 1. 데이터 흐름 개요 ``` 사용자 입력 (URL) ↓ ┌─────────────────────────────────────────────┐ │ Phase A: 데이터 수집 (Crawl + API) │ │ 웹사이트 → YouTube → Instagram → Facebook │ │ → 강남언니 → 네이버 → 기타 플랫폼 │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Phase B: AI 분석 (LLM) │ │ 채점 → 진단 → 전략 수립 → 로드맵 → KPI │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Phase C: 산출물 렌더링 │ │ Report → Plan → Studio → Distribution │ └─────────────────────────────────────────────┘ ``` **현재 상태:** Phase A~B가 모두 `src/data/mockReport.ts`, `src/data/mockPlan.ts`에 하드코딩되어 있음. --- ## 2. Report 데이터 (MarketingReport) > 타입 정의: `src/types/report.ts` > Mock 데이터: `src/data/mockReport.ts` > 사용 페이지: `/report/:id` (`src/pages/ReportPage.tsx`) ### 2.1 기본 메타 정보 | 필드 | 타입 | 현재 Mock 값 | 수집 소스 | 수집 방법 | |------|------|-------------|-----------|-----------| | `id` | string | `'view-clinic'` | 시스템 생성 | UUID / slug | | `createdAt` | string | `'2026-03-22'` | 시스템 생성 | 리포트 생성 시점 | | `targetUrl` | string | `'https://www.viewclinic.com'` | **사용자 입력** | 분석 시작점 | | `overallScore` | number | `62` | **AI 생성** | 채널 점수 가중 평균 | ### 2.2 의원 현황 (ClinicSnapshot) | 필드 | 타입 | 현재 Mock 값 | 수집 소스 | 수집 방법 | |------|------|-------------|-----------|-----------| | `name` | string | `'뷰성형외과의원'` | 웹사이트 크롤링 | ``, 메타태그, 구조화 데이터 | | `nameEn` | string | `'VIEW Plastic Surgery'` | 웹사이트 크롤링 | 영문 페이지 또는 메타태그 | | `established` | string | `'2005'` | 웹사이트/강남언니 | 본문 파싱 | | `yearsInBusiness` | number | `21` | 계산 | `현재연도 - established` | | `staffCount` | number | `28` | 강남언니/웹사이트 | 의료진 페이지 크롤링 | | `leadDoctor.name` | string | `'최순우'` | 강남언니/웹사이트 | 대표원장 정보 | | `leadDoctor.credentials` | string | `'서울대 출신, 의학박사'` | 웹사이트 | 의료진 프로필 파싱 | | `leadDoctor.rating` | number | `4.7` | **강남언니 크롤링** | 의료진 평점 | | `leadDoctor.reviewCount` | number | `1809` | **강남언니 크롤링** | 의료진 리뷰 수 | | `overallRating` | number | `4.8` | **강남언니 크롤링** | 병원 전체 평점 | | `totalReviews` | number | `18840` | **강남언니 크롤링** | 총 리뷰 수 | | `priceRange` | object | `{ min: '97,900', max: '13,200,000+' }` | **강남언니 크롤링** | 시술 가격 범위 | | `certifications` | string[] | 10개 항목 | 웹사이트 크롤링 | 인증/수상 섹션 파싱 | | `mediaAppearances` | string[] | 3개 항목 | 웹사이트 크롤링 | 미디어 출연 섹션 | | `medicalTourism` | string[] | 3개 항목 | 웹사이트/VisitKorea | 의료관광 관련 정보 | | `location` | string | `'서울시 강남구...'` | 웹사이트/네이버 플레이스 | 주소 파싱 | | `nearestStation` | string | `'9호선 신논현역...'` | 웹사이트/네이버 지도 | 교통 정보 | | `phone` | string | `'02-539-1177'` | 웹사이트 크롤링 | `<a href="tel:">` 또는 본문 | | `domain` | string | `'viewclinic.com'` | 사용자 입력 | URL에서 추출 | | `logoImages.circle` | string | 이미지 경로 | **웹사이트 크롤링** | favicon, 로고 `<img>` 추출 | | `logoImages.horizontal` | string | 이미지 경로 | **웹사이트 크롤링** | 헤더 로고 추출 | | `logoImages.korean` | string | 이미지 경로 | **웹사이트 크롤링** | 한글 로고 변형 | | `brandColors.primary` | string | `'#7B2D8E'` | **이미지 분석** | 로고 색상 추출 (Vision API / CSS 파싱) | | `brandColors.accent` | string | `'#E8B931'` | **이미지 분석** | 로고 보조 색상 | | `brandColors.text` | string | `'#6B2D7B'` | **CSS 파싱** | 웹사이트 텍스트 색상 | ### 2.3 채널 종합 점수 (ChannelScore[]) | 필드 | 타입 | 수집 소스 | 비고 | |------|------|-----------|------| | `channel` | string | 시스템 정의 | YouTube, Instagram KR, Instagram EN, Facebook, 강남언니, Website | | `icon` | string | 시스템 정의 | lucide-react 아이콘명 | | `score` | number (0-100) | **AI 생성** | 채널별 수집 데이터 기반 채점 | | `maxScore` | number | 시스템 정의 | 항상 100 | | `status` | Severity | **AI 생성** | score 기반 등급 (critical/warning/good/excellent) | | `headline` | string | **AI 생성** | 한 줄 요약 텍스트 | 현재 Mock 데이터: | 채널 | 점수 | 상태 | 헤드라인 | |------|------|------|----------| | YouTube | 65 | warning | 103K 구독자, 조회수 하락세 | | Instagram KR | 35 | critical | 14K 팔로워, Reels 0개 | | Instagram EN | 55 | warning | 68.8K 팔로워, 활발한 편 | | Facebook | 40 | critical | 브랜드 불일치, 계정 분산 | | 강남언니 | 95 | excellent | 4.8점, 18,840 리뷰 | | Website | 50 | warning | SNS 연결 없음, 트래킹만 존재 | ### 2.4 YouTube 분석 (YouTubeAudit) | 필드 | 타입 | 현재 Mock 값 | 수집 소스 | API 엔드포인트 | |------|------|-------------|-----------|----------------| | `channelName` | string | `'뷰성형외과 VIEW Plastic Surgery'` | YouTube Data API | `channels.list` → snippet.title | | `handle` | string | `'@ViewclinicKR'` | YouTube Data API | `channels.list` → snippet.customUrl | | `subscribers` | number | `103000` | YouTube Data API | `channels.list` → statistics.subscriberCount | | `totalVideos` | number | `1064` | YouTube Data API | `channels.list` → statistics.videoCount | | `totalViews` | number | `9952722` | YouTube Data API | `channels.list` → statistics.viewCount | | `weeklyViewGrowth.absolute` | number | `67097` | **주기적 수집 후 diff** | 7일 간격 viewCount 차이 | | `weeklyViewGrowth.percentage` | number | `4.09` | **계산** | absolute / (totalViews - absolute) * 100 | | `estimatedMonthlyRevenue` | object | `{ min: 499, max: 1000 }` | **Social Blade API** | 또는 자체 추정 로직 (CPM 기반) | | `avgVideoLength` | string | `'4.4분'` | YouTube Data API | `videos.list` → contentDetails.duration 평균 | | `uploadFrequency` | string | `'~주 1회'` | **계산** | 최근 30개 영상 업로드 날짜 간격 | | `channelCreatedDate` | string | `'2015-06-29'` | YouTube Data API | `channels.list` → snippet.publishedAt | | `subscriberRank` | string | `'#570K'` | **Social Blade** | 전세계 구독자 순위 | | `channelDescription` | string | (바이오 텍스트) | YouTube Data API | `channels.list` → snippet.description | | `linkedUrls` | array | 5개 링크 | YouTube Data API | `channels.list` → brandingSettings.channel.links (v3 미지원 시 크롤링) | | `playlists` | string[] | 9개 재생목록 | YouTube Data API | `playlists.list` → snippet.title | | `topVideos` | TopVideo[] | 8개 영상 | YouTube Data API | `search.list` (order=viewCount) + `videos.list` | | `diagnosis` | DiagnosisItem[] | 7개 항목 | **AI 생성** | 수집 데이터 → 패턴 분석 → 텍스트 생성 | #### TopVideo 상세 | 필드 | 수집 소스 | API | |------|-----------|-----| | `title` | YouTube Data API | `videos.list` → snippet.title | | `views` | YouTube Data API | `videos.list` → statistics.viewCount | | `uploadedAgo` | YouTube Data API | `videos.list` → snippet.publishedAt → 상대 시간 변환 | | `type` ('Short' / 'Long') | **계산** | duration ≤ 60초 && 세로형 → Short | | `duration` | YouTube Data API | `videos.list` → contentDetails.duration (Long만 표시) | ### 2.5 Instagram 분석 (InstagramAudit) | 필드 | 타입 | 수집 소스 | 수집 방법 | |------|------|-----------|-----------| | `accounts` | InstagramAccount[] | Instagram Graph API / Apify | 복수 계정 병렬 수집 | | `diagnosis` | DiagnosisItem[] | **AI 생성** | 계정 간 비교 분석 | #### InstagramAccount 상세 | 필드 | 현재 Mock (KR) | 현재 Mock (EN) | 수집 소스 | |------|---------------|---------------|-----------| | `handle` | `@viewplastic` | `@view_plastic_surgery` | 웹사이트 SNS 링크 → Graph API | | `language` | `'KR'` | `'EN'` | **AI 판단** (바이오/게시물 언어 감지) | | `label` | `'국내 (한국어)'` | `'국제 (영어)'` | language 기반 자동 라벨링 | | `posts` | `1409` | `2524` | Graph API / Apify | | `followers` | `14000` | `68800` | Graph API / Apify | | `following` | `4760` | `2834` | Graph API / Apify | | `category` | `'Health/beauty'` | `'Health/beauty'` | Graph API | | `profileLink` | `'litt.ly/viewplasticsurgery'` | `'litt.ly/viewplasticsurgeryenglish'` | Graph API / Apify | | `highlights` | 5개 하이라이트명 | 7개 하이라이트명 | **Apify 크롤링** (API 미지원) | | `reelsCount` | `0` | `50` | **Apify 크롤링** | | `contentFormat` | `'카드뉴스 100%'` | `'B/A + 환자 스토리 + Reels'` | **AI 분석** (게시물 샘플링) | | `profilePhoto` | `'모델 사진'` | `'VIEW 골드 로고'` | Graph API / Apify | | `bio` | (한국어 바이오) | (영어 바이오) | Graph API / Apify | ### 2.6 Facebook 분석 (FacebookAudit) | 필드 | 타입 | 수집 소스 | 수집 방법 | |------|------|-----------|-----------| | `pages` | FacebookPage[] | Facebook Graph API / Apify | 복수 페이지 수집 | | `diagnosis` | DiagnosisItem[] | **AI 생성** | 페이지 간 비교 분석 | | `brandInconsistencies` | BrandInconsistency[] | **AI 생성** | 전 채널 크로스 비교 | | `consolidationRecommendation` | string | **AI 생성** | 통합/폐쇄 권고 텍스트 | #### FacebookPage 상세 | 필드 | 현재 Mock (KR) | 현재 Mock (EN) | 수집 소스 | |------|---------------|---------------|-----------| | `url` | `'facebook.com/viewps1'` | `'facebook.com/viewclinic'` | 웹사이트/검색 | | `pageName` | `'뷰성형외과'` | `'View Plastic Surgery'` | Graph API | | `followers` | `253` | `88000` | Graph API | | `following` | `0` | `11` | Graph API | | `category` | `'성형외과 의사'` | `'건강/뷰티'` | Graph API | | `bio` | `'예쁨이 일상이 되는 순간!'` | `'Official Account by VIEW Partners'` | Graph API | | `logo` | `'일치 (공식 로고)'` | `'불일치 (비공식 변형)'` | **AI 비교** (로고 이미지 대조) | | `logoDescription` | (상세 설명) | (상세 설명) | **AI 생성** (이미지 분석) | | `link` | `'viewclinic.com'` | `'viewplasticsurgery.com'` | Graph API | | `linkedDomain` | `'viewclinic.com'` | `'viewplasticsurgery.com'` | Graph API → 도메인 추출 | | `reviews` | `0` | `3` | Graph API | | `recentPostAge` | `'1일 전'` | `'14분 전'` | Graph API → 상대시간 변환 | | `hasWhatsApp` | `false` | `true` | Graph API | | `postFrequency` | `'주 1~2회'` | `'일 1~2회'` | **계산** (최근 30일 게시물 수 / 30) | | `topContentType` | `'Instagram 카드뉴스 복사'` | `'B/A + Reels'` | **AI 분석** (게시물 샘플링) | | `engagement` | `'좋아요 0~3개'` | `'좋아요 50~300개'` | Graph API → 평균 계산 | #### BrandInconsistency 상세 | 필드 | 설명 | 수집 소스 | |------|------|-----------| | `field` | 비교 항목 (로고, 연결 도메인, 바이오) | 시스템 정의 | | `values[]` | 각 채널의 해당 필드 값 + `isCorrect` 판정 | **AI 비교** (전 채널 데이터 크로스 분석) | | `impact` | 불일치로 인한 비즈니스 영향 | **AI 생성** | | `recommendation` | 개선 권고사항 | **AI 생성** | ### 2.7 기타 채널 (OtherChannel[]) | 채널 | 현재 Mock 상태 | 수집 소스 | 수집 방법 | |------|--------------|-----------|-----------| | 카카오톡 | active | 카카오 채널 검색 API | 채널 URL 유효성 확인 | | 네이버 블로그 | unknown | Naver Search API | `blog.naver.com/{id}` 검색 | | 네이버 플레이스 | unknown | Naver Place API / 크롤링 | 병원명 검색 | | TikTok | not_found | TikTok API / Apify | 핸들 검색 | | 강남언니 | active | **강남언니 크롤링** | Apify 또는 직접 크롤링 | | 모두닥 | active | **크롤링** | 병원명 검색 | | Goodoc | active | **크롤링** | 병원명 검색 | | 닥터나우 | active | **크롤링** | 병원명 검색 | ### 2.8 웹사이트 분석 (WebsiteAudit) | 필드 | 현재 Mock 값 | 수집 소스 | 수집 방법 | |------|-------------|-----------|-----------| | `primaryDomain` | `'viewclinic.com'` | 사용자 입력 | URL에서 추출 | | `additionalDomains` | 3개 추가 도메인 | **DNS/리다이렉트 추적** | WHOIS + 크롤링 중 발견되는 도메인 | | `snsLinksOnSite` | `false` | **웹사이트 크롤링** | `<a>` 태그에서 SNS 도메인 검색 | | `trackingPixels[].name` | FB Pixel, Kakao Pixel, GTM | **HTML 파싱** | `<script>` 태그 패턴 매칭 | | `trackingPixels[].installed` | true/false | **HTML 파싱** | 스크립트 존재 여부 | | `trackingPixels[].details` | Pixel ID, GTM ID | **HTML 파싱** | 정규식으로 ID 추출 | | `mainCTA` | `'전화 + 카카오톡 상담'` | **AI 분석** | 메인 페이지 CTA 버튼/링크 분석 | ### 2.9 문제 진단 (DiagnosisItem[]) > 모든 진단 항목은 **AI가 생성**한다. | 필드 | 타입 | 설명 | |------|------|------| | `category` | string | 문제 영역 (브랜드 아이덴티티, 콘텐츠 전략 등) | | `detail` | string | 상세 설명 텍스트 | | `severity` | `'critical' \| 'warning' \| 'good' \| 'excellent'` | 심각도 등급 | | `evidenceIds` | string[] (optional) | 근거 스크린샷 ID 참조 | 현재 Mock 진단 영역: - YouTube: 7개 항목 (구독자 대비 조회수, Shorts 하락, 업로드 빈도, 톤앤매너 등) - Instagram: 6개 항목 (계정 분리, Reels 전무, 브랜드 비주얼, 크로스포스팅 등) - Facebook: 6개 항목 (로고 파편화, KR 방치, 도메인 불일치, 팔로워 격차 등) - 종합: 3개 항목 (브랜드 파편화, 콘텐츠 전략 부재, 플랫폼 간 유입 단절) ### 2.10 변환 전략 (TransformationProposal) > **전체가 AI 생성 데이터**. 수집된 raw 데이터의 As-Is를 분석하고 To-Be를 제안한다. #### brandIdentity (AsIsToBeItem[]) | area | asIs (수집 데이터 기반) | toBe (AI 제안) | |------|----------------------|----------------| | 로고 | 채널마다 다른 로고 4종 | VIEW 골드 로고 1종 통일 | | 컬러 팔레트 | 없음 (혼재) | Primary: Gold (#C4A462) + Dark (#1A1A1A) | | 프로필 사진 | KR=모델, EN=로고, FB=깃털 | 전 채널 VIEW 골드 로고 통일 | | 바이오 메시지 | 채널마다 다른 메시지 | "안전이 예술이 되는 곳 — 21년 무사고 VIEW" | | 해시태그 | 비체계적 | #뷰성형외과 #VIEW성형 #강남성형외과 #21년무사고 | #### contentStrategy (AsIsToBeItem[]) | area | asIs | toBe | |------|------|------| | 콘텐츠 캘린더 | 없음 | 월간 콘텐츠 캘린더 (4주 사이클) | | 업로드 빈도 | YouTube 주1회, Instagram 비정기 | YouTube 주3회 + Instagram 일1회 + Shorts/Reels 주5회 | | 콘텐츠 포맷 | KR Instagram = 카드뉴스만 | 카드뉴스 30% + Reels 40% + 카루셀 20% + Stories 10% | | 콘텐츠 앵글 | 시술 정보 중심 (병원 관점) | 환자 의사결정 보조 중심 (환자 관점) | | 톤앤매너 | 없음 | "차분한 전문가" — 과장 없이, 설명으로 설득 | #### platformStrategies (PlatformStrategy[]) | platform | currentMetric | targetMetric | 전략 개수 | |----------|--------------|-------------|-----------| | YouTube | 103K subscribers | 200K / 12개월 | 4개 | | Instagram KR | 14K followers | 50K / 12개월 | 4개 | | Facebook | KR 253 + EN 88K | 통합 관리 | 3개 | #### websiteImprovements (AsIsToBeItem[]) | area | asIs | toBe | |------|------|------| | SNS 링크 | 홈페이지에 0개 | Header/Footer에 YouTube + Instagram + KakaoTalk | | YouTube 임베드 | 없음 | 시술 페이지별 관련 YouTube 영상 임베드 | | 콘텐츠 허브 | 없음 | SEO 콘텐츠 허브 구축 | | 도메인 통합 | 4개 도메인 분산 | viewclinic.com 단일 도메인 + /en 국제 페이지 | #### newChannelProposals | channel | priority | rationale | |---------|----------|-----------| | TikTok | P1 | 20~30대 첫 수술 고민층 도달, YouTube Shorts 동시 배포 | | 네이버 블로그 | P0 | 한국 검색 1위 플랫폼 — SEO 핵심 | | 네이버 플레이스 | P0 | 지역 검색 노출 필수 | ### 2.11 로드맵 (RoadmapMonth[]) > **AI 생성**. 변환 전략을 월별 실행 계획으로 분해. | month | title | subtitle | tasks 수 | |-------|-------|----------|----------| | 1 | Foundation | 기반 구축 | 7개 | | 2 | Content Engine | 콘텐츠 엔진 가동 | 6개 | | 3 | Optimization | 최적화 & 광고 | 6개 | 각 task는 `{ task: string, completed: boolean }` 구조. ### 2.12 KPI 대시보드 (KPIMetric[]) > `current`는 **수집 데이터**, `target3Month`/`target12Month`는 **AI 생성**. | metric | current (수집) | target3Month (AI) | target12Month (AI) | |--------|---------------|-------------------|---------------------| | YouTube 구독자 | 103K | 115K | 200K | | YouTube 월 조회수 | ~270K | 500K | 1.5M | | YouTube Shorts 평균 조회수 | 500~1,000 | 5,000 | 20,000 | | Instagram KR 팔로워 | 14K | 20K | 50K | | Instagram KR Reels 평균 조회수 | 0 (없음) | 3,000 | 10,000 | | Instagram EN 팔로워 | 68.8K | 75K | 100K | | 네이버 블로그 방문자 | 0 (없음) | 5,000/월 | 30,000/월 | | 웹사이트 → SNS 유입 | 0% | 5% | 15% | | 콘텐츠 → 상담 전환 | 측정 불가 | UTM 추적 시작 | 월 50건 | ### 2.13 스크린샷 증거 (ScreenshotEvidence[]) | 필드 | 설명 | 수집 소스 | |------|------|-----------| | `id` | 고유 식별자 (진단의 evidenceIds에서 참조) | 시스템 생성 | | `url` | 이미지 경로 | **Puppeteer/Playwright** 스크린샷 | | `channel` | 어떤 채널의 스크린샷인지 | 시스템 정의 | | `capturedAt` | 캡처 시점 | 시스템 생성 | | `caption` | 스크린샷 설명 | **AI 생성** | | `sourceUrl` | 원본 페이지 URL | 크롤링 대상 URL | | `annotations` | 강조 표시 (highlight/arrow/text) | **AI 생성** (문제 지점 자동 표시) | 현재 6개 스크린샷: - `yt-channel` — YouTube 채널 메인 - `yt-about-links` — YouTube 정보 탭 - `ig-kr-profile` — Instagram KR 프로필 - `ig-en-profile` — Instagram EN 프로필 - `fb-en-page` — Facebook EN 페이지 - `website-homepage` — viewclinic.com 홈페이지 --- ## 3. Plan 데이터 (MarketingPlan) > 타입 정의: `src/types/plan.ts` > Mock 데이터: `src/data/mockPlan.ts` > 사용 페이지: `/plan/:id` (`src/pages/MarketingPlanPage.tsx`) > **전체가 AI 생성 데이터** — Report의 수집/분석 결과를 입력으로 사용 ### 3.1 기본 메타 | 필드 | 설명 | 데이터 소스 | |------|------|------------| | `id` | 플랜 ID | 시스템 생성 | | `reportId` | 연결된 리포트 ID | Report 참조 | | `clinicName` / `clinicNameEn` | 병원명 | Report에서 복사 | | `createdAt` | 생성일 | 시스템 생성 | | `targetUrl` | 대상 URL | Report에서 복사 | ### 3.2 브랜드 가이드 (BrandGuide) > Report의 brandInconsistencies 분석을 기반으로 **AI가 생성하는 가이드라인**. | 섹션 | 데이터 구조 | 항목 수 | 데이터 소스 | |------|-----------|--------|------------| | `colors` (ColorSwatch[]) | name, hex, usage | 5개 | **AI 제안** (로고 컬러 + 보완색) | | `fonts` (FontSpec[]) | family, weight, usage, sampleText | 3개 | **AI 제안** | | `logoRules` (LogoUsageRule[]) | rule, description, correct | 6개 | **AI 생성** (불일치 분석 기반) | | `toneOfVoice` | personality[], communicationStyle, do/don't 예시 | - | **AI 생성** | | `channelBranding` (ChannelBrandingRule[]) | channel, profilePhoto, bannerSpec, bioTemplate, currentStatus | 7개 채널 | **AI 생성** + 수집 데이터 (currentStatus) | | `brandInconsistencies` | Report에서 가져옴 | 2개 | Report 데이터 참조 | ### 3.3 채널 커뮤니케이션 전략 (ChannelStrategyCard[]) | 필드 | 설명 | 데이터 소스 | |------|------|------------| | `channelId` / `channelName` / `icon` | 채널 식별 | 시스템 정의 | | `currentStatus` | 현재 상태 요약 | **Report 수집 데이터** | | `targetGoal` | 목표 | **AI 생성** | | `contentTypes` | 콘텐츠 유형 목록 | **AI 생성** | | `postingFrequency` | 게시 빈도 | **AI 생성** | | `tone` | 톤앤매너 | **AI 생성** | | `formatGuidelines` | 포맷 가이드라인 | **AI 생성** | | `priority` | P0/P1/P2 | **AI 판단** | 현재 7개 채널: YouTube, Instagram KR, Instagram EN, Facebook, Naver Blog, TikTok, KakaoTalk ### 3.4 콘텐츠 마케팅 전략 (ContentStrategyData) | 섹션 | 데이터 구조 | 항목 수 | 데이터 소스 | |------|-----------|--------|------------| | `pillars` (ContentPillar[]) | title, description, relatedUSP, exampleTopics, color | 4개 | **AI 생성** (병원 USP 분석 기반) | | `typeMatrix` (ContentTypeRow[]) | format, channels, frequency, purpose | 6개 | **AI 생성** | | `workflow` (WorkflowStep[]) | step, name, description, owner, duration | 5단계 | **AI 생성** | | `repurposingSource` | 원본 콘텐츠 정의 | 1개 | **AI 생성** | | `repurposingOutputs` (RepurposingOutput[]) | format, channel, description | 6개 | **AI 생성** | 콘텐츠 필러 4개: 1. 수술 전문성 (Surgical Authority) 2. 안전 & 신뢰 (Trust & Safety) 3. 결과 예측 (Result Predictability) 4. 환자 여정 (Patient Guidance) ### 3.5 콘텐츠 캘린더 (CalendarData) | 필드 | 설명 | 데이터 소스 | |------|------|------------| | `weeks` (CalendarWeek[]) | 주차별 콘텐츠 스케줄 | **AI 생성** | | `weeks[].entries` (CalendarEntry[]) | 요일, 채널, 콘텐츠 유형, 제목 | **AI 생성** | | `monthlySummary` (ContentCountSummary[]) | 유형별 월간 합계 | **계산** (entries 집계) | 현재 4주 캘린더, 주당 7~8개 항목, 월간 합계: - 영상 16개 / 블로그 8개 / 소셜 12개 / 광고 4개 ### 3.6 에셋 수집 (AssetCollectionData) > 기존 콘텐츠 자산을 AI가 분류하고 재활용 방법을 제안. | 필드 | 설명 | 데이터 소스 | |------|------|------------| | `assets` (AssetCard[]) | 수집된/수집 예정 에셋 목록 | 일부 **크롤링 수집**, 일부 **AI 제안** | | `assets[].source` | homepage / naver_place / blog / social / youtube | 에셋 출처 | | `assets[].type` | photo / video / text | 에셋 유형 | | `assets[].status` | collected / pending / needs_creation | 수집 상태 | | `assets[].repurposingSuggestions` | 재활용 제안 목록 | **AI 생성** | | `youtubeRepurpose` (YouTubeRepurposeItem[]) | YouTube 영상 재활용 계획 | **AI 생성** (topVideos 기반) | 현재 11개 에셋 + 5개 YouTube 재활용 항목 --- ## 4. Studio 데이터 (Content Studio) > 타입 정의: `src/types/studio.ts` > 사용 페이지: `/studio/:id` (`src/pages/ContentStudioPage.tsx`) ### 4.1 채널/포맷 옵션 (하드코딩 상수) | 채널 | 포맷 | aspect ratio | |------|------|-------------| | YouTube | Shorts (9:16), Long-form (16:9) | | | Instagram | Reels (9:16), Carousel (1:1), Feed Image (1:1), Stories (9:16) | | | Naver Blog | SEO Post (16:9), FAQ Post (16:9) | | | TikTok | Short Video (9:16) | | | Facebook | Ad Creative (1:1), Retarget Content (16:9) | | ### 4.2 음악 트랙 (하드코딩 상수) 12개 트랙, 4개 장르: calm (3개), upbeat (3개), cinematic (3개), corporate (3개) ### 4.3 AI 이미지 생성 (geminiImageGen) | 데이터 | 소스 | 용도 | |--------|------|------| | `StudioState.channel` | 사용자 선택 | 프롬프트 힌트 (채널별 스타일) | | `StudioState.format` | 사용자 선택 | aspect ratio 결정 | | `StudioState.pillarId` | 사용자 선택 | 프롬프트 테마 (safety/expertise/results/care) | | 컬러 팔레트 | **하드코딩** | `#7B2D8E, #E8B931, #FAF8F5` (Report의 brandColors와 동일해야 함) | **의존성:** 현재 컬러 팔레트가 geminiImageGen.ts에 하드코딩되어 있으므로, 실제 구현 시 Report의 `brandColors`에서 동적으로 주입해야 함. --- ## 5. 수집 소스별 분류 ### 5.1 사용자 입력 (수동) | 데이터 | 설명 | |--------|------| | 대상 URL | 분석 시작점 (필수) | | 병원명 (선택) | URL에서 추출 불가 시 | ### 5.2 웹사이트 크롤링 (Firecrawl / Puppeteer) | 수집 대상 | 사용 위치 | 수집 방법 | |----------|-----------|-----------| | 병원명 (한/영) | ClinicSnapshot | `<title>`, 메타태그 | | 로고 이미지 | ClinicSnapshot.logoImages | `<img>` 태그, favicon | | 브랜드 컬러 | ClinicSnapshot.brandColors | CSS 파싱, 로고 색상 추출 | | 전화번호 | ClinicSnapshot.phone | `<a href="tel:">` | | 주소 | ClinicSnapshot.location | 구조화 데이터 | | 인증/수상 | ClinicSnapshot.certifications | 본문 섹션 파싱 | | SNS 링크 유무 | WebsiteAudit.snsLinksOnSite | `<a>` 태그 SNS 도메인 검색 | | 트래킹 픽셀 | WebsiteAudit.trackingPixels | `<script>` 패턴 매칭 | | 추가 도메인 | WebsiteAudit.additionalDomains | 리다이렉트 추적 | | 페이지 스크린샷 | screenshots[] | Puppeteer 전체 페이지 캡처 | | SNS 프로필 URL | Instagram/Facebook 핸들 발견 | `<a>` 태그에서 소셜 링크 추출 | ### 5.3 YouTube Data API v3 | 수집 대상 | API 엔드포인트 | 사용 위치 | |----------|----------------|-----------| | 채널 기본 정보 | `channels.list` (part=snippet,statistics,brandingSettings) | YouTubeAudit 전반 | | 재생목록 | `playlists.list` | YouTubeAudit.playlists | | 영상 검색 (조회순) | `search.list` (order=viewCount) | YouTubeAudit.topVideos | | 영상 상세 | `videos.list` (part=snippet,statistics,contentDetails) | topVideos 상세, avgVideoLength | | 최근 업로드 | `search.list` (order=date) | uploadFrequency 계산 | ### 5.4 Instagram / Facebook (Graph API + Apify) | 수집 대상 | 소스 | 사용 위치 | |----------|------|-----------| | 프로필 기본 정보 | Graph API | InstagramAccount, FacebookPage | | 팔로워/팔로잉 수 | Graph API | followers, following | | 게시물 수 | Graph API | posts | | 하이라이트 목록 | **Apify (API 미지원)** | highlights | | Reels 개수 | **Apify (API 미지원)** | reelsCount | | 프로필 사진 분석 | Graph API → 이미지 → AI 분석 | profilePhoto 설명 | | 바이오 텍스트 | Graph API | bio | | 게시 빈도 | Graph API → 계산 | postFrequency | | 참여율 | Graph API → 평균 | engagement | | 페이지 스크린샷 | **Puppeteer** | screenshots[] | ### 5.5 강남언니 크롤링 (Apify) | 수집 대상 | 사용 위치 | |----------|-----------| | 병원 전체 평점 | ClinicSnapshot.overallRating | | 총 리뷰 수 | ClinicSnapshot.totalReviews | | 가격 범위 | ClinicSnapshot.priceRange | | 의료진 수 | ClinicSnapshot.staffCount | | 대표원장 평점/리뷰수 | ClinicSnapshot.leadDoctor | | 인증 뱃지 | ClinicSnapshot.certifications | ### 5.6 외부 API / 기타 | 소스 | 수집 대상 | 사용 위치 | |------|----------|-----------| | Social Blade | 구독자 순위, 월 수익 추정 | subscriberRank, estimatedMonthlyRevenue | | Naver Search API | 블로그/카페 검색 | otherChannels (네이버 블로그 존재 여부) | | Naver Place API | 플레이스 등록 정보 | otherChannels (네이버 플레이스) | | Brandfetch API | 도메인 → 로고/컬러 자동 추출 | brandColors (보조 수단) | | Google Vision API | 이미지 → 로고 감지, 색상 추출 | brandColors (고도화) | --- ## 6. AI 생성 데이터 > 수집된 raw 데이터를 입력으로, LLM(Claude)이 분석/생성해야 하는 모든 데이터. ### 6.1 Report에서 AI가 생성하는 항목 | 카테고리 | 생성 항목 | 입력 데이터 | |----------|----------|------------| | **채점** | overallScore, channelScores[].score/status/headline | 전 채널 수집 데이터 | | **진단** | youtubeAudit.diagnosis[], instagramAudit.diagnosis[], facebookAudit.diagnosis[], problemDiagnosis[] | 각 채널 수집 데이터 | | **비교 분석** | brandInconsistencies[] | 전 채널 로고/바이오/도메인 비교 | | **변환 전략** | transformation 전체 (brandIdentity, contentStrategy, platformStrategies, websiteImprovements, newChannelProposals) | 진단 결과 + 수집 데이터 | | **로드맵** | roadmap[] (월별 tasks) | 변환 전략 | | **KPI 목표** | kpiDashboard[].target3Month, target12Month | 현재 수치 + 벤치마크 | | **스크린샷 캡션** | screenshots[].caption, annotations | 스크린샷 이미지 + 진단 결과 | | **통합 권고** | consolidationRecommendation | Facebook 페이지 분석 | ### 6.2 Plan에서 AI가 생성하는 항목 | 카테고리 | 생성 항목 | 입력 데이터 | |----------|----------|------------| | **브랜드 가이드** | colors, fonts, logoRules, toneOfVoice, channelBranding | Report의 brandColors + brandInconsistencies | | **채널 전략** | channelStrategies[] (목표, 빈도, 톤, 가이드라인) | Report의 channelScores + diagnosis | | **콘텐츠 전략** | pillars, typeMatrix, workflow, repurposing | 병원 USP + 채널 전략 | | **콘텐츠 캘린더** | weeks[].entries (4주 상세 스케줄) | 콘텐츠 전략 + 빈도 | | **에셋 분류** | assets[].repurposingSuggestions, youtubeRepurpose | 크롤링 수집 에셋 + topVideos | ### 6.3 Studio에서 AI가 생성하는 항목 | 카테고리 | 생성 항목 | 입력 데이터 | |----------|----------|------------| | **이미지** | AI 생성 마케팅 이미지 | 채널, 포맷, 콘텐츠 필러, 브랜드 컬러 | --- ## 7. 데이터 의존 관계 ``` 사용자 입력 (URL) │ ▼ [웹사이트 크롤링] ──→ ClinicSnapshot (기본 정보, 로고, 컬러) │ WebsiteAudit (도메인, SNS 링크, 트래킹) │ SNS 프로필 URL 발견 │ ├──→ [YouTube Data API] ──→ YouTubeAudit ├──→ [Instagram API / Apify] ──→ InstagramAudit ├──→ [Facebook Graph API / Apify] ──→ FacebookAudit ├──→ [강남언니 크롤링] ──→ ClinicSnapshot (평점, 리뷰, 가격) ├──→ [네이버 API] ──→ OtherChannels └──→ [Puppeteer 스크린샷] ──→ Screenshots │ ▼ [AI 분석 — Report] │ ├──→ ChannelScores (채점) ├──→ Diagnosis (진단) ├──→ BrandInconsistencies (비교) ├──→ TransformationProposal (전략) ├──→ Roadmap (로드맵) └──→ KPIDashboard (목표) │ ▼ [AI 분석 — Plan] │ ├──→ BrandGuide (브랜드 가이드) ├──→ ChannelStrategies (채널 전략) ├──→ ContentStrategy (콘텐츠 전략) ├──→ Calendar (캘린더) └──→ AssetCollection (에셋) │ ▼ [Content Studio] │ └──→ AI 이미지 생성 (Gemini) ``` ### 핵심 의존성 순서 1. **웹사이트 크롤링이 먼저** — SNS 프로필 URL을 여기서 발견 2. **SNS API 수집은 병렬 가능** — YouTube, Instagram, Facebook 동시 수집 3. **AI 분석은 모든 수집 완료 후** — 전 채널 데이터가 있어야 비교/진단 가능 4. **Plan은 Report 이후** — Report의 분석 결과가 Plan의 입력 5. **Studio는 Plan 이후** — Plan의 브랜드 가이드/콘텐츠 필러가 Studio의 입력 --- ## 8. Firecrawl 수집 검증 결과 > **검증일:** 2026-03-30 > **방법:** WebFetch(단순 HTTP GET + HTML 파싱)로 실제 타겟 사이트 5곳을 테스트하여 Firecrawl 도입 시 기대 가능한 수집 범위를 검증. > Firecrawl은 WebFetch보다 우수한 JS 렌더링 + LLM 기반 구조화 추출을 제공하므로, WebFetch에서 성공한 항목은 Firecrawl에서도 수집 가능하다고 판단. ### 8.1 사이트별 테스트 결과 #### viewclinic.com — 수집 가능 (Firecrawl 유효) | 필요 데이터 | 추출 결과 | 비고 | |------------|-----------|------| | 병원명 (한/영) | `뷰성형외과` / `VIEW Clinic` | 메타태그 + JSON-LD | | 전화번호 | `02-539-1177` | `tel:` 링크 | | 주소 | `서울 강남구 봉은사로 107` | | | 브랜드 컬러 | `#7d2a86` (보라), 그라디언트 확인 | CSS에서 추출 | | SNS 링크 | **카카오톡만 발견** (`pf.kakao.com/_xbtVxjl`) | YouTube/Instagram/Facebook 링크 미노출 — mock 데이터의 `snsLinksOnSite: false` 확인됨 | | 트래킹 픽셀 | FB Pixel `299151214739571`, GTM `GTM-52RT6DMK`, Kakao Pixel `5684247168888976904` | 전부 추출 성공 | | 인증/수상 | 가슴보형물 1위, 복지부장관 표창, 안면윤곽 대상, 렛미인 | | | 로고 이미지 | 일부 이미지 경로만 (`/image/` 하위) | 명시적 `<img>` 로고가 아닌 배경 이미지 가능성 | | JSON-LD | Organization, 언어 ko-KR | | | Kakao SDK Key | `4c6038836d6b8bf205b5c315606f053b` | | **결론:** JS 렌더링 불필요한 전통적 웹사이트. Firecrawl로 충분히 수집 가능. #### YouTube (@ViewclinicKR) — 수집 불가 | 시도 | 결과 | |------|------| | WebFetch | **실패** — JS 번들/설정 코드만 반환, 채널 메타데이터 없음 | | 추출 가능 데이터 | 클라이언트 리전(KR), 인터페이스 언어(ko)만 | | 추출 불가 데이터 | 채널명, 구독자 수, 영상 수, 설명, 재생목록, 프로필 이미지 전부 불가 | **결론:** YouTube는 InnerTube API 기반 SPA. Firecrawl의 JS 렌더링으로도 안정적 수집 어려움. **YouTube Data API v3 필수**. #### Instagram (@viewplastic) — 부분 수집만 가능 | 시도 | 결과 | |------|------| | WebFetch | **부분 성공** — 핸들, 바이오 텍스트, 카테고리만 추출 | | 추출 가능 데이터 | `@viewplastic`, 바이오: "뷰 성형외과 \| 가슴성형·안면윤곽·눈성형·코성형·리프팅", 카테고리: Medical | | 추출 불가 데이터 | 팔로워 수, 팔로잉 수, 게시물 수, 프로필 사진 URL, 외부 링크 | **결론:** 로그인 없이 기본 정보만 노출. 정량 데이터(팔로워, Reels 개수, 하이라이트)는 **Apify 또는 Instagram Graph API 필수**. #### Facebook (viewclinic) — 수집 거의 불가 | 시도 | 결과 | |------|------| | WebFetch | **거의 실패** — 페이지명 `"View Plastic Surgery \| Seoul"`만 추출 | | 추출 불가 데이터 | 팔로워, 바이오, 카테고리, 연락처, 웹사이트 링크, 프로필 사진, 리뷰 전부 불가 | **결론:** React SPA + 로그인 유도 구조. **Facebook Graph API 또는 Apify 필수**. #### 강남언니 (hospitals/189) — 수집 가능 (Firecrawl 유효) | 필요 데이터 | 추출 결과 | mock 데이터 대비 | |------------|-----------|----------------| | 병원 평점 | `9.5/10` | mock: 4.8/5.0 → 10점 만점 스케일 차이 | | 총 리뷰 수 | `18,959` | mock: 18,840 (실시간 증가) | | 의료진 수 | `31명` (전원 이름/평점/리뷰수 포함) | mock: 28명 (최신 데이터 반영 필요) | | 대표원장 | 최순우, 9.4점, 1,812 리뷰 | mock: 4.7점 → 5점 만점 환산값이었음 | | 가격 범위 | 시술별 상세 가격 (₩220,000~₩3,289,000+) | mock보다 상세 | | 인증 뱃지 | 10개 (수술실 CCTV, 마취과 상주, 입원실 등) | | | 시술 카테고리 | 10개 | | | 진료시간 | 요일별 상세 | mock에 없던 데이터 | | 상담 현황 | 최근 상담 857명 | mock에 없던 데이터 | **결론:** SSR 사이트이므로 Firecrawl/WebFetch 모두 잘 동작. **가장 풍부한 단일 데이터 소스**. ### 8.2 변환 전략(Transformation) 섹션 데이터 소스 분석 변환 전략은 모든 항목이 **As-Is(현재 상태) → To-Be(개선안)** 구조이며, As-Is는 수집 데이터, To-Be는 AI 생성이다. #### 브랜드 아이덴티티 탭 | area | As-Is 데이터 | 수집 소스 | Firecrawl? | |------|-------------|-----------|------------| | 로고 | "채널마다 다른 로고 4종" | 각 채널 프로필 사진 비교 | X → **Apify** | | 컬러 팔레트 | "없음 (혼재)" | 웹사이트 CSS + 각 채널 비주얼 | 부분 (웹사이트만) | | 프로필 사진 | "KR=모델, EN=로고, FB=깃털" | Instagram/Facebook 프로필 이미지 | X → **Apify** | | 바이오 메시지 | "채널마다 다른 메시지" | 각 채널 바이오 텍스트 | X → **Apify** | | 해시태그 | "비체계적" | 각 채널 게시물 분석 | X → **Apify** | #### 콘텐츠 전략 탭 | area | As-Is 데이터 | 수집 소스 | Firecrawl? | |------|-------------|-----------|------------| | 콘텐츠 캘린더 | "없음" | 업로드 패턴 분석 | X → **YouTube API + Apify** | | 업로드 빈도 | "YouTube 주1회, Instagram 비정기" | 업로드 날짜 분석 | X → **YouTube API + Apify** | | 콘텐츠 포맷 | "KR Instagram = 카드뉴스만" | 게시물 유형 분류 | X → **Apify** | | 콘텐츠 앵글 | "시술 정보 중심 (병원 관점)" | 게시물 내용 분석 | X → **Apify + AI 분석** | | 톤앤매너 | "없음" | 게시물 텍스트 분석 | X → **Apify + AI 분석** | #### 플랫폼 전략 탭 | platform | currentMetric (As-Is) | 수집 소스 | Firecrawl? | |----------|----------------------|-----------|------------| | YouTube | "103K subscribers" | 구독자 수 | X → **YouTube Data API** | | Instagram KR | "14K followers" | 팔로워 수 | X → **Apify** | | Facebook | "KR 253 + EN 88K" | 페이지별 팔로워 | X → **Apify** | #### 웹사이트 개선 탭 | area | As-Is 데이터 | 수집 소스 | Firecrawl? | |------|-------------|-----------|------------| | SNS 링크 | "홈페이지에 0개" | 웹사이트 `<a>` 태그 분석 | **O** | | YouTube 임베드 | "없음" | 웹사이트 `<iframe>` 검색 | **O** | | 콘텐츠 허브 | "없음" | 사이트맵/페이지 구조 분석 | **O** | | 도메인 통합 | "4개 도메인 분산" | 리다이렉트/링크 추적 | **O** | #### 신규 채널 제안 탭 | channel | As-Is 확인 사항 | 수집 소스 | Firecrawl? | |---------|---------------|-----------|------------| | TikTok | "계정 없음" | TikTok 핸들 검색 | X → **Apify** | | 네이버 블로그 | "미확인" | 네이버 검색 | X → **Naver Search API** | | 네이버 플레이스 | "미확인" | 네이버 플레이스 검색 | X → **Naver Place API** | #### 변환 전략 섹션 소스별 커버리지 ``` Firecrawl ██░░░░░░░░ ~15% (웹사이트 개선 탭만) Apify ██████░░░░ ~35% (Instagram/Facebook/TikTok 현황) YouTube API ███░░░░░░░ ~15% (YouTube 현황) Naver API █░░░░░░░░░ ~5% (네이버 존재 여부) Claude AI ███████░░░ ~30% (To-Be 전체 + 진단 텍스트) ``` ### 8.3 전체 플랫폼 기준 Firecrawl 커버리지 ``` ┌─────────────────────────────────────────────────┐ │ Firecrawl로 수집 가능 (~35%) │ │ ✓ viewclinic.com (웹사이트 전체) │ │ ✓ 강남언니 (평점, 리뷰, 가격, 의료진) │ │ ✓ 모두닥, Goodoc 등 SSR 사이트 │ │ ✓ 네이버 블로그 콘텐츠 (존재 시) │ └─────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────┐ │ 별도 API/Apify 필수 (~45%) │ │ ✗ YouTube → YouTube Data API v3 │ │ ✗ Instagram → Graph API 또는 Apify │ │ ✗ Facebook → Graph API 또는 Apify │ │ ✗ TikTok → TikTok API 또는 Apify │ └─────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────┐ │ AI 분석/생성 (~20%) │ │ ✗ 채점, 진단, 전략, 로드맵, KPI │ │ → Claude API │ └─────────────────────────────────────────────────┘ ``` ### 8.4 실제 구현 시 필요한 도구 조합 | 우선순위 | 도구 | 역할 | 월 비용 | |----------|------|------|---------| | **P0** | **Firecrawl** | 웹사이트 크롤링 (로고, 컬러, 트래킹, SNS 링크, 스크린샷) | ~₩26,000 | | **P0** | **YouTube Data API v3** | YouTube 채널/영상 전체 데이터 | 무료 | | **P0** | **Apify** | Instagram + Facebook + TikTok + 강남언니 프로필 스크래핑 | ~₩65,000 | | **P0** | **Claude API** | 전체 분석, 진단, 전략, 로드맵, KPI 생성 | ~₩50,000 | | **P1** | **Naver Search API** | 네이버 블로그/카페 존재 여부 | 무료 | | **P1** | Instagram/Facebook Graph API | 공식 게시/인사이트 (Distribution 단계) | 무료 | | **P2** | Social Blade | YouTube 순위, 수익 추정 | 유료 | | **P2** | Naver Place API | 플레이스 상세 정보 | 유료 | ### 8.5 mock 데이터 vs 실제 수집 데이터 차이 발견 검증 과정에서 mock 데이터와 실제 데이터 간 차이가 발견됨: | 항목 | mock 값 | 실제 값 | 원인 | |------|---------|---------|------| | 강남언니 평점 | 4.8 (5점 만점) | 9.5 (10점 만점) | **스케일 다름** — mock 작성 시 5점 만점으로 환산한 것 | | 총 리뷰 수 | 18,840 | 18,959 | 실시간 증가 (정상) | | 의료진 수 | 28명 | 31명 | mock 작성 이후 증원 | | 대표원장 리뷰 | 1,809 | 1,812 | 실시간 증가 (정상) | | 브랜드 컬러 primary | `#7B2D8E` | `#7d2a86` | 근사값이나 정확히 다름 — 자동 추출 시 보정 필요 | --- *Last updated: 2026-03-30*