from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Phase 1 Pydantic Settings — reads all Phase 1 env vars from environment or .env file.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore", env_list_separator=",", ) # Data directory — used only for the flat-file settings.json path (Phase 1) data_dir: str = "/app/data" # PostgreSQL database_url: str = "postgresql+psycopg://docuvault_app:changeme_app@postgres:5432/docuvault" database_migrate_url: str = "postgresql+psycopg://docuvault_migrate:changeme_migrate@postgres:5432/docuvault" # MinIO minio_endpoint: str = "minio:9000" minio_access_key: str = "docuvault_app" minio_secret_key: str = "changeme_minio_app" minio_bucket: str = "docuvault" # Redis / Celery redis_url: str = "redis://:changeme_redis@redis:6379/0" # Security (Phase 2 — documented now, not read by Phase 1 code paths) secret_key: str = "CHANGEME" # Auth / JWT (Phase 2) access_token_expire_minutes: int = 15 refresh_token_expire_days: int = 30 # SMTP (Phase 2 — D-01) smtp_host: str = "" smtp_port: int = 587 smtp_user: str = "" smtp_password: str = "" smtp_from: str = "noreply@docuvault.local" # Admin bootstrap (Phase 2 — D-04) admin_email: str = "" admin_password: str = "" # CORS (Phase 2 — D-09) cors_origins: list[str] = ["http://localhost:5173"] settings = Settings() # SETTINGS_FILE: still flat-file in Phase 1; migrates to users.ai_provider in Phase 2 SETTINGS_FILE = Path(settings.data_dir) / "settings.json" DEFAULT_SYSTEM_PROMPT = """You are a document classification assistant. When given a document's text content and a list of existing topics, you must: 1. Assign the document to one or more relevant topics from the list. 2. If no existing topics fit well, suggest new topic names. Return ONLY valid JSON in this exact format, with no additional text or explanation: {"assigned_topics": ["topic1"], "new_topic_suggestions": ["new topic name"]} If the document fits no topics and you have no suggestions, return: {"assigned_topics": [], "new_topic_suggestions": []}""" DEFAULT_SETTINGS = { "system_prompt": DEFAULT_SYSTEM_PROMPT, "active_provider": "lmstudio", "providers": { "anthropic": { "api_key": "", "model": "claude-sonnet-4-6" }, "openai": { "api_key": "", "model": "gpt-4o", "base_url": None }, "ollama": { "base_url": "http://host.docker.internal:11434", "model": "llama3.2" }, "lmstudio": { "base_url": "http://host.docker.internal:1234", "model": "gemma-4-e4b-it" } } }