# backend/app/config.py from functools import lru_cache from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore") database_url: str = "sqlite:///./ari.db" # LLM — 절대 특정 모델을 하드코딩하지 않는다. 설치된 모델을 env로 주입. ollama_host: str = "http://localhost:11434" ollama_model: str = "llama3.1" # 기본 placeholder. 실제 운영은 .env 로 덮어쓴다. llm_provider: str = "ollama" # 실 LLM 전용(휴리스틱 폴백 제거, phase-16+) llm_timeout: float = 20.0 # 초 # 리스크 계산 기준일 — CONTRACT: TODAY=8 (6/8). 시드가 '6/7~6/12 한 주' 가정. risk_today: int = 8 # CORS 허용 출처(콤마구분). 단일 환경변수 규약: FRONTEND_ORIGIN. # 개발 포트는 흔한 dev 포트와 충돌을 피해 31xxx 대역 사용(프론트 31300). frontend_origin: str = "http://localhost:31300" # 테스트 리셋 게이트 (테스트 환경에서만 시드 리셋 허용) ari_allow_test_reset: bool = False # ---- 포스트-MVP 커넥터 (CONNECTOR_=mock|real, 기본 mock) ---- connector_calendar: str = "mock" # phase-8/13 connector_mail: str = "mock" # phase-9/13 # ---- phase-13: 외부 연동 토큰 암호화 + OAuth 자격증명 + 동기화 정책 ---- # 토큰 암호화 키(real 켤 때 필수). Fernet 키 파생용. ari_secret_key: str = "dev-insecure-change-me-please-32bytes!" # OAuth2 자격증명(제공자별). 비어 있으면 해당 RealConnector 비활성. google_client_id: str = "" # Gmail + Google Calendar 공용 google_client_secret: str = "" google_redirect_uri: str = "http://localhost:31800/api/connectors/oauth/callback" # Microsoft(Outlook/Graph) — 개인+조직 공용 tenant 기본 "common". microsoft_client_id: str = "" microsoft_client_secret: str = "" microsoft_tenant: str = "common" notion_client_id: str = "" notion_client_secret: str = "" readwise_token: str = "" # Readwise 는 단순 토큰(OAuth 아님) # google/microsoft 공용 단일 콜백(state 로 provider 식별). 양쪽 콘솔에 동일 URI 등록. oauth_redirect_uri: str = "http://localhost:31800/api/connectors/oauth/callback" # 동기화 정책 sync_interval_minutes: int = 15 # worker 주기 sync sync_page_size: int = 50 sync_max_messages: int = 500 # 초기/전체 sync 시 1계정 최대 수집 건수(페이지네이션 상한) connector_http_timeout: float = 20.0 # 앱 내장 자동 풀링(메일·일정): uvicorn lifespan 의 백그라운드 루프가 주기적으로 # 연결된 real 계정을 증분 sync 한다(별도 워커 프로세스 불필요). auto_sync_enabled: bool = True # AUTO_SYNC_ENABLED auto_sync_interval_seconds: int = 10 # AUTO_SYNC_INTERVAL_SECONDS (기본 10초) # ---- phase-15: 인증/멀티유저 + 관측 + 운영 ---- auth_enabled: bool = False # AUTH_ENABLED 기본 off(데모 무손상) session_secret: str = "dev-insecure-session-secret-change-me" # 세션 쿠키 서명 session_cookie_name: str = "ari_session" session_ttl_s: int = 1209600 # 14일 cookie_secure: bool = False # prod=true (HTTPS 전용) ari_env: str = "dev" # prod 이면 기본 비밀 거부 log_level: str = "INFO" ollama_max_concurrency: int = 2 ollama_timeout_s: float = 12.0 demo_admin_email: str = "jiwoo@lumi.co" demo_admin_password: str = "demo-1234" # ---- phase-14: 멀티모달 캡처 + 능동 워커 ---- stt_provider: str = "auto" # STT_PROVIDER auto|ollama|heuristic stt_model: str = "whisper" # STT_MODEL (모델 비종속, 주입) vision_provider: str = "auto" # VISION_PROVIDER auto|ollama|heuristic vision_model: str = "llava" # VISION_MODEL (placeholder, 주입) worker_enabled: bool = False # WORKER_ENABLED 스케줄러 on/off(기본 수동 트리거) @lru_cache def get_settings() -> Settings: return Settings()