from config.config_loader import ConfigModel class WebServerConfig(ConfigModel): server_name: str = "" port: int = 0 process_count: int = 1 is_ssl: bool = False is_test: bool = False client_url: str = "" nego_chat_url: str = "http://localhost:3300" agent_base_url: str = "http://localhost:9500" # 협상 agent(9500). 공용 카탈로그 변경 알림용. class LogConfig(ConfigModel): print_console: bool = True log_level: str = "debug" # DB Read/Write 분리 설정. # 하나의 논리 DB 에 대해 write(주) / read(복제) 접속 정보를 각각 가진다. class MainDBConfig(ConfigModel): db_type: str = "postgresql" name: str = "" write_host: str = "" write_port: int = 5432 write_id: str = "" write_pw: str = "" read_host: str = "" read_port: int = 5432 read_id: str = "" read_pw: str = "" show_log: bool = False # 커넥션 풀 사이징. 실제 동시 커넥션 상한 = (pool_size + max_overflow) x 엔진수(R/W=2) x 워커수. # PostgreSQL max_connections 를 넘지 않도록 설정해야 한다. (예: 10+20=30 x 2 x 5워커 = 300) pool_size: int = 10 max_overflow: int = 20 # SSL/TLS 모드: ""/"disable"=미사용(로컬), "require"/"verify-ca"/"verify-full"=관리형 DB(RDS/Aurora/Azure). sslmode: str = "" class JwtToken(ConfigModel): access_key: str = "" refresh_key: str = "" access_expire_min: int = 30 refresh_expire_day: int = 7 # 정적 파일(상품 이미지 등) 저장소 = Azure Blob Storage. # infinith 와 같은 계정/컨테이너 SAS 를 그대로 쓰고, blob_root 로 디렉터리만 분리한다. # SDK 없이 SAS 토큰을 URL 에 붙여 httpx 로 PUT 한다(services/azure_blob_client.py). class StorageConfig(ConfigModel): azure_blob_base_url: str = "" # https://.blob.core.windows.net/ azure_blob_sas_token: str = "" # SAS 토큰(쿼리스트링). 만료 있음 — 만료되면 업로드 실패 blob_root: str = "negodata" # 컨테이너 내 최상위 디렉터리(infinith 파일과 분리) max_image_mb: int = 4 # 업로드 허용 최대 크기(MB). 프론트 ImageDropzone 와 일치 # 협상 초청 메일 발송 설정. services/email.py 가 ACS → SMTP 순으로 시도한다. # 1순위: Azure Communication Services(ACS) Email — endpoint + accesskey. # azure_acs_sender 는 검증된 MailFrom 주소(예: donotreply@negodata.o2o.kr). Blob 과 별개 리소스다. # 2순위(폴백): SMTP — ACS 미설정 시 사용. 둘 다 비우면 발송 시 EmailUnavailable. class MailConfig(ConfigModel): azure_acs_endpoint: str = "" azure_acs_accesskey: str = "" azure_acs_sender: str = "" smtp_host: str = "" smtp_port: int = 587 smtp_user: str = "" smtp_password: str = "" smtp_from: str = "Negodata " smtp_starttls: bool = True @property def acs_configured(self) -> bool: return bool(self.azure_acs_endpoint and self.azure_acs_accesskey and self.azure_acs_sender)