from datetime import datetime from pydantic import BaseModel, Field class HostSummary(BaseModel): id: int hostname: str display_name: str | None os_family: str os_version: str | None = None product: str product_version: str | None ipv4: str | None last_seen_at: datetime event_count: int | None = None last_heartbeat_at: datetime | None = None last_daily_report_at: datetime | None = None last_inventory_at: datetime | None = None agent_status: str = "unknown" version_status: str = "unknown" pending_agent_update: bool = False model_config = {"from_attributes": True} class HostDetail(HostSummary): agent_instance_id: str | None = None ipv6: str | None = None tags: list | None = None use_sac_mode: str | None = None inventory: dict | None = None inventory_updated_at: datetime | None = None created_at: datetime | None = None ssh_admin_ok: bool | None = None ssh_admin_checked_at: datetime | None = None pending_update_requested_at: datetime | None = None pending_update_target_version: str | None = None agent_config_revision: int = 0 agent_config: dict | None = None agent_update_state: str | None = None agent_update_last_at: datetime | None = None agent_update_last_error: str | None = None class HostListResponse(BaseModel): items: list[HostSummary] total: int page: int page_size: int latest_agent_versions: dict[str, str] = Field(default_factory=dict) reference_agent_versions: dict[str, str] = Field( default_factory=dict, description="Эталон для «устарела»: max(git latest, min, max в fleet)", ) git_latest_rdp_version: str | None = Field( None, description="Последняя версия rdp-login-monitor из git (version.txt / main)", ) git_latest_ssh_version: str | None = Field( None, description="Последняя версия ssh-monitor из git (version.txt / main)", ) class EventSummary(BaseModel): id: int event_id: str host_id: int hostname: str display_name: str | None = None product_version: str | None = None occurred_at: datetime received_at: datetime category: str type: str severity: str title: str summary: str actor_user: str | None = None rdg_flap: bool = False rdg_flap_pair_event_id: int | None = None rdg_flap_qwinsta_event_id: int | None = None rdg_access_path: str | None = None rdg_qwinsta_enabled: bool = False model_config = {"from_attributes": True} class EventDetail(EventSummary): details: dict | None = None raw: dict | None = None dedup_key: str | None = None correlation_id: str | None = None payload: dict class EventListResponse(BaseModel): items: list[EventSummary] total: int page: int page_size: int