Removed VueJS frontend and dramatically enhanced API

This commit is contained in:
pacnpal
2025-08-28 14:01:28 -04:00
parent 08a4a2d034
commit 715e284b3e
123 changed files with 4056 additions and 26546 deletions

View File

@@ -7,9 +7,11 @@ including view tracking and other core functionality.
from .view_tracking import ViewTrackingMiddleware, get_view_stats_for_content
from .analytics import PgHistoryContextMiddleware
from .nextjs import APIResponseMiddleware
__all__ = [
"ViewTrackingMiddleware",
"get_view_stats_for_content",
"PgHistoryContextMiddleware",
"APIResponseMiddleware",
]

View File

@@ -38,5 +38,8 @@ class PgHistoryContextMiddleware:
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
# Set the pghistory context with request information
context_data = request_context(request)
with pghistory.context(**context_data):
response = self.get_response(request)
return response

View File

@@ -0,0 +1,48 @@
# backend/apps/core/middleware.py
from django.utils.deprecation import MiddlewareMixin
class APIResponseMiddleware(MiddlewareMixin):
"""
Middleware to ensure consistent API responses for Next.js
"""
def process_response(self, request, response):
# Only process API requests
if not request.path.startswith("/api/"):
return response
# Ensure CORS headers are set
if not response.has_header("Access-Control-Allow-Origin"):
origin = request.META.get("HTTP_ORIGIN")
# Allow localhost/127.0.0.1 (any port) and IPv6 loopback for development
if origin:
import re
# support http or https, IPv4 and IPv6 loopback, any port
localhost_pattern = r"^https?://(localhost|127\.0\.0\.1|\[::1\]):\d+"
if re.match(localhost_pattern, origin):
response["Access-Control-Allow-Origin"] = origin
# Ensure caches vary by Origin
existing_vary = response.get("Vary")
if existing_vary:
response["Vary"] = f"{existing_vary}, Origin"
else:
response["Vary"] = "Origin"
# Helpful dev CORS headers (adjust for your frontend requests)
response["Access-Control-Allow-Methods"] = (
"GET, POST, PUT, PATCH, DELETE, OPTIONS"
)
response["Access-Control-Allow-Headers"] = (
"Authorization, Content-Type, X-Requested-With"
)
# Uncomment if your dev frontend needs to send cookies/auth credentials
# response['Access-Control-Allow-Credentials'] = 'true'
else:
response["Access-Control-Allow-Origin"] = "null"
return response

View File

@@ -21,7 +21,6 @@ class PerformanceMiddleware(MiddlewareMixin):
request._performance_initial_queries = (
len(connection.queries) if hasattr(connection, "queries") else 0
)
return None
def process_response(self, request, response):
"""Log performance metrics after response is ready"""
@@ -158,7 +157,7 @@ class PerformanceMiddleware(MiddlewareMixin):
extra=performance_data,
)
return None # Don't handle the exception, just log it
# Don't return anything - let the exception propagate normally
def _get_client_ip(self, request):
"""Extract client IP address from request"""
@@ -201,7 +200,6 @@ class QueryCountMiddleware(MiddlewareMixin):
request._query_count_start = (
len(connection.queries) if hasattr(connection, "queries") else 0
)
return None
def process_response(self, request, response):
"""Check query count and warn if excessive"""
@@ -253,8 +251,6 @@ class DatabaseConnectionMiddleware(MiddlewareMixin):
)
# Don't block the request, let Django handle the database error
return None
def process_response(self, request, response):
"""Close database connections properly"""
try:
@@ -275,7 +271,6 @@ class CachePerformanceMiddleware(MiddlewareMixin):
request._cache_hits = 0
request._cache_misses = 0
request._cache_start_time = time.time()
return None
def process_response(self, request, response):
"""Log cache performance metrics"""

View File

@@ -280,8 +280,11 @@ class CacheMonitor:
stats = {}
try:
# Redis cache stats
if hasattr(self.cache_service.default_cache, "_cache"):
# Try to get Redis cache stats
cache_backend = self.cache_service.default_cache.__class__.__name__
if "Redis" in cache_backend:
# Attempt to get Redis client and stats
redis_client = self.cache_service.default_cache._cache.get_client()
info = redis_client.info()
stats["redis"] = {
@@ -297,8 +300,16 @@ class CacheMonitor:
misses = info.get("keyspace_misses", 0)
if hits + misses > 0:
stats["redis"]["hit_rate"] = hits / (hits + misses) * 100
else:
# For local memory cache or other backends
stats["cache_backend"] = cache_backend
stats["message"] = f"Cache statistics not available for {cache_backend}"
except Exception as e:
logger.error(f"Error getting cache stats: {e}")
# Don't log as error since this is expected for non-Redis backends
cache_backend = self.cache_service.default_cache.__class__.__name__
stats["cache_backend"] = cache_backend
stats["message"] = f"Cache statistics not available for {cache_backend}"
return stats