""" Recording API - Pydantic Models & Configuration. Data models for recording, transcription, and webhook endpoints. """ import os from datetime import datetime from typing import Optional, List from pydantic import BaseModel, Field # ========================================== # ENVIRONMENT CONFIGURATION # ========================================== MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT", "minio:9000") MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY", "breakpilot") MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY", "breakpilot123") MINIO_BUCKET = os.getenv("MINIO_BUCKET", "breakpilot-recordings") MINIO_SECURE = os.getenv("MINIO_SECURE", "false").lower() == "true" # Default retention period in days (DSGVO compliance) DEFAULT_RETENTION_DAYS = int(os.getenv("RECORDING_RETENTION_DAYS", "365")) # ========================================== # PYDANTIC MODELS # ========================================== class JibriWebhookPayload(BaseModel): """Webhook payload from Jibri finalize.sh script.""" event: str = Field(..., description="Event type: recording_completed") recording_name: str = Field(..., description="Unique recording identifier") storage_path: str = Field(..., description="Path in MinIO bucket") audio_path: Optional[str] = Field(None, description="Extracted audio path") file_size_bytes: int = Field(..., description="Video file size in bytes") timestamp: str = Field(..., description="ISO timestamp of upload") class RecordingCreate(BaseModel): """Manual recording creation (for testing).""" meeting_id: str title: Optional[str] = None storage_path: str audio_path: Optional[str] = None duration_seconds: Optional[int] = None participant_count: Optional[int] = 0 retention_days: Optional[int] = DEFAULT_RETENTION_DAYS class RecordingResponse(BaseModel): """Recording details response.""" id: str meeting_id: str title: Optional[str] storage_path: str audio_path: Optional[str] file_size_bytes: Optional[int] duration_seconds: Optional[int] participant_count: int status: str recorded_at: datetime retention_days: int retention_expires_at: datetime transcription_status: Optional[str] = None transcription_id: Optional[str] = None class RecordingListResponse(BaseModel): """Paginated list of recordings.""" recordings: List[RecordingResponse] total: int page: int page_size: int class TranscriptionRequest(BaseModel): """Request to start transcription.""" language: str = Field(default="de", description="Language code: de, en, etc.") model: str = Field(default="large-v3", description="Whisper model to use") priority: int = Field(default=0, description="Queue priority (higher = sooner)") class TranscriptionStatusResponse(BaseModel): """Transcription status and progress.""" id: str recording_id: str status: str language: str model: str word_count: Optional[int] confidence_score: Optional[float] processing_duration_seconds: Optional[int] error_message: Optional[str] created_at: datetime completed_at: Optional[datetime]