import uuid from datetime import datetime from typing import Any from pydantic import ConfigDict, Field from common.enums import LocalContentStatus, LocalContentType, LocalSource from common.models.gmodel import Res_WebPacketProtocol, WebPacketProtocol class LocalContentData(WebPacketProtocol): model_config = ConfigDict(from_attributes=True) local_content_id: uuid.UUID region_code: str content_type: LocalContentType source: LocalSource external_id: str | None = None title: str | None = None body: dict[str, Any] status: LocalContentStatus collected_at: datetime | None = None published_at: datetime | None = None display_start_at: datetime | None = None display_end_at: datetime | None = None class PlaceContentData(WebPacketProtocol): """업장 반경 주변정보 1건(admin 목록용).""" model_config = ConfigDict(from_attributes=True) place_content_id: uuid.UUID place_id: uuid.UUID content_type: LocalContentType external_id: str title: str body: dict[str, Any] distance_m: int has_image: bool hidden: bool display_end_at: datetime | None = None collected_at: datetime | None = None class ResPlaceContentList(Res_WebPacketProtocol): contents: list[PlaceContentData] = [] class ReqHidePlaceContent(WebPacketProtocol): hidden: bool class ReqPublishLocalContent(WebPacketProtocol): content_ids: list[uuid.UUID] = Field(min_length=1, max_length=100) class ReqUpdateLocalContent(WebPacketProtocol): title: str | None = Field(default=None, min_length=1, max_length=300) body: dict[str, Any] | None = None display_start_at: datetime | None = None display_end_at: datetime | None = None class ResLocalContentList(Res_WebPacketProtocol): contents: list[LocalContentData] = [] class ResSyncPlace(Res_WebPacketProtocol): """업장 반경 동기화 결과 — 종류별로 **남긴** 건수(반경·기간 필터 뒤).""" festivals: int = 0 attractions: int = 0 restaurants: int = 0 courses: int = 0 changed: bool = False class ResLocalGuide(Res_WebPacketProtocol): """에디터 캔버스가 그리는 지역 가이드.""" attractions: list[dict[str, Any]] = [] restaurants: list[dict[str, Any]] = [] festivals: list[dict[str, Any]] = [] courses: list[dict[str, Any]] = [] # 1박2일·2박3일 각 5개(services/itinerary_llm_service). itineraries: list[dict[str, Any]] = [] synced_at: str | None = None class WeatherData(WebPacketProtocol): temperature: float weather_code: int wind_speed: float | None = None observed_at: str timezone: str | None = None latitude: float longitude: float class ResWeather(Res_WebPacketProtocol): weather: WeatherData | None = None cached: bool = False stale: bool = False