o2o-infinith-backend/app/integrations/llm/schemas/plan.py

240 lines
5.2 KiB
Python

from typing import Literal
from pydantic import BaseModel
class PlanInput(BaseModel):
clinic_name: str | None = None
clinic_name_en: str | None = None
address: str | None = None
phone: str | None = None
slogan: str | None = None
services: str | None = None
doctors: str | None = None
report: str | None = None
# --- BrandGuide ---
class ColorSwatch(BaseModel):
name: str
hex: str
usage: str
class FontSpec(BaseModel):
family: str
weight: str
usage: str
sampleText: str
class LogoUsageRule(BaseModel):
rule: str
description: str
correct: bool
class ToneOfVoice(BaseModel):
personality: list[str]
communicationStyle: str
doExamples: list[str]
dontExamples: list[str]
class ChannelBrandingRule(BaseModel):
channel: str
icon: str
profilePhoto: str
bannerSpec: str
bioTemplate: str
currentStatus: Literal["correct", "incorrect", "missing"]
class BrandInconsistencyValue(BaseModel):
channel: str
value: str
isCorrect: bool
class BrandInconsistency(BaseModel):
field: str
values: list[BrandInconsistencyValue]
impact: str
recommendation: str
class BrandGuide(BaseModel):
colors: list[ColorSwatch]
fonts: list[FontSpec]
logoRules: list[LogoUsageRule]
toneOfVoice: ToneOfVoice
channelBranding: list[ChannelBrandingRule]
brandInconsistencies: list[BrandInconsistency]
# --- ChannelStrategy ---
class ChannelStrategyCard(BaseModel):
channelId: str
channelName: str
icon: str
currentStatus: str
targetGoal: str
contentTypes: list[str]
postingFrequency: str
tone: str
formatGuidelines: list[str]
priority: Literal["P0", "P1", "P2"]
customerJourneyStage: Literal["awareness", "interest", "consideration", "conversion", "loyalty"] | None = None
# --- ContentStrategy ---
class ContentPillar(BaseModel):
title: str
description: str
relatedUSP: str
exampleTopics: list[str]
color: str
class ContentTypeRow(BaseModel):
format: str
channels: list[str]
frequency: str
purpose: str
class WorkflowStep(BaseModel):
step: int
name: str
description: str
owner: str
duration: str
class RepurposingOutput(BaseModel):
format: str
channel: str
description: str
class ContentStrategyData(BaseModel):
pillars: list[ContentPillar]
typeMatrix: list[ContentTypeRow]
workflow: list[WorkflowStep]
repurposingSource: str
repurposingOutputs: list[RepurposingOutput]
# --- Calendar ---
class CalendarEntry(BaseModel):
dayOfWeek: int
channel: str
channelIcon: str
contentType: Literal["video", "blog", "social", "ad"]
title: str
id: str | None = None
description: str | None = None
pillar: str | None = None
status: Literal["draft", "approved", "published"] | None = None
isManualEdit: bool | None = None
aiPromptSeed: str | None = None
class CalendarWeek(BaseModel):
weekNumber: int
label: str
entries: list[CalendarEntry]
class ContentCountSummary(BaseModel):
type: Literal["video", "blog", "social", "ad"]
label: str
count: int
color: str
class CalendarData(BaseModel):
weeks: list[CalendarWeek]
monthlySummary: list[ContentCountSummary]
# --- AssetCollection ---
class AssetCard(BaseModel):
id: str
source: Literal["homepage", "naver_place", "blog", "social", "youtube"]
sourceLabel: str
type: Literal["photo", "video", "text"]
title: str
description: str
repurposingSuggestions: list[str]
status: Literal["collected", "pending", "needs_creation"]
class YouTubeRepurposeItem(BaseModel):
title: str
views: int
type: Literal["Short", "Long"]
repurposeAs: list[str]
class AssetCollectionData(BaseModel):
assets: list[AssetCard]
youtubeRepurpose: list[YouTubeRepurposeItem]
# --- Repurposing ---
class RepurposingProposalItem(BaseModel):
sourceVideo: YouTubeRepurposeItem
outputs: list[RepurposingOutput]
estimatedEffort: Literal["low", "medium", "high"]
priority: Literal["high", "medium", "low"]
# --- Workflow ---
class WorkflowVideoDraft(BaseModel):
script: str
shootingGuide: list[str]
duration: str
# class WorkflowImageTextDraft(BaseModel):
# type: Literal["cardnews", "blog"]
# headline: str
# copy: list[str]
# layoutHint: str | None = None
# class WorkflowItem(BaseModel):
# id: str
# title: str
# contentType: Literal["video", "image-text"]
# channel: str
# channelIcon: str
# stage: Literal["planning", "ai-draft", "review", "approved", "scheduled"]
# userNotes: str | None = None
# videoDraft: WorkflowVideoDraft | None = None
# imageTextDraft: WorkflowImageTextDraft | None = None
# scheduledDate: str | None = None
# class WorkflowData(BaseModel):
# items: list[WorkflowItem]
# --- PlanOutput ---
class PlanOutput(BaseModel):
brandGuide: BrandGuide
channelStrategies: list[ChannelStrategyCard]
contentStrategy: ContentStrategyData
calendar: CalendarData
assetCollection: AssetCollectionData
repurposingProposals: list[RepurposingProposalItem] | None = None
#workflow: WorkflowData | None = None