mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 08:11:08 -05:00
Add secret management guide, client-side performance monitoring, and search accessibility enhancements
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols. - Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage. - Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
184
backend/config/settings/third_party.py
Normal file
184
backend/config/settings/third_party.py
Normal file
@@ -0,0 +1,184 @@
|
||||
"""
|
||||
Third-party application configuration for thrillwiki project.
|
||||
|
||||
This module configures third-party Django applications including:
|
||||
- django-allauth (authentication)
|
||||
- Celery (task queue)
|
||||
- Health checks
|
||||
- Tailwind CSS
|
||||
- Cloudflare Images
|
||||
- Road Trip service
|
||||
|
||||
Why python-decouple?
|
||||
- Already used in base.py for consistency
|
||||
- Simpler API than django-environ
|
||||
- Sufficient for our configuration needs
|
||||
- Better separation of config from code
|
||||
"""
|
||||
|
||||
from decouple import config
|
||||
|
||||
# =============================================================================
|
||||
# Django Allauth Configuration
|
||||
# =============================================================================
|
||||
# https://django-allauth.readthedocs.io/
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# Signup fields configuration
|
||||
# The asterisks indicate required fields
|
||||
ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"]
|
||||
|
||||
# Login methods - allow both email and username
|
||||
ACCOUNT_LOGIN_METHODS = {"email", "username"}
|
||||
|
||||
# Email verification settings
|
||||
ACCOUNT_EMAIL_VERIFICATION = config(
|
||||
"ACCOUNT_EMAIL_VERIFICATION", default="mandatory"
|
||||
)
|
||||
ACCOUNT_EMAIL_VERIFICATION_SUPPORTS_CHANGE = True
|
||||
ACCOUNT_EMAIL_VERIFICATION_SUPPORTS_RESEND = True
|
||||
|
||||
# Security settings
|
||||
ACCOUNT_REAUTHENTICATION_REQUIRED = True
|
||||
ACCOUNT_EMAIL_NOTIFICATIONS = True
|
||||
ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False
|
||||
|
||||
# Redirect URLs
|
||||
LOGIN_REDIRECT_URL = config("LOGIN_REDIRECT_URL", default="/")
|
||||
ACCOUNT_LOGOUT_REDIRECT_URL = config("ACCOUNT_LOGOUT_REDIRECT_URL", default="/")
|
||||
|
||||
# Custom adapters for extending allauth behavior
|
||||
ACCOUNT_ADAPTER = "apps.accounts.adapters.CustomAccountAdapter"
|
||||
SOCIALACCOUNT_ADAPTER = "apps.accounts.adapters.CustomSocialAccountAdapter"
|
||||
|
||||
# Social account provider settings
|
||||
SOCIALACCOUNT_PROVIDERS = {
|
||||
"google": {
|
||||
"SCOPE": [
|
||||
"profile",
|
||||
"email",
|
||||
],
|
||||
"AUTH_PARAMS": {"access_type": "online"},
|
||||
},
|
||||
"discord": {
|
||||
"SCOPE": ["identify", "email"],
|
||||
"OAUTH_PKCE_ENABLED": True,
|
||||
},
|
||||
}
|
||||
|
||||
# Additional social account settings
|
||||
SOCIALACCOUNT_LOGIN_ON_GET = True
|
||||
SOCIALACCOUNT_AUTO_SIGNUP = False
|
||||
SOCIALACCOUNT_STORE_TOKENS = True
|
||||
|
||||
# =============================================================================
|
||||
# Celery Configuration
|
||||
# =============================================================================
|
||||
# Celery task queue settings (actual Celery config is in config/celery.py)
|
||||
|
||||
CELERY_BROKER_URL = config("REDIS_URL", default="redis://localhost:6379/1")
|
||||
CELERY_RESULT_BACKEND = config("REDIS_URL", default="redis://localhost:6379/1")
|
||||
|
||||
# Task settings for test environments
|
||||
CELERY_TASK_ALWAYS_EAGER = config(
|
||||
"CELERY_TASK_ALWAYS_EAGER", default=False, cast=bool
|
||||
)
|
||||
CELERY_TASK_EAGER_PROPAGATES = config(
|
||||
"CELERY_TASK_EAGER_PROPAGATES", default=False, cast=bool
|
||||
)
|
||||
|
||||
# =============================================================================
|
||||
# Health Check Configuration
|
||||
# =============================================================================
|
||||
# https://django-health-check.readthedocs.io/
|
||||
|
||||
HEALTH_CHECK = {
|
||||
"DISK_USAGE_MAX": config("HEALTH_CHECK_DISK_USAGE_MAX", default=90, cast=int),
|
||||
"MEMORY_MIN": config("HEALTH_CHECK_MEMORY_MIN", default=100, cast=int),
|
||||
}
|
||||
|
||||
# Custom health check backends
|
||||
HEALTH_CHECK_BACKENDS = [
|
||||
"health_check.db",
|
||||
"health_check.cache",
|
||||
"health_check.storage",
|
||||
"core.health_checks.custom_checks.CacheHealthCheck",
|
||||
"core.health_checks.custom_checks.DatabasePerformanceCheck",
|
||||
"core.health_checks.custom_checks.ApplicationHealthCheck",
|
||||
"core.health_checks.custom_checks.ExternalServiceHealthCheck",
|
||||
"core.health_checks.custom_checks.DiskSpaceHealthCheck",
|
||||
]
|
||||
|
||||
# =============================================================================
|
||||
# Tailwind CSS Configuration
|
||||
# =============================================================================
|
||||
# https://django-tailwind.readthedocs.io/
|
||||
|
||||
TAILWIND_CLI_CONFIG_FILE = "tailwind.config.js"
|
||||
TAILWIND_CLI_SRC_CSS = "static/css/src/input.css"
|
||||
TAILWIND_CLI_DIST_CSS = "css/tailwind.css"
|
||||
|
||||
# =============================================================================
|
||||
# Cloudflare Images Configuration
|
||||
# =============================================================================
|
||||
# https://developers.cloudflare.com/images/
|
||||
|
||||
CLOUDFLARE_IMAGES = {
|
||||
"ACCOUNT_ID": config("CLOUDFLARE_IMAGES_ACCOUNT_ID", default=""),
|
||||
"API_TOKEN": config("CLOUDFLARE_IMAGES_API_TOKEN", default=""),
|
||||
"ACCOUNT_HASH": config("CLOUDFLARE_IMAGES_ACCOUNT_HASH", default=""),
|
||||
# Optional settings
|
||||
"DEFAULT_VARIANT": config("CLOUDFLARE_IMAGES_DEFAULT_VARIANT", default="public"),
|
||||
"UPLOAD_TIMEOUT": config("CLOUDFLARE_IMAGES_UPLOAD_TIMEOUT", default=300, cast=int),
|
||||
"WEBHOOK_SECRET": config("CLOUDFLARE_IMAGES_WEBHOOK_SECRET", default=""),
|
||||
"CLEANUP_EXPIRED_HOURS": config(
|
||||
"CLOUDFLARE_IMAGES_CLEANUP_HOURS", default=24, cast=int
|
||||
),
|
||||
"MAX_FILE_SIZE": config(
|
||||
"CLOUDFLARE_IMAGES_MAX_FILE_SIZE", default=10 * 1024 * 1024, cast=int
|
||||
),
|
||||
"ALLOWED_FORMATS": ["jpeg", "png", "gif", "webp"],
|
||||
"REQUIRE_SIGNED_URLS": config(
|
||||
"CLOUDFLARE_IMAGES_REQUIRE_SIGNED_URLS", default=False, cast=bool
|
||||
),
|
||||
"DEFAULT_METADATA": {},
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Road Trip Service Configuration
|
||||
# =============================================================================
|
||||
# Settings for the road trip planning service using OpenStreetMap
|
||||
|
||||
ROADTRIP_CACHE_TIMEOUT = config(
|
||||
"ROADTRIP_CACHE_TIMEOUT", default=3600 * 24, cast=int
|
||||
) # 24 hours for geocoding
|
||||
ROADTRIP_ROUTE_CACHE_TIMEOUT = config(
|
||||
"ROADTRIP_ROUTE_CACHE_TIMEOUT", default=3600 * 6, cast=int
|
||||
) # 6 hours for routes
|
||||
ROADTRIP_MAX_REQUESTS_PER_SECOND = config(
|
||||
"ROADTRIP_MAX_REQUESTS_PER_SECOND", default=1, cast=int
|
||||
) # Respect OSM rate limits
|
||||
ROADTRIP_USER_AGENT = config(
|
||||
"ROADTRIP_USER_AGENT", default="ThrillWiki/1.0 (https://thrillwiki.com)"
|
||||
)
|
||||
ROADTRIP_REQUEST_TIMEOUT = config(
|
||||
"ROADTRIP_REQUEST_TIMEOUT", default=10, cast=int
|
||||
) # seconds
|
||||
ROADTRIP_MAX_RETRIES = config("ROADTRIP_MAX_RETRIES", default=3, cast=int)
|
||||
ROADTRIP_BACKOFF_FACTOR = config("ROADTRIP_BACKOFF_FACTOR", default=2, cast=int)
|
||||
|
||||
# =============================================================================
|
||||
# Autocomplete Configuration
|
||||
# =============================================================================
|
||||
# django-autocomplete-light settings
|
||||
|
||||
AUTOCOMPLETE_BLOCK_UNAUTHENTICATED = config(
|
||||
"AUTOCOMPLETE_BLOCK_UNAUTHENTICATED", default=False, cast=bool
|
||||
)
|
||||
|
||||
# =============================================================================
|
||||
# Frontend Configuration
|
||||
# =============================================================================
|
||||
|
||||
FRONTEND_DOMAIN = config("FRONTEND_DOMAIN", default="https://thrillwiki.com")
|
||||
Reference in New Issue
Block a user