525 lines
13 KiB
Python
525 lines
13 KiB
Python
from pydantic import BaseModel, ConfigDict, Field
|
|
from datetime import datetime, date
|
|
from typing import Optional, List, Dict, Any
|
|
|
|
|
|
class TopicFieldBase(BaseModel):
|
|
name: str
|
|
icon: Optional[str] = None
|
|
color: Optional[str] = None
|
|
description: Optional[str] = None
|
|
parent_id: Optional[int] = None
|
|
sort_order: int = 0
|
|
is_active: bool = True
|
|
|
|
|
|
class TopicFieldResponse(TopicFieldBase):
|
|
id: int
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class TopicConfigFieldBase(BaseModel):
|
|
name: str
|
|
key: str
|
|
field_type: str = "number"
|
|
weight: float = 1.0
|
|
options: List[Any] = []
|
|
min_value: Optional[float] = None
|
|
max_value: Optional[float] = None
|
|
is_required: bool = False
|
|
sort_order: int = 0
|
|
|
|
|
|
class TopicConfigFieldResponse(TopicConfigFieldBase):
|
|
id: int
|
|
field_id: int
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class TopicStatusConfigBase(BaseModel):
|
|
status: str
|
|
label: str
|
|
color: Optional[str] = None
|
|
icon: Optional[str] = None
|
|
sort_order: int = 0
|
|
is_default: bool = False
|
|
|
|
|
|
class TopicStatusConfigResponse(TopicStatusConfigBase):
|
|
id: int
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class TopicBase(BaseModel):
|
|
id: str
|
|
field_id: Optional[int] = None
|
|
field_name: Optional[str] = None
|
|
org_id: Optional[str] = None
|
|
title: str
|
|
format: Optional[str] = None
|
|
core_concept: Optional[str] = None
|
|
audience_pain: Optional[str] = None
|
|
unique_angle: Optional[str] = None
|
|
priority: Optional[str] = None
|
|
priority_score: int | float = 0
|
|
total_score: Optional[float] = None
|
|
status: str = "pending"
|
|
tags: List[str] = []
|
|
custom_data: Dict[str, Any] = {}
|
|
scoring_data: Dict[str, Any] = {}
|
|
lock_by: Optional[str] = None
|
|
lock_at: Optional[datetime] = None
|
|
|
|
|
|
class TopicCreate(BaseModel):
|
|
id: Optional[str] = None
|
|
field_id: Optional[int] = None
|
|
title: str = Field(..., min_length=1)
|
|
format: Optional[str] = None
|
|
core_concept: Optional[str] = None
|
|
audience_pain: Optional[str] = None
|
|
unique_angle: Optional[str] = None
|
|
priority: Optional[str] = None
|
|
tags: List[str] = []
|
|
custom_data: Dict[str, Any] = {}
|
|
scoring_data: Dict[str, Any] = {}
|
|
|
|
|
|
class TopicUpdate(BaseModel):
|
|
field_id: Optional[int] = None
|
|
title: Optional[str] = None
|
|
format: Optional[str] = None
|
|
core_concept: Optional[str] = None
|
|
audience_pain: Optional[str] = None
|
|
unique_angle: Optional[str] = None
|
|
priority: Optional[str] = None
|
|
status: Optional[str] = None
|
|
tags: Optional[List[str]] = None
|
|
custom_data: Optional[Dict[str, Any]] = None
|
|
scoring_data: Optional[Dict[str, Any]] = None
|
|
priority_score: Optional[int] = None
|
|
total_score: Optional[float] = None
|
|
|
|
|
|
class TopicResponse(TopicBase):
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
generated_at: Optional[datetime] = None
|
|
ready_at: Optional[date] = None
|
|
published_at: Optional[date] = None
|
|
compliance_score: Optional[int] = None
|
|
platform_urls: Dict[str, str] = {}
|
|
cases: List[Any] = []
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class TopicScoreRequest(BaseModel):
|
|
scoring_data: Dict[str, Any]
|
|
|
|
|
|
class ArticleBase(BaseModel):
|
|
id: str
|
|
topic_id: str
|
|
platform: str
|
|
file_path: str
|
|
status: str = "draft"
|
|
compliance_score: Optional[int] = None
|
|
word_count: Optional[int] = None
|
|
outline: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ArticleResponse(ArticleBase):
|
|
html_content: Optional[str] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ContentCalendarBase(BaseModel):
|
|
topic_id: Optional[str] = None
|
|
field_id: Optional[int] = None
|
|
title: str
|
|
planned_date: date
|
|
platform: Optional[str] = None
|
|
status: str = "planned"
|
|
reminder_time: Optional[datetime] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class ContentCalendarCreate(ContentCalendarBase):
|
|
created_by: Optional[str] = None
|
|
|
|
|
|
class ContentCalendarUpdate(BaseModel):
|
|
topic_id: Optional[str] = None
|
|
title: Optional[str] = None
|
|
planned_date: Optional[date] = None
|
|
published_date: Optional[date] = None
|
|
platform: Optional[str] = None
|
|
status: Optional[str] = None
|
|
reminder_time: Optional[datetime] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class ContentCalendarResponse(ContentCalendarBase):
|
|
id: int
|
|
published_date: Optional[date] = None
|
|
created_by: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
topic_status: Optional[str] = None
|
|
platform_icon: Optional[str] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ContentMetricsBase(BaseModel):
|
|
topic_id: str
|
|
platform: str
|
|
publish_url: Optional[str] = None
|
|
views: int = 0
|
|
likes: int = 0
|
|
favorites: int = 0
|
|
comments: int = 0
|
|
shares: int = 0
|
|
|
|
|
|
class ContentMetricsCreate(ContentMetricsBase):
|
|
data_snapshot: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
class ContentMetricsUpdate(BaseModel):
|
|
publish_url: Optional[str] = None
|
|
views: Optional[int] = None
|
|
likes: Optional[int] = None
|
|
favorites: Optional[int] = None
|
|
comments: Optional[int] = None
|
|
shares: Optional[int] = None
|
|
data_snapshot: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
class ContentMetricsResponse(ContentMetricsBase):
|
|
id: int
|
|
engagement_rate: float = 0
|
|
last_fetched: Optional[datetime] = None
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class MediaAssetBase(BaseModel):
|
|
filename: str
|
|
file_path: str
|
|
file_url: Optional[str] = None
|
|
file_type: str
|
|
mime_type: Optional[str] = None
|
|
size: Optional[int] = None
|
|
width: Optional[int] = None
|
|
height: Optional[int] = None
|
|
thumbnail_path: Optional[str] = None
|
|
alt_text: Optional[str] = None
|
|
tags: List[str] = []
|
|
topic_ids: List[str] = []
|
|
|
|
|
|
class MediaAssetCreate(MediaAssetBase):
|
|
uploaded_by: Optional[str] = None
|
|
|
|
|
|
class MediaAssetUpdate(BaseModel):
|
|
alt_text: Optional[str] = None
|
|
tags: Optional[List[str]] = None
|
|
topic_ids: Optional[List[str]] = None
|
|
|
|
|
|
class MediaAssetResponse(MediaAssetBase):
|
|
id: int
|
|
usage_count: int = 0
|
|
uploaded_by: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class PlatformConfigBase(BaseModel):
|
|
platform: str
|
|
name: str
|
|
icon: Optional[str] = None
|
|
api_endpoint: Optional[str] = None
|
|
auth_config: Dict[str, Any] = {}
|
|
format_template: Dict[str, Any] = {}
|
|
compliance_rules: Dict[str, Any] = {}
|
|
default_format: Optional[str] = None
|
|
is_active: bool = True
|
|
requires_image: bool = False
|
|
image_count_min: int = 0
|
|
image_count_max: int = 0
|
|
image_width: int = 0
|
|
image_height: int = 0
|
|
min_words: int = 0
|
|
max_words: int = 0
|
|
|
|
|
|
class PlatformConfigCreate(PlatformConfigBase):
|
|
pass
|
|
|
|
|
|
class PlatformConfigUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
icon: Optional[str] = None
|
|
api_endpoint: Optional[str] = None
|
|
auth_config: Optional[Dict[str, Any]] = None
|
|
format_template: Optional[Dict[str, Any]] = None
|
|
compliance_rules: Optional[Dict[str, Any]] = None
|
|
default_format: Optional[str] = None
|
|
is_active: Optional[bool] = None
|
|
requires_image: Optional[bool] = None
|
|
image_count_min: Optional[int] = None
|
|
image_count_max: Optional[int] = None
|
|
image_width: Optional[int] = None
|
|
image_height: Optional[int] = None
|
|
min_words: Optional[int] = None
|
|
max_words: Optional[int] = None
|
|
|
|
|
|
class PlatformConfigResponse(PlatformConfigBase):
|
|
id: int
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ContentTaskBase(BaseModel):
|
|
topic_id: Optional[str] = None
|
|
stage: str
|
|
status: str = "pending"
|
|
progress: int = 0
|
|
message: Optional[str] = None
|
|
|
|
|
|
class ContentTaskCreate(BaseModel):
|
|
topic_id: Optional[str] = None
|
|
stage: str
|
|
created_by: Optional[str] = None
|
|
|
|
|
|
class ContentTaskResponse(ContentTaskBase):
|
|
id: int
|
|
task_id: str
|
|
topic_id: Optional[str] = None
|
|
topic_title: Optional[str] = None
|
|
result_data: Dict[str, Any] = {}
|
|
error_msg: Optional[str] = None
|
|
started_at: Optional[datetime] = None
|
|
finished_at: Optional[datetime] = None
|
|
duration: Optional[int] = None
|
|
created_by: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class MetricsDashboard(BaseModel):
|
|
total_topics: int
|
|
topics_by_status: Dict[str, int]
|
|
total_published: int
|
|
total_views: int
|
|
total_likes: int
|
|
avg_engagement_rate: float
|
|
top_topics: List[Dict[str, Any]]
|
|
recent_metrics: List[ContentMetricsResponse]
|
|
|
|
|
|
class CalendarMonthResponse(BaseModel):
|
|
year: int
|
|
month: int
|
|
entries: List[ContentCalendarResponse]
|
|
stats: Dict[str, int]
|
|
|
|
|
|
class AuditLogBase(BaseModel):
|
|
user_id: Optional[int] = None
|
|
username: str
|
|
action: str
|
|
resource_type: Optional[str] = None
|
|
resource_id: Optional[str] = None
|
|
details: Optional[Dict[str, Any]] = None
|
|
ip_address: Optional[str] = None
|
|
user_agent: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class AuditLogResponse(AuditLogBase):
|
|
id: int
|
|
|
|
|
|
class UserBase(BaseModel):
|
|
username: str
|
|
role: str = "user"
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
password: str
|
|
org_id: Optional[str] = None
|
|
|
|
|
|
class UserUpdate(BaseModel):
|
|
username: Optional[str] = None
|
|
password: Optional[str] = None
|
|
role: Optional[str] = None
|
|
|
|
|
|
class UserResponse(UserBase):
|
|
id: int
|
|
org_id: Optional[str] = None
|
|
created_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
token: str
|
|
role: str
|
|
user: UserResponse
|
|
|
|
|
|
class PublishRequest(BaseModel):
|
|
topic_id: str
|
|
platform_urls: Dict[str, str]
|
|
|
|
|
|
class PublishActionRequest(BaseModel):
|
|
action: str
|
|
platform: Optional[str] = None
|
|
status: str
|
|
operator: Optional[str] = None
|
|
description: Optional[str] = None
|
|
suggestion: Optional[str] = None
|
|
url: Optional[str] = None
|
|
error_msg: Optional[str] = None
|
|
|
|
|
|
class PublishRecordResponse(BaseModel):
|
|
id: int
|
|
topic_id: str
|
|
platform: str
|
|
action: str
|
|
status: str
|
|
operator: Optional[str] = None
|
|
description: Optional[str] = None
|
|
suggestion: Optional[str] = None
|
|
url: Optional[str] = None
|
|
error_msg: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class CaseBase(BaseModel):
|
|
title: str
|
|
field: str
|
|
summary: str
|
|
key_metrics: Optional[str] = None
|
|
date: Optional[str] = None
|
|
source: str
|
|
source_url: Optional[str] = None
|
|
credibility_rating: Optional[str] = None
|
|
china_applicability: Optional[str] = None
|
|
|
|
|
|
class CaseResponse(CaseBase):
|
|
id: int
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class TaskLogBase(BaseModel):
|
|
task_name: str
|
|
topic_id: Optional[str] = None
|
|
status: str
|
|
message: Optional[str] = None
|
|
started_at: Optional[datetime] = None
|
|
finished_at: Optional[datetime] = None
|
|
duration: Optional[int] = None
|
|
|
|
|
|
class TaskLogResponse(TaskLogBase):
|
|
id: int
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class LLMConfigBase(BaseModel):
|
|
name: str
|
|
system_prompt: Optional[str] = None
|
|
user_prompt_template: str
|
|
temperature: float = 0.7
|
|
max_tokens: int = 2000
|
|
model: Optional[str] = None
|
|
provider: str = "opencode-go"
|
|
base_url: Optional[str] = None
|
|
api_key: Optional[str] = None
|
|
is_active: bool = True
|
|
|
|
|
|
class LLMConfigResponse(LLMConfigBase):
|
|
id: int
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
created_at: Optional[datetime] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class SystemConfigBase(BaseModel):
|
|
key: str
|
|
value: Optional[str] = None
|
|
description: Optional[str] = None
|
|
|
|
|
|
class SystemConfigResponse(SystemConfigBase):
|
|
value: Optional[Any] = None
|
|
updated_at: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class SystemStatus(BaseModel):
|
|
total_topics: int
|
|
topics_by_status: Dict[str, int]
|
|
ready_topics: List[TopicResponse]
|
|
today_articles: int
|
|
compliance_rate: float
|
|
last_optimization: Optional[datetime] = None
|
|
execution_time: Optional[float] = None
|
|
|
|
|
|
class OptimizationRequest(BaseModel):
|
|
topic_ids: Optional[List[str]] = None
|
|
|
|
|
|
class BatchPublishRequest(BaseModel):
|
|
date: str |