from pydantic import BaseModel, Field from typing import Any, Dict, List, Optional from enum import Enum class MelodyType(str, Enum): orthodox = "orthodox" catholic = "catholic" all = "all" class MelodyTone(str, Enum): normal = "normal" festive = "festive" cheerful = "cheerful" lamentation = "lamentation" class MelodyInfo(BaseModel): name: str = "" description: str = "" melodyTone: MelodyTone = MelodyTone.normal customTags: List[str] = [] minSpeed: int = 0 maxSpeed: int = 0 totalNotes: int = Field(default=1, ge=1, le=16) totalActiveBells: int = 0 steps: int = 0 color: str = "" isTrueRing: bool = False previewURL: str = "" archetype_csv: Optional[str] = None outdated_archetype: bool = False class MelodyAttributes(BaseModel): speed: int = 50 duration: int = 0 totalRunDuration: int = 0 pauseDuration: int = 0 infiniteLoop: bool = False echoRing: List[int] = [] noteAssignments: List[int] = [] # --- Request / Response schemas --- class MelodyCreate(BaseModel): information: MelodyInfo default_settings: MelodyAttributes type: MelodyType = MelodyType.all url: str = "" uid: str = "" pid: str = "" metadata: Optional[Dict[str, Any]] = None class MelodyUpdate(BaseModel): information: Optional[MelodyInfo] = None default_settings: Optional[MelodyAttributes] = None type: Optional[MelodyType] = None url: Optional[str] = None uid: Optional[str] = None pid: Optional[str] = None metadata: Optional[Dict[str, Any]] = None class MelodyInDB(MelodyCreate): id: str status: str = "published" class MelodyListResponse(BaseModel): melodies: List[MelodyInDB] total: int