feat: add dark mode, navigation, and Web Vitals tracking to marketplace
Backend: - Simplify DatabaseConfig: remove effective_url property and project root finder - Update to Pydantic v2 model_config (replace nested Config class) - Add web_vitals router to main.py and __init__.py - Fix ExplorerService datetime handling (ensure timezone-naive comparisons) - Fix status_label extraction to handle both enum and string job states Frontend (Marketplace): - Add dark mode toggle with system preference detection
This commit is contained in:
@@ -11,6 +11,7 @@ from .users import router as users
|
||||
from .exchange import router as exchange
|
||||
from .marketplace_offers import router as marketplace_offers
|
||||
from .payments import router as payments
|
||||
from .web_vitals import router as web_vitals
|
||||
# from .registry import router as registry
|
||||
|
||||
__all__ = ["client", "miner", "admin", "marketplace", "marketplace_gpu", "explorer", "services", "users", "exchange", "marketplace_offers", "payments", "registry"]
|
||||
__all__ = ["client", "miner", "admin", "marketplace", "marketplace_gpu", "explorer", "services", "users", "exchange", "marketplace_offers", "payments", "web_vitals", "registry"]
|
||||
|
||||
53
apps/coordinator-api/src/app/routers/web_vitals.py
Normal file
53
apps/coordinator-api/src/app/routers/web_vitals.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Web Vitals API endpoint for collecting performance metrics
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict, Any, Optional
|
||||
import logging
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
class WebVitalsEntry(BaseModel):
|
||||
name: str
|
||||
startTime: Optional[float] = None
|
||||
duration: Optional[float] = None
|
||||
|
||||
class WebVitalsMetric(BaseModel):
|
||||
name: str
|
||||
value: float
|
||||
id: str
|
||||
delta: Optional[float] = None
|
||||
entries: List[WebVitalsEntry] = []
|
||||
url: Optional[str] = None
|
||||
timestamp: Optional[str] = None
|
||||
|
||||
@router.post("/web-vitals")
|
||||
async def collect_web_vitals(metric: WebVitalsMetric):
|
||||
"""
|
||||
Collect Web Vitals performance metrics from the frontend.
|
||||
This endpoint receives Core Web Vitals (LCP, FID, CLS, TTFB, FCP) for monitoring.
|
||||
"""
|
||||
try:
|
||||
# Log the metric for monitoring/analysis
|
||||
logging.info(f"Web Vitals - {metric.name}: {metric.value}ms (ID: {metric.id}) from {metric.url or 'unknown'}")
|
||||
|
||||
# In a production setup, you might:
|
||||
# - Store in database for trend analysis
|
||||
# - Send to monitoring service (DataDog, New Relic, etc.)
|
||||
# - Trigger alerts for poor performance
|
||||
|
||||
# For now, just acknowledge receipt
|
||||
return {"status": "received", "metric": metric.name, "value": metric.value}
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error processing web vitals metric: {e}")
|
||||
raise HTTPException(status_code=500, detail="Failed to process metric")
|
||||
|
||||
# Health check for web vitals endpoint
|
||||
@router.get("/web-vitals/health")
|
||||
async def web_vitals_health():
|
||||
"""Health check for web vitals collection endpoint"""
|
||||
return {"status": "healthy", "service": "web-vitals"}
|
||||
Reference in New Issue
Block a user