import os from datetime import timedelta from dotenv import load_dotenv load_dotenv() class Config: # Flask SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production') DEBUG = False TESTING = False # Database MYSQL_HOST = os.getenv('MYSQL_HOST', 'localhost') MYSQL_PORT = int(os.getenv('MYSQL_PORT', 3306)) MYSQL_USER = os.getenv('MYSQL_USER', 'root') MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD', '') MYSQL_DATABASE = os.getenv('MYSQL_DATABASE', 'todo_system') SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}?charset=utf8mb4" SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = False # Database Connection Pool Settings SQLALCHEMY_ENGINE_OPTIONS = { 'pool_pre_ping': True, # 每次使用前檢查連接 'pool_recycle': 300, # 5分鐘回收連接 'pool_timeout': 20, # 連接超時 20 秒 'max_overflow': 10, # 最大溢出連接數 'pool_size': 5, # 連接池大小 'connect_args': { 'connect_timeout': 10, # MySQL 連接超時 'read_timeout': 30, # MySQL 讀取超時 'write_timeout': 30, # MySQL 寫入超時 'charset': 'utf8mb4' } } # JWT JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY', SECRET_KEY) JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=int(os.getenv('JWT_ACCESS_TOKEN_EXPIRES_HOURS', 8))) JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=int(os.getenv('JWT_REFRESH_TOKEN_EXPIRES_DAYS', 30))) JWT_ALGORITHM = 'HS256' # LDAP/AD LDAP_SERVER = os.getenv('LDAP_SERVER', 'ldap://dc.company.com') LDAP_PORT = int(os.getenv('LDAP_PORT', 389)) LDAP_USE_SSL = os.getenv('LDAP_USE_SSL', 'false').lower() == 'true' LDAP_USE_TLS = os.getenv('LDAP_USE_TLS', 'false').lower() == 'true' LDAP_SEARCH_BASE = os.getenv('LDAP_SEARCH_BASE', 'DC=company,DC=com') LDAP_BIND_USER_DN = os.getenv('LDAP_BIND_USER_DN', '') LDAP_BIND_USER_PASSWORD = os.getenv('LDAP_BIND_USER_PASSWORD', '') LDAP_USER_LOGIN_ATTR = os.getenv('LDAP_USER_LOGIN_ATTR', 'userPrincipalName') # SMTP Email SMTP_SERVER = os.getenv('SMTP_SERVER', 'smtp.company.com') SMTP_PORT = int(os.getenv('SMTP_PORT', 25)) SMTP_USE_TLS = os.getenv('SMTP_USE_TLS', 'false').lower() == 'true' SMTP_USE_SSL = os.getenv('SMTP_USE_SSL', 'false').lower() == 'true' SMTP_AUTH_REQUIRED = os.getenv('SMTP_AUTH_REQUIRED', 'false').lower() == 'true' SMTP_SENDER_EMAIL = os.getenv('SMTP_SENDER_EMAIL', 'todo-system@company.com') SMTP_SENDER_PASSWORD = os.getenv('SMTP_SENDER_PASSWORD', '') # Mail Settings MAIL_SERVER = SMTP_SERVER MAIL_PORT = SMTP_PORT MAIL_USE_TLS = SMTP_USE_TLS MAIL_USE_SSL = SMTP_USE_SSL MAIL_USERNAME = SMTP_SENDER_EMAIL if SMTP_AUTH_REQUIRED else None MAIL_PASSWORD = SMTP_SENDER_PASSWORD if SMTP_AUTH_REQUIRED else None MAIL_DEFAULT_SENDER = SMTP_SENDER_EMAIL # Fire Email Limits FIRE_EMAIL_COOLDOWN_MINUTES = int(os.getenv('FIRE_EMAIL_COOLDOWN_MINUTES', 2)) FIRE_EMAIL_DAILY_LIMIT = int(os.getenv('FIRE_EMAIL_DAILY_LIMIT', 20)) # Scheduled Reminders REMINDER_DAYS_BEFORE = int(os.getenv('REMINDER_DAYS_BEFORE', 3)) REMINDER_DAYS_AFTER = int(os.getenv('REMINDER_DAYS_AFTER', 1)) WEEKLY_SUMMARY_DAY = int(os.getenv('WEEKLY_SUMMARY_DAY', 0)) # 0=Monday WEEKLY_SUMMARY_HOUR = int(os.getenv('WEEKLY_SUMMARY_HOUR', 9)) # File Upload MAX_CONTENT_LENGTH = int(os.getenv('MAX_CONTENT_LENGTH', 16)) * 1024 * 1024 # MB UPLOAD_FOLDER = os.getenv('UPLOAD_FOLDER', 'uploads') ALLOWED_EXTENSIONS = {'xlsx', 'xls', 'csv'} # Pagination ITEMS_PER_PAGE = int(os.getenv('ITEMS_PER_PAGE', 20)) # Redis (for caching and celery) REDIS_URL = os.getenv('REDIS_URL', 'redis://localhost:6379/0') # Celery CELERY_BROKER_URL = REDIS_URL CELERY_RESULT_BACKEND = REDIS_URL # CORS CORS_ORIGINS = os.getenv('CORS_ORIGINS', 'http://localhost:3000').split(',') # Logging LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO') LOG_FILE = os.getenv('LOG_FILE', 'logs/app.log') class DevelopmentConfig(Config): DEBUG = True SQLALCHEMY_ECHO = True # 開發模式可使用Mock LDAP USE_MOCK_LDAP = os.getenv('USE_MOCK_LDAP', 'true').lower() == 'true' class ProductionConfig(Config): DEBUG = False TESTING = False class TestingConfig(Config): TESTING = True SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' SQLALCHEMY_TRACK_MODIFICATIONS = False # 禁用外部服務 CELERY_TASK_ALWAYS_EAGER = True CELERY_TASK_EAGER_PROPAGATES = True # 測試用的簡化設定 JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1) FIRE_EMAIL_COOLDOWN_MINUTES = 2 FIRE_EMAIL_DAILY_LIMIT = 3 # 禁用郵件發送 MAIL_SUPPRESS_SEND = True config = { 'development': DevelopmentConfig, 'production': ProductionConfig, 'testing': TestingConfig, 'default': DevelopmentConfig }