diff --git a/analysisResult.json b/analysisResult.json deleted file mode 100644 index dde7532..0000000 --- a/analysisResult.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "marketing_analysis": { - "brand_identity": { - "location_feature_analysis": "전북 군산시 절골길 일대는 도시의 편의성과 근교의 한적함을 동시에 누릴 수 있어 ‘조용한 재충전’ 수요에 적합합니다. 군산의 레트로 감성과 주변 관광 동선 결합이 쉬워 1~2박 체류형 여행지로 매력적입니다.", - "concept_scalability": "‘머뭄’이라는 네이밍을 ‘잠시 멈춰 머무는 시간’으로 확장해, 느린 체크인·명상/독서 큐레이션·로컬 티/다과 등 체류 경험형 서비스로 고도화가 가능합니다. 로컬 콘텐츠(군산 빵/커피, 근대문화 투어)와 결합해 패키지화하면 재방문 명분을 만들 수 있습니다." - }, - "market_positioning": { - "category_definition": "군산 감성 ‘슬로우 스테이’ 프라이빗 숙소", - "core_value": "아무것도 하지 않아도 회복되는 ‘멈춤의 시간’" - }, - "target_persona": [ - { - "persona": "번아웃 회복형 직장인 커플: 주말에 조용히 쉬며 리셋을 원하는 2인 여행자", - "age": { - "min_age": 27, - "max_age": 39 - }, - "favor_target": [ - "조용한 동네 분위기", - "미니멀/내추럴 인테리어", - "편안한 침구와 숙면 환경", - "셀프 체크인 선호", - "카페·맛집 연계 동선" - ], - "decision_trigger": "‘조용히 쉬는 데 최적화’된 프라이빗함과 숙면 컨디션(침구/동선/소음 차단) 확신" - }, - { - "persona": "감성 기록형 친구 여행: 사진과 무드를 위해 공간을 선택하는 2~3인 여성 그룹", - "age": { - "min_age": 23, - "max_age": 34 - }, - "favor_target": [ - "자연광 좋은 공간", - "감성 소품/컬러 톤", - "포토존(거울/창가/테이블)", - "와인·디저트 페어링", - "야간 무드 조명" - ], - "decision_trigger": "사진이 ‘그대로 작품’이 되는 포토 스팟과 야간 무드 연출 요소" - }, - { - "persona": "로컬 탐험형 소도시 여행자: 군산의 레트로/로컬 콘텐츠를 깊게 즐기는 커플·솔로", - "age": { - "min_age": 28, - "max_age": 45 - }, - "favor_target": [ - "근대문화/레트로 감성", - "로컬 맛집·빵집 투어", - "동선 효율(차로 이동 용이)", - "체크아웃 후 관광 연계", - "조용한 밤" - ], - "decision_trigger": "‘군산 로컬 동선’과 결합하기 좋은 위치 + 숙소 자체의 휴식 완성도" - } - ], - "selling_points": [ - { - "category": "LOCATION", - "description": "군산 감성 동선", - "score": 88 - }, - { - "category": "HEALING", - "description": "멈춤이 되는 쉼", - "score": 92 - }, - { - "category": "PRIVACY", - "description": "방해 없는 머뭄", - "score": 86 - }, - { - "category": "NIGHT MOOD", - "description": "밤이 예쁜 조명", - "score": 84 - }, - { - "category": "PHOTO SPOT", - "description": "자연광 포토존", - "score": 83 - }, - { - "category": "SHORT GETAWAY", - "description": "주말 리셋 스테이", - "score": 89 - }, - { - "category": "HOSPITALITY", - "description": "세심한 웰컴감", - "score": 80 - } - ], - "target_keywords": [ - "군산숙소", - "군산감성숙소", - "전북숙소추천", - "군산여행", - "커플스테이", - "주말여행", - "감성스테이", - "조용한숙소", - "힐링스테이", - "스테이머뭄" - ] - } - -} \ No newline at end of file diff --git a/api/social_api_spec.json b/api/social_api_spec.json deleted file mode 100644 index 9632ccf..0000000 --- a/api/social_api_spec.json +++ /dev/null @@ -1,585 +0,0 @@ -{ - "info": { - "title": "Social Media Integration API", - "version": "1.0.0", - "description": "소셜 미디어 연동 및 영상 업로드 API 명세서", - "baseUrl": "http://localhost:8000" - }, - "authentication": { - "type": "Bearer Token", - "header": "Authorization", - "format": "Bearer {access_token}", - "description": "카카오 로그인 후 발급받은 JWT access_token 사용" - }, - "endpoints": { - "oauth": { - "connect": { - "name": "소셜 계정 연동 시작", - "method": "GET", - "url": "/social/oauth/{platform}/connect", - "description": "OAuth 인증 URL을 생성합니다. 반환된 auth_url로 사용자를 리다이렉트하세요.", - "authentication": true, - "pathParameters": { - "platform": { - "type": "string", - "enum": ["youtube"], - "description": "연동할 플랫폼 (현재 youtube만 지원)" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=xxx&redirect_uri=xxx&response_type=code&scope=xxx&state=xxx", - "state": "abc123xyz789", - "platform": "youtube" - } - }, - "error": { - "401": { - "detail": "인증이 필요합니다." - }, - "422": { - "detail": "지원하지 않는 플랫폼입니다." - } - } - }, - "frontendAction": "auth_url로 window.location.href 또는 새 창으로 리다이렉트" - }, - "callback": { - "name": "OAuth 콜백 (백엔드 자동 처리)", - "method": "GET", - "url": "/social/oauth/{platform}/callback", - "description": "Google에서 자동으로 호출됩니다. 프론트엔드에서 직접 호출하지 마세요.", - "authentication": false, - "note": "연동 성공 시 프론트엔드의 /social/connect/success 페이지로 리다이렉트됩니다.", - "redirectOnSuccess": { - "url": "{PROJECT_DOMAIN}/social/connect/success", - "queryParams": { - "platform": "youtube", - "account_id": 1 - } - }, - "redirectOnError": { - "url": "{PROJECT_DOMAIN}/social/connect/error", - "queryParams": { - "platform": "youtube", - "error": "에러 메시지" - } - } - }, - "getAccounts": { - "name": "연동된 계정 목록 조회", - "method": "GET", - "url": "/social/oauth/accounts", - "description": "현재 사용자가 연동한 모든 소셜 계정 목록을 반환합니다.", - "authentication": true, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "accounts": [ - { - "id": 1, - "platform": "youtube", - "platform_user_id": "UC1234567890abcdef", - "platform_username": "@mychannel", - "display_name": "My YouTube Channel", - "profile_image_url": "https://yt3.ggpht.com/...", - "is_active": true, - "connected_at": "2024-01-15T12:00:00", - "platform_data": { - "channel_id": "UC1234567890abcdef", - "channel_title": "My YouTube Channel", - "subscriber_count": "1000", - "video_count": "50" - } - } - ], - "total": 1 - } - } - } - }, - "getAccountByPlatform": { - "name": "특정 플랫폼 연동 계정 조회", - "method": "GET", - "url": "/social/oauth/accounts/{platform}", - "description": "특정 플랫폼에 연동된 계정 정보를 반환합니다.", - "authentication": true, - "pathParameters": { - "platform": { - "type": "string", - "enum": ["youtube"], - "description": "조회할 플랫폼" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "id": 1, - "platform": "youtube", - "platform_user_id": "UC1234567890abcdef", - "platform_username": "@mychannel", - "display_name": "My YouTube Channel", - "profile_image_url": "https://yt3.ggpht.com/...", - "is_active": true, - "connected_at": "2024-01-15T12:00:00", - "platform_data": { - "channel_id": "UC1234567890abcdef", - "channel_title": "My YouTube Channel", - "subscriber_count": "1000", - "video_count": "50" - } - } - }, - "error": { - "404": { - "detail": "youtube 플랫폼에 연동된 계정이 없습니다." - } - } - } - }, - "disconnect": { - "name": "소셜 계정 연동 해제", - "method": "DELETE", - "url": "/social/oauth/{platform}/disconnect", - "description": "소셜 미디어 계정 연동을 해제합니다.", - "authentication": true, - "pathParameters": { - "platform": { - "type": "string", - "enum": ["youtube"], - "description": "연동 해제할 플랫폼" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "success": true, - "message": "youtube 계정 연동이 해제되었습니다." - } - }, - "error": { - "404": { - "detail": "youtube 플랫폼에 연동된 계정이 없습니다." - } - } - } - } - }, - "upload": { - "create": { - "name": "소셜 플랫폼에 영상 업로드 요청", - "method": "POST", - "url": "/social/upload", - "description": "영상을 소셜 미디어 플랫폼에 업로드합니다. 백그라운드에서 처리됩니다.", - "authentication": true, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", - "Content-Type": "application/json" - }, - "body": { - "video_id": { - "type": "integer", - "required": true, - "description": "업로드할 영상 ID (Video 테이블의 id)", - "example": 123 - }, - "platform": { - "type": "string", - "required": true, - "enum": ["youtube"], - "description": "업로드할 플랫폼", - "example": "youtube" - }, - "title": { - "type": "string", - "required": true, - "maxLength": 100, - "description": "영상 제목", - "example": "나의 첫 영상" - }, - "description": { - "type": "string", - "required": false, - "maxLength": 5000, - "description": "영상 설명", - "example": "이 영상은 테스트 영상입니다." - }, - "tags": { - "type": "array", - "required": false, - "items": "string", - "description": "태그 목록", - "example": ["여행", "vlog", "일상"] - }, - "privacy_status": { - "type": "string", - "required": false, - "enum": ["public", "unlisted", "private"], - "default": "private", - "description": "공개 상태", - "example": "private" - }, - "platform_options": { - "type": "object", - "required": false, - "description": "플랫폼별 추가 옵션", - "example": { - "category_id": "22" - } - } - }, - "example": { - "video_id": 123, - "platform": "youtube", - "title": "나의 첫 영상", - "description": "이 영상은 테스트 영상입니다.", - "tags": ["여행", "vlog"], - "privacy_status": "private", - "platform_options": { - "category_id": "22" - } - } - }, - "response": { - "success": { - "status": 200, - "body": { - "success": true, - "upload_id": 456, - "platform": "youtube", - "status": "pending", - "message": "업로드 요청이 접수되었습니다." - } - }, - "error": { - "404_video": { - "detail": "영상을 찾을 수 없습니다." - }, - "404_account": { - "detail": "youtube 플랫폼에 연동된 계정이 없습니다." - }, - "400": { - "detail": "영상이 아직 준비되지 않았습니다." - } - } - }, - "youtubeCategoryIds": { - "1": "Film & Animation", - "2": "Autos & Vehicles", - "10": "Music", - "15": "Pets & Animals", - "17": "Sports", - "19": "Travel & Events", - "20": "Gaming", - "22": "People & Blogs (기본값)", - "23": "Comedy", - "24": "Entertainment", - "25": "News & Politics", - "26": "Howto & Style", - "27": "Education", - "28": "Science & Technology", - "29": "Nonprofits & Activism" - } - }, - "getStatus": { - "name": "업로드 상태 조회", - "method": "GET", - "url": "/social/upload/{upload_id}/status", - "description": "특정 업로드 작업의 상태를 조회합니다. 폴링으로 상태를 확인하세요.", - "authentication": true, - "pathParameters": { - "upload_id": { - "type": "integer", - "description": "업로드 ID" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "upload_id": 456, - "video_id": 123, - "platform": "youtube", - "status": "completed", - "upload_progress": 100, - "title": "나의 첫 영상", - "platform_video_id": "dQw4w9WgXcQ", - "platform_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "error_message": null, - "retry_count": 0, - "created_at": "2024-01-15T12:00:00", - "uploaded_at": "2024-01-15T12:05:00" - } - }, - "error": { - "404": { - "detail": "업로드 정보를 찾을 수 없습니다." - } - } - }, - "statusValues": { - "pending": "업로드 대기 중", - "uploading": "업로드 진행 중 (upload_progress 확인)", - "processing": "플랫폼에서 처리 중", - "completed": "업로드 완료 (platform_url 사용 가능)", - "failed": "업로드 실패 (error_message 확인)", - "cancelled": "업로드 취소됨" - }, - "pollingRecommendation": { - "interval": "3초", - "maxAttempts": 100, - "stopConditions": ["completed", "failed", "cancelled"] - } - }, - "getHistory": { - "name": "업로드 이력 조회", - "method": "GET", - "url": "/social/upload/history", - "description": "사용자의 소셜 미디어 업로드 이력을 조회합니다.", - "authentication": true, - "queryParameters": { - "platform": { - "type": "string", - "required": false, - "enum": ["youtube"], - "description": "플랫폼 필터" - }, - "status": { - "type": "string", - "required": false, - "enum": ["pending", "uploading", "processing", "completed", "failed", "cancelled"], - "description": "상태 필터" - }, - "page": { - "type": "integer", - "required": false, - "default": 1, - "description": "페이지 번호" - }, - "size": { - "type": "integer", - "required": false, - "default": 20, - "min": 1, - "max": 100, - "description": "페이지 크기" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - }, - "exampleUrl": "/social/upload/history?platform=youtube&status=completed&page=1&size=20" - }, - "response": { - "success": { - "status": 200, - "body": { - "items": [ - { - "upload_id": 456, - "video_id": 123, - "platform": "youtube", - "status": "completed", - "title": "나의 첫 영상", - "platform_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "created_at": "2024-01-15T12:00:00", - "uploaded_at": "2024-01-15T12:05:00" - } - ], - "total": 1, - "page": 1, - "size": 20 - } - } - } - }, - "retry": { - "name": "업로드 재시도", - "method": "POST", - "url": "/social/upload/{upload_id}/retry", - "description": "실패한 업로드를 재시도합니다.", - "authentication": true, - "pathParameters": { - "upload_id": { - "type": "integer", - "description": "업로드 ID" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "success": true, - "upload_id": 456, - "platform": "youtube", - "status": "pending", - "message": "업로드 재시도가 요청되었습니다." - } - }, - "error": { - "400": { - "detail": "실패하거나 취소된 업로드만 재시도할 수 있습니다." - }, - "404": { - "detail": "업로드 정보를 찾을 수 없습니다." - } - } - } - }, - "cancel": { - "name": "업로드 취소", - "method": "DELETE", - "url": "/social/upload/{upload_id}", - "description": "대기 중인 업로드를 취소합니다.", - "authentication": true, - "pathParameters": { - "upload_id": { - "type": "integer", - "description": "업로드 ID" - } - }, - "request": { - "headers": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } - }, - "response": { - "success": { - "status": 200, - "body": { - "success": true, - "message": "업로드가 취소되었습니다." - } - }, - "error": { - "400": { - "detail": "대기 중인 업로드만 취소할 수 있습니다." - }, - "404": { - "detail": "업로드 정보를 찾을 수 없습니다." - } - } - } - } - } - }, - "frontendPages": { - "required": [ - { - "path": "/social/connect/success", - "description": "OAuth 연동 성공 후 리다이렉트되는 페이지", - "queryParams": ["platform", "account_id"], - "action": "연동 성공 메시지 표시 후 설정 페이지로 이동" - }, - { - "path": "/social/connect/error", - "description": "OAuth 연동 실패 시 리다이렉트되는 페이지", - "queryParams": ["platform", "error"], - "action": "에러 메시지 표시 및 재시도 옵션 제공" - } - ], - "recommended": [ - { - "path": "/settings/social", - "description": "소셜 계정 관리 페이지", - "features": ["연동된 계정 목록", "연동/해제 버튼", "업로드 이력"] - } - ] - }, - "flowExamples": { - "connectYouTube": { - "description": "YouTube 계정 연동 플로우", - "steps": [ - { - "step": 1, - "action": "GET /social/oauth/youtube/connect 호출", - "result": "auth_url 반환" - }, - { - "step": 2, - "action": "window.location.href = auth_url", - "result": "Google 로그인 페이지로 이동" - }, - { - "step": 3, - "action": "사용자가 권한 승인", - "result": "백엔드 콜백 URL로 자동 리다이렉트" - }, - { - "step": 4, - "action": "백엔드가 토큰 교환 후 프론트엔드로 리다이렉트", - "result": "/social/connect/success?platform=youtube&account_id=1" - }, - { - "step": 5, - "action": "연동 성공 처리 후 GET /social/oauth/accounts 호출", - "result": "연동된 계정 정보 표시" - } - ] - }, - "uploadVideo": { - "description": "YouTube 영상 업로드 플로우", - "steps": [ - { - "step": 1, - "action": "POST /social/upload 호출", - "request": { - "video_id": 123, - "platform": "youtube", - "title": "영상 제목", - "privacy_status": "private" - }, - "result": "upload_id 반환" - }, - { - "step": 2, - "action": "GET /social/upload/{upload_id}/status 폴링 (3초 간격)", - "result": "status, upload_progress 확인" - }, - { - "step": 3, - "action": "status === 'completed' 확인", - "result": "platform_url로 YouTube 링크 표시" - } - ], - "pollingCode": "setInterval(() => checkUploadStatus(uploadId), 3000)" - } - } -}