Files
Task_Reporter/app/core/config.py
egg 599802b818 feat: Add Chat UX improvements with notifications and @mention support
- Add ActionBar component with expandable toolbar for mobile
- Add @mention functionality with autocomplete dropdown
- Add browser notification system (push, sound, vibration)
- Add NotificationSettings modal for user preferences
- Add mention badges on room list cards
- Add ReportPreview with Markdown rendering and copy/download
- Add message copy functionality with hover actions
- Add backend mentions field to messages with Alembic migration
- Add lots field to rooms, remove templates
- Optimize WebSocket database session handling
- Various UX polish (animations, accessibility)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 08:20:37 +08:00

114 lines
3.6 KiB
Python

"""Application configuration loaded from environment variables"""
from pydantic_settings import BaseSettings
from pydantic import field_validator
from functools import lru_cache
from typing import List
import logging
class Settings(BaseSettings):
"""Application settings"""
# Database
DATABASE_URL: str
# Security
FERNET_KEY: str
# AD API
AD_API_URL: str
AD_API_TIMEOUT_SECONDS: int = 10 # AD API request timeout
# Session Settings
SESSION_INACTIVITY_DAYS: int = 3
TOKEN_REFRESH_THRESHOLD_MINUTES: int = 5
MAX_REFRESH_ATTEMPTS: int = 3
# Server
HOST: str = "0.0.0.0"
PORT: int = 8000
DEBUG: bool = False # Default to False for security
LOG_LEVEL: str = "INFO" # DEBUG, INFO, WARNING, ERROR
# CORS Configuration
CORS_ORIGINS: str = "http://localhost:3000" # Comma-separated list of allowed origins
# System Admin
SYSTEM_ADMIN_EMAIL: str = "" # System administrator email with special permissions
# Realtime Messaging Settings
MESSAGE_EDIT_TIME_LIMIT_MINUTES: int = 15 # Time limit for editing messages
TYPING_TIMEOUT_SECONDS: int = 3 # Typing indicator timeout
# File Upload Size Limits (in MB)
IMAGE_MAX_SIZE_MB: int = 10
DOCUMENT_MAX_SIZE_MB: int = 20
LOG_MAX_SIZE_MB: int = 5
# MinIO Object Storage
MINIO_ENDPOINT: str = "localhost:9000"
MINIO_ACCESS_KEY: str = "minioadmin"
MINIO_SECRET_KEY: str = "minioadmin"
MINIO_BUCKET: str = "task-reporter-files"
MINIO_SECURE: bool = False # Use HTTPS
# DIFY AI Service
DIFY_BASE_URL: str = "https://dify.theaken.com/v1"
DIFY_API_KEY: str = "" # Required for report generation
DIFY_TIMEOUT_SECONDS: int = 120 # AI generation can take time
# Report Generation
REPORT_MAX_MESSAGES: int = 200 # Summarize if exceeded
REPORT_STORAGE_PATH: str = "reports" # MinIO path prefix for reports
# Database Connection Pool
DB_POOL_SIZE: int = 20 # Number of persistent connections
DB_MAX_OVERFLOW: int = 30 # Max additional connections beyond pool_size
DB_POOL_TIMEOUT: int = 10 # Seconds to wait for available connection
DB_POOL_RECYCLE: int = 1800 # Recycle connections after 30 minutes
@field_validator("LOG_LEVEL")
@classmethod
def validate_log_level(cls, v: str) -> str:
"""Validate log level"""
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
v_upper = v.upper()
if v_upper not in valid_levels:
raise ValueError(f"LOG_LEVEL must be one of {valid_levels}")
return v_upper
def get_cors_origins(self) -> List[str]:
"""Parse CORS_ORIGINS into a list"""
if not self.CORS_ORIGINS:
return []
return [origin.strip() for origin in self.CORS_ORIGINS.split(",") if origin.strip()]
def get_image_max_size_bytes(self) -> int:
"""Get image max size in bytes"""
return self.IMAGE_MAX_SIZE_MB * 1024 * 1024
def get_document_max_size_bytes(self) -> int:
"""Get document max size in bytes"""
return self.DOCUMENT_MAX_SIZE_MB * 1024 * 1024
def get_log_max_size_bytes(self) -> int:
"""Get log file max size in bytes"""
return self.LOG_MAX_SIZE_MB * 1024 * 1024
def configure_logging(self) -> None:
"""Configure application logging based on LOG_LEVEL"""
logging.basicConfig(
level=getattr(logging, self.LOG_LEVEL),
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
class Config:
env_file = ".env"
case_sensitive = True
@lru_cache()
def get_settings() -> Settings:
"""Get cached settings instance"""
return Settings()