kanban-app/backend/app/config.py

166 lines
5.5 KiB
Python
Raw Normal View History

import os
from datetime import timedelta
class Config:
"""Base configuration"""
2026-02-24 16:19:15 +00:00
SECRET_KEY = os.environ.get("SECRET_KEY") or "dev-secret-key-change-in-production"
SQLALCHEMY_TRACK_MODIFICATIONS = False
2026-02-24 14:36:31 +00:00
JWT_SECRET_KEY = os.environ["JWT_SECRET_KEY"]
JWT_ACCESS_TOKEN_EXPIRES = timedelta(days=1)
JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30)
CORS_ORIGINS = os.environ.get("CORS_ORIGINS", "*")
2026-02-24 16:19:15 +00:00
2026-02-21 18:38:19 +00:00
# Celery Configuration
CELERY = {
"broker_url": os.environ.get("CELERY_BROKER_URL", "redis://redis:6379/0"),
2026-02-24 16:19:15 +00:00
"result_backend": os.environ.get(
"CELERY_RESULT_BACKEND", "redis://redis:6379/0"
),
2026-02-21 18:38:19 +00:00
"task_serializer": "json",
"result_serializer": "json",
"accept_content": ["json"],
"timezone": "UTC",
"enable_utc": True,
"task_track_started": True,
"task_time_limit": 30 * 60, # 30 minutes
"task_soft_time_limit": 25 * 60, # 25 minutes
"worker_prefetch_multiplier": 1,
"worker_max_tasks_per_child": 100,
"broker_connection_retry_on_startup": True,
}
2026-02-25 18:32:57 +00:00
2026-02-25 16:48:18 +00:00
SQLALCHEMY_ENGINE_OPTIONS = {
2026-02-25 18:32:57 +00:00
"pool_size": 20, # Reduce from default
"max_overflow": 10, # Reduce overflow
"pool_timeout": 30,
"pool_recycle": 1800, # Recycle connections after 30 minutes
"pool_pre_ping": True, # Verify connections before using
2026-02-25 16:48:18 +00:00
}
2026-03-22 11:52:33 +00:00
# MinIO Configuration
MINIO_ENDPOINT = os.environ.get("MINIO_ENDPOINT", "minio:9000")
MINIO_ACCESS_KEY = os.environ.get("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.environ.get("MINIO_SECRET_KEY", "minioadmin")
MINIO_REGION = os.environ.get("MINIO_REGION", "garage")
MINIO_USE_SSL = os.environ.get("MINIO_USE_SSL", "true").lower() == "true"
# MinIO Buckets
MINIO_IMAGES_BUCKET = "kanban-images"
MINIO_DOCUMENTS_BUCKET = "kanban-documents"
MINIO_THUMBNAILS_BUCKET = "kanban-thumbnails"
class DevelopmentConfig(Config):
"""Development configuration"""
2026-02-24 16:19:15 +00:00
DEBUG = True
2026-02-25 16:48:18 +00:00
SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
2026-03-20 17:17:01 +00:00
# MinIO Configuration for Development
MINIO_ENDPOINT = os.environ.get("MINIO_ENDPOINT", "minio:9000")
MINIO_ACCESS_KEY = os.environ.get("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.environ.get("MINIO_SECRET_KEY", "minioadmin")
MINIO_USE_SSL = os.environ.get("MINIO_USE_SSL", "false").lower() == "true"
MINIO_IMAGES_BUCKET = "kanban-images"
MINIO_DOCUMENTS_BUCKET = "kanban-documents"
MINIO_THUMBNAILS_BUCKET = "kanban-thumbnails"
MAX_UPLOAD_SIZE_IMAGE = 10 * 1024 * 1024
MAX_UPLOAD_SIZE_DOCUMENT = 50 * 1024 * 1024
ALLOWED_IMAGE_TYPES = [
"image/jpeg",
"image/png",
"image/gif",
"image/svg+xml",
"image/webp",
]
ALLOWED_DOCUMENT_TYPES = ["application/pdf"]
class TestingConfig(Config):
"""Testing configuration"""
2026-02-24 16:19:15 +00:00
TESTING = True
2026-03-20 17:17:01 +00:00
USE_MOCK_STORAGE = True # Use in-memory mock storage for tests
2026-03-15 12:52:44 +00:00
SQLALCHEMY_DATABASE_URI = os.environ.get("TEST_DATABASE_URL")
WTF_CSRF_ENABLED = False
2026-02-25 18:32:57 +00:00
# Conservative connection pool settings for testing
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_size": 1, # Only one connection in the pool
2026-02-27 20:26:25 +00:00
"max_overflow": 0, # No overflow connections allowed
2026-02-25 18:32:57 +00:00
"pool_timeout": 30,
"pool_recycle": 3600, # Recycle after 1 hour
"pool_pre_ping": True, # Verify connections before using
}
2026-03-20 17:17:01 +00:00
# MinIO configuration (not used in tests due to USE_MOCK_STORAGE=True)
MINIO_ENDPOINT = "minio:9000"
MINIO_ACCESS_KEY = os.environ.get("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.environ.get("MINIO_SECRET_KEY", "minioadmin")
MINIO_USE_SSL = os.environ.get("MINIO_USE_SSL", "false").lower() == "true"
# Bucket names (required for FileService even with mock storage)
MINIO_IMAGES_BUCKET = "kanban-images"
MINIO_DOCUMENTS_BUCKET = "kanban-documents"
MINIO_THUMBNAILS_BUCKET = "kanban-thumbnails"
# File upload limits
MAX_UPLOAD_SIZE_IMAGE = 10 * 1024 * 1024 # 10MB
MAX_UPLOAD_SIZE_DOCUMENT = 50 * 1024 * 1024 # 50MB
# Allowed file types
ALLOWED_IMAGE_TYPES = [
"image/jpeg",
"image/png",
"image/gif",
"image/svg+xml",
"image/webp",
]
ALLOWED_DOCUMENT_TYPES = ["application/pdf"]
class ProductionConfig(Config):
"""Production configuration"""
2026-02-24 16:19:15 +00:00
DEBUG = False
2026-02-25 16:48:18 +00:00
SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
2026-02-24 16:19:15 +00:00
# Security headers
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
2026-03-20 17:17:01 +00:00
# MinIO Configuration
MINIO_ENDPOINT = os.environ.get("MINIO_ENDPOINT", "minio:9000")
MINIO_ACCESS_KEY = os.environ.get("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY = os.environ.get("MINIO_SECRET_KEY", "minioadmin")
MINIO_USE_SSL = os.environ.get("MINIO_USE_SSL", "true").lower() == "true"
# MinIO Buckets
MINIO_IMAGES_BUCKET = "kanban-images"
MINIO_DOCUMENTS_BUCKET = "kanban-documents"
MINIO_THUMBNAILS_BUCKET = "kanban-thumbnails"
# File Upload Limits (in bytes)
MAX_UPLOAD_SIZE_IMAGE = 10 * 1024 * 1024 # 10MB
MAX_UPLOAD_SIZE_DOCUMENT = 50 * 1024 * 1024 # 50MB
# Allowed File Types
ALLOWED_IMAGE_TYPES = [
"image/jpeg",
"image/png",
"image/gif",
"image/svg+xml",
"image/webp",
]
ALLOWED_DOCUMENT_TYPES = ["application/pdf"]
config_by_name = {
"dev": DevelopmentConfig,
"test": TestingConfig,
2026-02-24 16:19:15 +00:00
"prod": ProductionConfig,
}