402 lines
11 KiB
TypeScript
402 lines
11 KiB
TypeScript
|
|
// 사용자 경험 레벨
|
|
export type UserLevel = 'beginner' | 'intermediate' | 'pro';
|
|
|
|
// 레벨별 기능 플래그
|
|
export interface FeatureFlags {
|
|
// 옵션 선택기 표시
|
|
showLanguageSelector: boolean;
|
|
showMusicGenreSelector: boolean;
|
|
showAudioModeSelector: boolean;
|
|
showMusicDurationSelector: boolean;
|
|
showTextEffectSelector: boolean;
|
|
showTransitionSelector: boolean;
|
|
showAspectRatioSelector: boolean;
|
|
showVisualStyleSelector: boolean;
|
|
showTtsConfig: boolean;
|
|
|
|
// 고급 기능
|
|
showFestivalIntegration: boolean;
|
|
showAiImageGeneration: boolean;
|
|
showCustomCss: boolean;
|
|
showSeoEditor: boolean;
|
|
showThumbnailSelector: boolean;
|
|
|
|
// 메뉴 표시
|
|
showAssetLibrary: boolean;
|
|
showPensionManagement: boolean;
|
|
showAdvancedSettings: boolean;
|
|
showFestivalMenu: boolean;
|
|
|
|
// 자동화
|
|
autoUpload: boolean;
|
|
showUploadOptions: boolean;
|
|
showScheduleSettings: boolean;
|
|
}
|
|
|
|
// 자동 생성 설정
|
|
export interface AutoGenerationSettings {
|
|
enabled: boolean;
|
|
dayOfWeek: number; // 0=일, 1=월, ..., 6=토
|
|
timeOfDay: string; // "09:00"
|
|
pensionId?: number;
|
|
lastGeneratedAt?: string;
|
|
nextScheduledAt?: string;
|
|
}
|
|
|
|
export type Language = 'KO' | 'EN' | 'JP' | 'CN' | 'TH' | 'VN';
|
|
|
|
// 펜션 카테고리 타입
|
|
export type PensionCategory =
|
|
| 'PoolVilla' // 풀빌라
|
|
| 'OceanView' // 오션뷰
|
|
| 'Mountain' // 산장/계곡
|
|
| 'Private' // 독채
|
|
| 'Couple' // 커플펜션
|
|
| 'Family' // 가족펜션
|
|
| 'Pet' // 애견동반
|
|
| 'Glamping' // 글램핑
|
|
| 'Traditional'; // 한옥펜션
|
|
|
|
export type MusicGenre =
|
|
| 'Auto'
|
|
| 'K-Pop' | 'Ballad' | 'Hip-Hop' | 'R&B' | 'EDM' | 'Trot' | 'Jazz' | 'Rock' // Global/KR
|
|
| 'Pop' | 'Country' // EN
|
|
| 'J-Pop' | 'Enka' | 'Anime' // JP
|
|
| 'C-Pop' | 'Mandopop' | 'Traditional CN' // CN
|
|
| 'T-Pop' | 'Luk Thung' // TH
|
|
| 'V-Pop' | 'Bolero' // VN
|
|
;
|
|
|
|
export type MusicDuration = 'Short' | 'Full';
|
|
|
|
|
|
|
|
export type AudioMode = 'Song' | 'Narration' | 'Instrumental';
|
|
|
|
|
|
|
|
export type TTSGender = 'Male' | 'Female';
|
|
export type TTSAge = 'Young' | 'Middle';
|
|
export type TTSTone = 'Professional' | 'Bright' | 'Calm' | 'Energetic';
|
|
export type TextEffect = 'Neon' | 'Glitch' | 'Typewriter' | 'Cinematic' | 'Bold' | 'Motion' | 'LineReveal' | 'Boxed' | 'Elegant' | 'BlockReveal' | 'Custom';
|
|
export type TransitionEffect = 'Mix' | 'Zoom' | 'Slide' | 'Wipe'; // 전환 효과 추가
|
|
export type AspectRatio = '16:9' | '9:16';
|
|
export type CreationMode = 'Full' | 'AudioOnly'; // 생성 모드 추가
|
|
|
|
export interface TTSConfig {
|
|
gender: TTSGender;
|
|
age: TTSAge;
|
|
tone: TTSTone;
|
|
}
|
|
|
|
export interface BusinessInfo {
|
|
name: string;
|
|
description: string;
|
|
images: File[];
|
|
audioMode: AudioMode;
|
|
musicGenre: MusicGenre;
|
|
musicDuration: MusicDuration;
|
|
ttsConfig: TTSConfig;
|
|
textEffect: TextEffect;
|
|
transitionEffect?: TransitionEffect; // 전환 효과 필드
|
|
visualStyle: VisualStyle;
|
|
aspectRatio: AspectRatio;
|
|
creationMode: CreationMode; // 추가됨
|
|
sourceUrl?: string;
|
|
customStyleCSS?: string;
|
|
address?: string;
|
|
category?: string;
|
|
language: Language;
|
|
useAiImages: boolean; // AI 이미지 생성 허용 여부
|
|
pensionCategories?: PensionCategory[]; // 펜션 카테고리 (복수 선택)
|
|
nearbyFestivals?: { // 근처 축제 정보 (콘텐츠 생성에 활용)
|
|
id: number;
|
|
title: string;
|
|
eventstartdate?: string;
|
|
eventenddate?: string;
|
|
addr1?: string;
|
|
distance?: number;
|
|
}[];
|
|
}
|
|
|
|
export interface GeneratedAssets {
|
|
id: string;
|
|
createdAt: number;
|
|
businessName: string;
|
|
description?: string;
|
|
videoUrl: string;
|
|
audioUrl: string;
|
|
posterUrl: string; // AudioOnly일 경우 빈 문자열일 수 있음
|
|
adCopy: string[];
|
|
lyrics: string;
|
|
audioMode: AudioMode;
|
|
textEffect: TextEffect;
|
|
transitionEffect?: TransitionEffect; // 전환 효과 필드
|
|
visualStyle: VisualStyle;
|
|
aspectRatio: AspectRatio;
|
|
creationMode: CreationMode; // 추가됨
|
|
images?: string[];
|
|
customStyleCSS?: string;
|
|
sourceUrl?: string; // 추가됨
|
|
musicGenre?: string; // 추가됨
|
|
finalVideoPath?: string; // 렌더링 완료된 파일 경로
|
|
address?: string;
|
|
category?: string;
|
|
language?: Language;
|
|
pensionCategories?: PensionCategory[]; // 펜션 카테고리 (복수 선택)
|
|
}
|
|
|
|
export interface LoadingState {
|
|
status: 'idle' | 'crawling' | 'generating_text' | 'generating_audio' | 'generating_poster' | 'generating_video' | 'completed' | 'error';
|
|
message: string;
|
|
}
|
|
|
|
export enum Step {
|
|
INPUT = 0,
|
|
PROCESSING = 1,
|
|
RESULT = 2
|
|
}
|
|
|
|
export type VisualStyle = 'Video' | 'Slideshow';
|
|
|
|
// 구독 플랜 타입
|
|
export type PlanType = 'free' | 'basic' | 'pro' | 'business';
|
|
|
|
// 플랜별 설정
|
|
export const PLAN_CONFIG: Record<PlanType, {
|
|
name: string;
|
|
nameKo: string;
|
|
price: number;
|
|
maxPensions: number;
|
|
monthlyCredits: number;
|
|
features: string[];
|
|
}> = {
|
|
free: {
|
|
name: 'Free',
|
|
nameKo: '무료',
|
|
price: 0,
|
|
maxPensions: 1,
|
|
monthlyCredits: 10,
|
|
features: ['월 10회 영상 생성', '기본 음악', '720p 화질', '펜션 1개']
|
|
},
|
|
basic: {
|
|
name: 'Basic',
|
|
nameKo: '베이직',
|
|
price: 29000,
|
|
maxPensions: 1,
|
|
monthlyCredits: 15,
|
|
features: ['월 15회 영상 생성', '프리미엄 음악', '1080p 화질', '펜션 1개', 'AI 로고송 2곡']
|
|
},
|
|
pro: {
|
|
name: 'Pro',
|
|
nameKo: '프로',
|
|
price: 89000, // 베이직의 약 3배
|
|
maxPensions: 5,
|
|
monthlyCredits: 75, // 15 * 5
|
|
features: ['월 75회 영상 생성', '프리미엄 음악', '1080p Full HD', '펜션 5개 관리', 'AI 로고송 10곡', 'YouTube 분석', '우선 지원']
|
|
},
|
|
business: {
|
|
name: 'Business',
|
|
nameKo: '비즈니스',
|
|
price: 249000,
|
|
maxPensions: 999, // 무제한
|
|
monthlyCredits: 999, // 무제한
|
|
features: ['무제한 영상', '독점 음악 제작', '4K Ultra HD', '펜션 무제한', '로고송 무제한', '전담 매니저', 'API 연동']
|
|
}
|
|
};
|
|
|
|
export interface User {
|
|
id: number;
|
|
username: string; // ID
|
|
email?: string;
|
|
name: string;
|
|
role: 'admin' | 'user';
|
|
phone?: string;
|
|
business_name?: string;
|
|
approved?: number; // 0 or 1
|
|
emailVerified?: boolean;
|
|
email_verified?: number; // DB에서 0 or 1
|
|
createdAt?: string;
|
|
// 구독 관련
|
|
plan_type?: PlanType;
|
|
max_pensions?: number;
|
|
monthly_credits?: number;
|
|
credits?: number;
|
|
subscription_started_at?: string;
|
|
subscription_expires_at?: string;
|
|
}
|
|
|
|
// 펜션 프로필 타입
|
|
export interface PensionProfile {
|
|
id: number;
|
|
user_id: number;
|
|
is_default: number;
|
|
brand_name: string;
|
|
brand_name_en?: string;
|
|
region?: string;
|
|
address?: string;
|
|
pension_types?: string;
|
|
target_customers?: string;
|
|
key_features?: string;
|
|
nearby_attractions?: string;
|
|
booking_url?: string;
|
|
homepage_url?: string;
|
|
kakao_channel?: string;
|
|
instagram_handle?: string;
|
|
languages?: string;
|
|
price_range?: string;
|
|
description?: string;
|
|
youtube_playlist_id?: string;
|
|
youtube_playlist_title?: string;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
// YouTube 분석 데이터 타입
|
|
export interface YouTubeAnalytics {
|
|
id: number;
|
|
pension_id: number;
|
|
playlist_id: string;
|
|
date: string;
|
|
views: number;
|
|
playlist_starts: number;
|
|
average_time_in_playlist: number;
|
|
estimated_minutes_watched: number;
|
|
subscribers_gained: number;
|
|
likes: number;
|
|
comments: number;
|
|
shares: number;
|
|
cached_at: string;
|
|
}
|
|
|
|
// 월간 통계 타입
|
|
export interface PensionMonthlyStats {
|
|
id: number;
|
|
pension_id: number;
|
|
year_month: string;
|
|
total_views: number;
|
|
total_videos: number;
|
|
total_watch_time: number;
|
|
avg_view_duration: number;
|
|
top_video_id?: string;
|
|
growth_rate: number;
|
|
cached_at: string;
|
|
}
|
|
|
|
// 에셋 타입
|
|
export type AssetType = 'image' | 'audio' | 'video';
|
|
export type AssetSourceType = 'upload' | 'crawl' | 'ai_generated' | 'rendered';
|
|
|
|
// 사용자 에셋 타입
|
|
export interface UserAsset {
|
|
id: number;
|
|
user_id: number;
|
|
pension_id?: number;
|
|
history_id?: number;
|
|
asset_type: AssetType;
|
|
source_type: AssetSourceType;
|
|
file_name: string;
|
|
file_path: string;
|
|
file_size: number;
|
|
mime_type?: string;
|
|
thumbnail_path?: string;
|
|
duration?: number;
|
|
width?: number;
|
|
height?: number;
|
|
metadata?: string;
|
|
is_deleted: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
// 스토리지 사용량 통계
|
|
export interface StorageStats {
|
|
totalUsed: number; // bytes
|
|
storageLimit: number; // MB
|
|
imageCount: number;
|
|
audioCount: number;
|
|
videoCount: number;
|
|
imageSize: number; // bytes
|
|
audioSize: number; // bytes
|
|
videoSize: number; // bytes
|
|
}
|
|
|
|
// 축제 정보 타입
|
|
export interface NearbyFestival {
|
|
id: number;
|
|
title: string;
|
|
addr1?: string;
|
|
addr2?: string;
|
|
eventstartdate?: string;
|
|
eventenddate?: string;
|
|
tel?: string;
|
|
firstimage?: string;
|
|
firstimage2?: string;
|
|
mapx?: number;
|
|
mapy?: number;
|
|
distance?: number; // km 단위 거리
|
|
overview?: string;
|
|
}
|
|
|
|
// Business DNA - 펜션/숙소의 브랜드 DNA 분석 결과
|
|
export interface BusinessDNA {
|
|
// 기본 정보
|
|
name: string;
|
|
tagline?: string; // 한 줄 슬로건
|
|
|
|
// 톤 & 매너
|
|
toneAndManner: {
|
|
primary: string; // 예: "Warm & Cozy", "Luxurious & Elegant", "Modern & Minimal"
|
|
secondary?: string;
|
|
description: string; // 상세 설명
|
|
};
|
|
|
|
// 타겟 고객
|
|
targetCustomers: {
|
|
primary: string; // 예: "Young Couples", "Families with Kids", "Solo Travelers"
|
|
secondary?: string[];
|
|
ageRange?: string; // 예: "25-35"
|
|
characteristics?: string[]; // 특성들
|
|
};
|
|
|
|
// 브랜드 컬러
|
|
brandColors: {
|
|
primary: string; // HEX 코드, 예: "#4A90A4"
|
|
secondary?: string;
|
|
accent?: string;
|
|
palette?: string[]; // 전체 팔레트
|
|
mood: string; // 컬러가 주는 분위기
|
|
};
|
|
|
|
// 키워드 & 해시태그
|
|
keywords: {
|
|
primary: string[]; // 핵심 키워드 3-5개
|
|
secondary?: string[]; // 부가 키워드
|
|
hashtags?: string[]; // 추천 해시태그
|
|
};
|
|
|
|
// 시각적 스타일 (NEW)
|
|
visualStyle: {
|
|
interior: string; // 예: "Scandinavian Minimalist", "Korean Traditional Hanok", "Industrial Loft"
|
|
exterior: string; // 예: "Mountain Lodge", "Seaside Villa", "Forest Cabin"
|
|
atmosphere: string; // 예: "Serene & Peaceful", "Vibrant & Energetic", "Romantic & Intimate"
|
|
photoStyle: string; // 사진 스타일: "Warm Natural Light", "Moody & Dramatic", "Bright & Airy"
|
|
suggestedFilters?: string[]; // 추천 필터/톤: ["Warm", "High Contrast", "Muted Colors"]
|
|
};
|
|
|
|
// 차별화 포인트
|
|
uniqueSellingPoints: string[];
|
|
|
|
// 분위기/무드
|
|
mood: {
|
|
primary: string;
|
|
emotions: string[]; // 고객이 느낄 감정들
|
|
};
|
|
|
|
// 메타 정보
|
|
analyzedAt: string;
|
|
confidence: number; // 0-1 분석 신뢰도
|
|
sources?: string[]; // 분석에 사용된 소스들
|
|
}
|
|
|