from pydantic import BaseModel, Field, field_validator from typing import Optional, List from uuid import UUID from datetime import datetime VALID_TYPES = {"note", "issue"} VALID_STATUSES = {"open", "researching", "resolved"} VALID_SEVERITIES = {"low", "medium", "high", "critical"} VALID_CATEGORIES = {"technical", "install_support", "general"} VALID_ENTITIES = {"device", "app_user", "customer"} class EntryLinkIn(BaseModel): entity_type: str entity_id: str @field_validator("entity_type") @classmethod def check_entity_type(cls, v): if v not in VALID_ENTITIES: raise ValueError(f"entity_type must be one of {VALID_ENTITIES}") return v class EntryCreate(BaseModel): type: str title: str = Field(..., max_length=500) body: Optional[str] = None status: Optional[str] = None severity: Optional[str] = None category: Optional[str] = None links: List[EntryLinkIn] = [] @field_validator("type") @classmethod def check_type(cls, v): if v not in VALID_TYPES: raise ValueError(f"type must be one of {VALID_TYPES}") return v @field_validator("status") @classmethod def check_status(cls, v): if v is not None and v not in VALID_STATUSES: raise ValueError(f"status must be one of {VALID_STATUSES}") return v @field_validator("severity") @classmethod def check_severity(cls, v): if v is not None and v not in VALID_SEVERITIES: raise ValueError(f"severity must be one of {VALID_SEVERITIES}") return v @field_validator("category") @classmethod def check_category(cls, v): if v is not None and v not in VALID_CATEGORIES: raise ValueError(f"category must be one of {VALID_CATEGORIES}") return v class EntryUpdate(BaseModel): title: Optional[str] = Field(None, max_length=500) body: Optional[str] = None status: Optional[str] = None severity: Optional[str] = None category: Optional[str] = None class EntryLinkOut(BaseModel): id: UUID entity_type: str entity_id: str model_config = {"from_attributes": True} class EntryOut(BaseModel): id: UUID type: str title: str body: Optional[str] status: Optional[str] severity: Optional[str] category: Optional[str] author_id: str author_name: Optional[str] created_at: datetime updated_at: datetime links: List[EntryLinkOut] = [] model_config = {"from_attributes": True} class EntryListResponse(BaseModel): data: List[EntryOut] pagination: dict class LinksReplaceIn(BaseModel): links: List[EntryLinkIn]