from pydantic import BaseModel, EmailStr from typing import Optional, Union, List import datetime class LoginRequest(BaseModel): username: str password: str class LoginResponse(BaseModel): user_id: int username: str caption: str email: EmailStr token: str role_id: int class RoleInfo(BaseModel): role_id: int role_name: str class UserInfo(BaseModel): user_id: int username: str caption: str email: EmailStr created_at: datetime.datetime meetings_created: int meetings_attended: int role_id: int role_name: str class UserListResponse(BaseModel): users: list[UserInfo] total: int class CreateUserRequest(BaseModel): username: str password: Optional[str] = None caption: str email: EmailStr role_id: int class UpdateUserRequest(BaseModel): username: Optional[str] = None caption: Optional[str] = None email: Optional[str] = None role_id: Optional[int] = None class AttendeeInfo(BaseModel): user_id: int caption: str class Tag(BaseModel): id: int name: str color: str class TranscriptionTaskStatus(BaseModel): task_id: str status: str # 'pending', 'processing', 'completed', 'failed' progress: int # 0-100 meeting_id: int created_at: Optional[str] = None updated_at: Optional[str] = None completed_at: Optional[str] = None error_message: Optional[str] = None class Meeting(BaseModel): meeting_id: int title: str meeting_time: Optional[datetime.datetime] summary: Optional[str] created_at: datetime.datetime attendees: Union[List[str], List[AttendeeInfo]] # Support both formats creator_id: int creator_username: str audio_file_path: Optional[str] = None transcription_status: Optional[TranscriptionTaskStatus] = None tags: Optional[List[Tag]] = [] class TranscriptSegment(BaseModel): segment_id: int meeting_id: int speaker_id: Optional[int] = None # AI解析的原始结果 speaker_tag: str start_time_ms: int end_time_ms: int text_content: str class CreateMeetingRequest(BaseModel): user_id: int title: str meeting_time: Optional[datetime.datetime] attendee_ids: list[int] tags: Optional[str] = None class UpdateMeetingRequest(BaseModel): title: str meeting_time: Optional[datetime.datetime] summary: Optional[str] attendee_ids: list[int] tags: Optional[str] = None class SpeakerTagUpdateRequest(BaseModel): speaker_id: int # 使用原始speaker_id(整数) new_tag: str class BatchSpeakerTagUpdateRequest(BaseModel): updates: List[SpeakerTagUpdateRequest] class TranscriptUpdateRequest(BaseModel): segment_id: int text_content: str class BatchTranscriptUpdateRequest(BaseModel): updates: List[TranscriptUpdateRequest] class PasswordChangeRequest(BaseModel): old_password: str new_password: str class KnowledgeBase(BaseModel): kb_id: int title: str content: Optional[str] = None creator_id: int creator_caption: str # To show in the UI is_shared: bool source_meeting_ids: Optional[str] = None user_prompt: Optional[str] = None tags: Union[Optional[str], Optional[List[Tag]]] = None # 支持字符串或Tag列表 created_at: datetime.datetime updated_at: datetime.datetime source_meeting_count: Optional[int] = 0 created_by_name: Optional[str] = None class KnowledgeBaseTask(BaseModel): task_id: str user_id: int kb_id: int user_prompt: Optional[str] = None status: str progress: int error_message: Optional[str] = None created_at: datetime.datetime updated_at: datetime.datetime completed_at: Optional[datetime.datetime] = None class CreateKnowledgeBaseRequest(BaseModel): title: Optional[str] = None # 改为可选,后台自动生成 is_shared: bool user_prompt: Optional[str] = None source_meeting_ids: Optional[str] = None tags: Optional[str] = None class UpdateKnowledgeBaseRequest(BaseModel): title: str content: Optional[str] = None tags: Optional[str] = None class KnowledgeBaseListResponse(BaseModel): kbs: List[KnowledgeBase] total: int # 客户端下载相关模型 class ClientDownload(BaseModel): id: int platform_type: str # 'mobile' or 'desktop' platform_name: str # 'ios', 'android', 'windows', 'mac_intel', 'mac_m', 'linux' version: str version_code: int download_url: str file_size: Optional[int] = None release_notes: Optional[str] = None is_active: bool is_latest: bool min_system_version: Optional[str] = None created_at: datetime.datetime updated_at: datetime.datetime created_by: Optional[int] = None class CreateClientDownloadRequest(BaseModel): platform_type: str platform_name: str version: str version_code: int download_url: str file_size: Optional[int] = None release_notes: Optional[str] = None is_active: bool = True is_latest: bool = False min_system_version: Optional[str] = None class UpdateClientDownloadRequest(BaseModel): version: Optional[str] = None version_code: Optional[int] = None download_url: Optional[str] = None file_size: Optional[int] = None release_notes: Optional[str] = None is_active: Optional[bool] = None is_latest: Optional[bool] = None min_system_version: Optional[str] = None class ClientDownloadListResponse(BaseModel): clients: List[ClientDownload] total: int # 声纹采集相关模型 class VoiceprintInfo(BaseModel): vp_id: int user_id: int file_path: str file_size: Optional[int] = None duration_seconds: Optional[float] = None collected_at: datetime.datetime updated_at: datetime.datetime class VoiceprintStatus(BaseModel): has_voiceprint: bool vp_id: Optional[int] = None file_path: Optional[str] = None duration_seconds: Optional[float] = None collected_at: Optional[datetime.datetime] = None class VoiceprintTemplate(BaseModel): template_text: str duration_seconds: int sample_rate: int channels: int