清理內容: - 移除所有開發元資訊(Author, Version, DocID, Rationale等) - 刪除註解掉的代碼片段(力導向演算法等24行) - 移除調試用的 logger.debug 語句 - 簡化冗餘的內聯註解(emoji、"重要"等標註) - 刪除 TDD 文件引用 清理檔案: - backend/main.py - 移除調試日誌和元資訊 - backend/importer.py - 移除詳細類型檢查調試 - backend/export.py - 簡化 docstring - backend/schemas.py - 移除元資訊 - backend/renderer.py - 移除 TDD 引用 - backend/renderer_timeline.py - 移除註解代碼和冗餘註解 - backend/path_planner.py - 簡化策略註解 保留內容: - 所有函數的 docstring(功能說明、參數、返回值) - 必要的業務邏輯註解 - 簡潔的模組功能說明 效果: - 刪除約 100+ 行冗餘註解 - 代碼更加簡潔專業 - 功能完整性 100% 保留 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
253 lines
7.2 KiB
Python
253 lines
7.2 KiB
Python
"""
|
||
資料模型定義 (Data Schemas)
|
||
|
||
本模組定義 TimeLine Designer 所有資料結構。
|
||
遵循 Pydantic BaseModel 進行嚴格型別驗證。
|
||
"""
|
||
|
||
from datetime import datetime
|
||
from typing import Optional, Literal, List
|
||
from pydantic import BaseModel, Field, field_validator
|
||
from enum import Enum
|
||
|
||
|
||
class EventType(str, Enum):
|
||
"""事件類型枚舉"""
|
||
POINT = "point" # 時間點事件
|
||
RANGE = "range" # 時間區間事件
|
||
MILESTONE = "milestone" # 里程碑
|
||
|
||
|
||
class Event(BaseModel):
|
||
"""
|
||
時間軸事件模型
|
||
|
||
對應 SDD.md - 2. 資料模型 - Event
|
||
用於表示時間軸上的單一事件或時間區間。
|
||
"""
|
||
id: str = Field(..., description="事件唯一識別碼")
|
||
title: str = Field(..., min_length=1, max_length=200, description="事件標題")
|
||
start: datetime = Field(..., description="開始時間")
|
||
end: Optional[datetime] = Field(None, description="結束時間(可選)")
|
||
group: Optional[str] = Field(None, description="事件群組/分類")
|
||
description: Optional[str] = Field(None, max_length=1000, description="事件詳細描述")
|
||
color: str = Field(default='#3B82F6', pattern=r'^#[0-9A-Fa-f]{6}$', description="事件顏色(HEX格式)")
|
||
event_type: EventType = Field(EventType.POINT, description="事件類型")
|
||
|
||
@field_validator('end')
|
||
@classmethod
|
||
def validate_end_after_start(cls, end, info):
|
||
"""驗證結束時間必須晚於開始時間"""
|
||
if end and info.data.get('start') and end < info.data['start']:
|
||
raise ValueError('結束時間必須晚於開始時間')
|
||
return end
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"id": "evt-001",
|
||
"title": "專案啟動",
|
||
"start": "2024-01-01T09:00:00",
|
||
"end": "2024-01-01T17:00:00",
|
||
"group": "Phase 1",
|
||
"description": "專案正式啟動會議",
|
||
"color": "#3B82F6",
|
||
"event_type": "range"
|
||
}
|
||
}
|
||
|
||
|
||
class ThemeStyle(str, Enum):
|
||
"""主題樣式枚舉"""
|
||
MODERN = "modern"
|
||
CLASSIC = "classic"
|
||
MINIMAL = "minimal"
|
||
CORPORATE = "corporate"
|
||
|
||
|
||
class TimelineConfig(BaseModel):
|
||
"""
|
||
時間軸配置模型
|
||
|
||
對應 SDD.md - 2. 資料模型 - TimelineConfig
|
||
控制時間軸的顯示方式與視覺樣式。
|
||
"""
|
||
direction: Literal['horizontal', 'vertical'] = Field(
|
||
'horizontal',
|
||
description="時間軸方向"
|
||
)
|
||
theme: ThemeStyle = Field(
|
||
ThemeStyle.MODERN,
|
||
description="視覺主題"
|
||
)
|
||
show_grid: bool = Field(
|
||
True,
|
||
description="是否顯示網格線"
|
||
)
|
||
show_tooltip: bool = Field(
|
||
True,
|
||
description="是否顯示提示訊息"
|
||
)
|
||
enable_zoom: bool = Field(
|
||
True,
|
||
description="是否啟用縮放功能"
|
||
)
|
||
enable_drag: bool = Field(
|
||
True,
|
||
description="是否啟用拖曳功能"
|
||
)
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"direction": "horizontal",
|
||
"theme": "modern",
|
||
"show_grid": True,
|
||
"show_tooltip": True,
|
||
"enable_zoom": True,
|
||
"enable_drag": True
|
||
}
|
||
}
|
||
|
||
|
||
class ExportFormat(str, Enum):
|
||
"""匯出格式枚舉"""
|
||
PNG = "png"
|
||
PDF = "pdf"
|
||
SVG = "svg"
|
||
|
||
|
||
class ExportOptions(BaseModel):
|
||
"""
|
||
匯出選項模型
|
||
|
||
對應 SDD.md - 2. 資料模型 - ExportOptions
|
||
控制時間軸圖檔的匯出格式與品質。
|
||
"""
|
||
fmt: ExportFormat = Field(..., description="匯出格式")
|
||
dpi: int = Field(
|
||
300,
|
||
ge=72,
|
||
le=600,
|
||
description="解析度(DPI)"
|
||
)
|
||
width: Optional[int] = Field(
|
||
1920,
|
||
ge=800,
|
||
le=4096,
|
||
description="圖片寬度(像素)"
|
||
)
|
||
height: Optional[int] = Field(
|
||
1080,
|
||
ge=600,
|
||
le=4096,
|
||
description="圖片高度(像素)"
|
||
)
|
||
transparent_background: bool = Field(
|
||
False,
|
||
description="是否使用透明背景"
|
||
)
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"fmt": "pdf",
|
||
"dpi": 300,
|
||
"width": 1920,
|
||
"height": 1080,
|
||
"transparent_background": False
|
||
}
|
||
}
|
||
|
||
|
||
class Theme(BaseModel):
|
||
"""
|
||
主題定義模型
|
||
|
||
用於 /themes API 回傳主題列表。
|
||
"""
|
||
name: str = Field(..., description="主題名稱")
|
||
style: ThemeStyle = Field(..., description="主題樣式識別碼")
|
||
primary_color: str = Field(..., pattern=r'^#[0-9A-Fa-f]{6}$', description="主要顏色")
|
||
background_color: str = Field(..., pattern=r'^#[0-9A-Fa-f]{6}$', description="背景顏色")
|
||
text_color: str = Field(..., pattern=r'^#[0-9A-Fa-f]{6}$', description="文字顏色")
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"name": "現代風格",
|
||
"style": "modern",
|
||
"primary_color": "#3B82F6",
|
||
"background_color": "#FFFFFF",
|
||
"text_color": "#1F2937"
|
||
}
|
||
}
|
||
|
||
|
||
class ImportResult(BaseModel):
|
||
"""
|
||
匯入結果模型
|
||
|
||
用於 /import API 回傳匯入結果。
|
||
"""
|
||
success: bool = Field(..., description="是否成功")
|
||
events: List[Event] = Field(default_factory=list, description="成功匯入的事件列表")
|
||
errors: List[str] = Field(default_factory=list, description="錯誤訊息列表")
|
||
total_rows: int = Field(0, description="總行數")
|
||
imported_count: int = Field(0, description="成功匯入數量")
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"success": True,
|
||
"events": [],
|
||
"errors": [],
|
||
"total_rows": 100,
|
||
"imported_count": 98
|
||
}
|
||
}
|
||
|
||
|
||
class RenderResult(BaseModel):
|
||
"""
|
||
渲染結果模型
|
||
|
||
用於 /render API 回傳 Plotly JSON 格式的時間軸資料。
|
||
"""
|
||
success: bool = Field(..., description="是否成功")
|
||
data: dict = Field(..., description="Plotly 圖表資料(JSON格式)")
|
||
layout: dict = Field(..., description="Plotly 佈局設定")
|
||
config: dict = Field(default_factory=dict, description="Plotly 配置")
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"success": True,
|
||
"data": {},
|
||
"layout": {},
|
||
"config": {}
|
||
}
|
||
}
|
||
|
||
|
||
class APIResponse(BaseModel):
|
||
"""
|
||
通用 API 回應模型
|
||
|
||
用於標準化 API 回應格式,提供一致的錯誤處理。
|
||
"""
|
||
success: bool = Field(..., description="操作是否成功")
|
||
message: str = Field("", description="回應訊息")
|
||
data: Optional[dict] = Field(None, description="回應資料")
|
||
error_code: Optional[str] = Field(None, description="錯誤代碼(如有)")
|
||
|
||
class Config:
|
||
json_schema_extra = {
|
||
"example": {
|
||
"success": True,
|
||
"message": "操作成功",
|
||
"data": None,
|
||
"error_code": None
|
||
}
|
||
}
|