o2o-infinith-demo/src/types/plan.ts
Haewon Kam 2027ae9b64 feat: 마케팅 플랜 Phase 1~3 완성
- ContentCalendar: 드래그앤드롭(주차 내 요일 간 이동) + 엔트리 추가 버튼 + iCal Export
- BrandingGuide: 색상 팔레트 인라인 편집(스와치 클릭 → hex 팝오버) + DO/DON'T 2컬럼
- WorkflowTracker: 콘텐츠 제작 파이프라인(기획→AI초안→검토→승인→배포), 동영상/이미지+텍스트 분류
- RepurposingProposal: YouTube 인기 영상 리퍼포징 제안 아코디언 섹션
- AssetDetailModal: 에셋 카드 클릭 시 상세 모달
- 디자인 시스템 감사: Lucide 라인 아이콘 제거, 원색(pink/indigo/purple) 제거, 이모지 UI 제거
- "My Assets" → "나의 소재" 일관성 변경
- FilledIcons: DownloadFilled, RocketFilled 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:44:21 +09:00

231 lines
5.1 KiB
TypeScript

import type { BrandInconsistency } from './report';
// ─── Section 1: Branding Guide ───
export interface ColorSwatch {
name: string;
hex: string;
usage: string;
}
export interface FontSpec {
family: string;
weight: string;
usage: string;
sampleText: string;
}
export interface LogoUsageRule {
rule: string;
description: string;
correct: boolean;
}
export interface ToneOfVoice {
personality: string[];
communicationStyle: string;
doExamples: string[];
dontExamples: string[];
}
export interface ChannelBrandingRule {
channel: string;
icon: string;
profilePhoto: string;
bannerSpec: string;
bioTemplate: string;
currentStatus: 'correct' | 'incorrect' | 'missing';
}
export interface BrandGuide {
colors: ColorSwatch[];
fonts: FontSpec[];
logoRules: LogoUsageRule[];
toneOfVoice: ToneOfVoice;
channelBranding: ChannelBrandingRule[];
brandInconsistencies: BrandInconsistency[];
}
// ─── Section 2: Channel Communication Strategy ───
export interface ChannelStrategyCard {
channelId: string;
channelName: string;
icon: string;
currentStatus: string;
targetGoal: string;
contentTypes: string[];
postingFrequency: string;
tone: string;
formatGuidelines: string[];
priority: 'P0' | 'P1' | 'P2';
customerJourneyStage?: 'awareness' | 'interest' | 'consideration' | 'conversion' | 'loyalty';
}
// ─── Section 3: Content Marketing Strategy ───
export interface ContentPillar {
title: string;
description: string;
relatedUSP: string;
exampleTopics: string[];
color: string;
}
export interface ContentTypeRow {
format: string;
channels: string[];
frequency: string;
purpose: string;
}
export interface WorkflowStep {
step: number;
name: string;
description: string;
owner: string;
duration: string;
}
export interface RepurposingOutput {
format: string;
channel: string;
description: string;
}
export interface ContentStrategyData {
pillars: ContentPillar[];
typeMatrix: ContentTypeRow[];
workflow: WorkflowStep[];
repurposingSource: string;
repurposingOutputs: RepurposingOutput[];
}
// ─── Section 4: Content Calendar ───
export type ContentCategory = 'video' | 'blog' | 'social' | 'ad';
export interface CalendarEntry {
dayOfWeek: number;
channel: string;
channelIcon: string;
contentType: ContentCategory;
title: string;
// AI-generated fields (optional — backward compatible with deterministic engine)
id?: string;
description?: string;
pillar?: string;
status?: 'draft' | 'approved' | 'published';
isManualEdit?: boolean;
aiPromptSeed?: string;
}
export interface CalendarWeek {
weekNumber: number;
label: string;
entries: CalendarEntry[];
}
export interface ContentCountSummary {
type: ContentCategory;
label: string;
count: number;
color: string;
}
export interface CalendarData {
weeks: CalendarWeek[];
monthlySummary: ContentCountSummary[];
}
// ─── Section 5: Asset Collection ───
export type AssetSource = 'homepage' | 'naver_place' | 'blog' | 'social' | 'youtube';
export type AssetType = 'photo' | 'video' | 'text';
export type AssetStatus = 'collected' | 'pending' | 'needs_creation';
export interface AssetCard {
id: string;
source: AssetSource;
sourceLabel: string;
type: AssetType;
title: string;
description: string;
repurposingSuggestions: string[];
status: AssetStatus;
}
export interface YouTubeRepurposeItem {
title: string;
views: number;
type: 'Short' | 'Long';
repurposeAs: string[];
}
export interface AssetCollectionData {
assets: AssetCard[];
youtubeRepurpose: YouTubeRepurposeItem[];
}
// ─── Section 6: Repurposing Proposal ───
export interface RepurposingProposalItem {
sourceVideo: YouTubeRepurposeItem;
outputs: RepurposingOutput[];
estimatedEffort: 'low' | 'medium' | 'high';
priority: 'high' | 'medium' | 'low';
}
// ─── Section 7: Workflow Tracker ───
export type WorkflowStage = 'planning' | 'ai-draft' | 'review' | 'approved' | 'scheduled';
export type WorkflowContentType = 'video' | 'image-text';
export interface WorkflowVideoDraft {
script: string;
shootingGuide: string[];
duration: string; // e.g. '60초', '15분'
}
export interface WorkflowImageTextDraft {
type: 'cardnews' | 'blog';
headline: string;
copy: string[];
layoutHint?: string;
}
export interface WorkflowItem {
id: string;
title: string;
contentType: WorkflowContentType;
channel: string;
channelIcon: string;
stage: WorkflowStage;
userNotes?: string; // 사람이 입력한 수정 사항
videoDraft?: WorkflowVideoDraft;
imageTextDraft?: WorkflowImageTextDraft;
scheduledDate?: string;
}
export interface WorkflowData {
items: WorkflowItem[];
}
// ─── Root Plan Type ───
export interface MarketingPlan {
id: string;
reportId: string;
clinicName: string;
clinicNameEn: string;
createdAt: string;
targetUrl: string;
brandGuide: BrandGuide;
channelStrategies: ChannelStrategyCard[];
contentStrategy: ContentStrategyData;
calendar: CalendarData;
assetCollection: AssetCollectionData;
repurposingProposals?: RepurposingProposalItem[];
workflow?: WorkflowData;
}