from datetime import datetime from enum import Enum from typing import Optional from sqlmodel import SQLModel, Field, Column from sqlalchemy import JSON class MeetingStatus(str, Enum): pending = "pending" uploading = "uploading" uploaded = "uploaded" splitting = "splitting" transcribing = "transcribing" summarizing = "summarizing" done = "done" failed = "failed" class Meeting(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) title: str participants: Optional[str] = None # comma-separated object_key: Optional[str] = None # MinIO key file_size: Optional[int] = None duration: Optional[int] = None # seconds status: MeetingStatus = Field(default=MeetingStatus.pending) chunks_done: int = 0 chunks_total: int = 0 error: Optional[str] = None created_at: datetime = Field(default_factory=datetime.utcnow) updated_at: datetime = Field(default_factory=datetime.utcnow) class TranscriptSegment(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) meeting_id: int = Field(foreign_key="meeting.id", index=True) start: float # seconds end: float speaker: Optional[str] = None text: str class Summary(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) meeting_id: int = Field(foreign_key="meeting.id", unique=True, index=True) key_points: list = Field(default_factory=list, sa_column=Column(JSON)) todos: list = Field(default_factory=list, sa_column=Column(JSON)) decisions: list = Field(default_factory=list, sa_column=Column(JSON)) keywords: list = Field(default_factory=list, sa_column=Column(JSON)) preview: str = "" created_at: datetime = Field(default_factory=datetime.utcnow)