sync: 193 file da Baida98/AI@bd00f054 (2026-08-28 06:05 UTC) [deploy-all]

#128
by Baida07 - opened
Files changed (2) hide show
  1. api/performance_rum.py +47 -0
  2. main.py +2 -0
api/performance_rum.py CHANGED
@@ -25,6 +25,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator
25
  from .auth_guard import AuthRole, require_role
26
 
27
  router = APIRouter(prefix="/api/performance", tags=["performance"])
 
28
  admin_dependency = Depends(require_role(AuthRole.ADMIN))
29
 
30
  _RELEASE_RE = re.compile(r"^[0-9a-f]{7,40}$")
@@ -189,6 +190,52 @@ async def ingest_metric(
189
  return {"accepted": True}
190
 
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  @router.get("/admin/summary", dependencies=[admin_dependency])
193
  async def performance_summary(
194
  from_time: datetime,
 
25
  from .auth_guard import AuthRole, require_role
26
 
27
  router = APIRouter(prefix="/api/performance", tags=["performance"])
28
+ debug_router = APIRouter(prefix="/api/debug", tags=["debug"])
29
  admin_dependency = Depends(require_role(AuthRole.ADMIN))
30
 
31
  _RELEASE_RE = re.compile(r"^[0-9a-f]{7,40}$")
 
190
  return {"accepted": True}
191
 
192
 
193
+ @debug_router.get("/db-check", include_in_schema=False)
194
+ async def debug_db_check(role: AuthRole = Depends(require_role(AuthRole.MACHINE))) -> dict[str, Any]:
195
+ """Temporary internal DB probe; remove after diagnosing Supabase connectivity."""
196
+ started = time.perf_counter()
197
+ try:
198
+ rows = await asyncio.to_thread(_execute, "select now() as db_now", {}, fetch=True)
199
+ elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
200
+ return {
201
+ "ok": True,
202
+ "db_now": rows[0].get("db_now") if rows else None,
203
+ "latency_ms": elapsed_ms,
204
+ "tls_required": True,
205
+ "connect_timeout_s": 5,
206
+ "statement_timeout_ms": 5000,
207
+ }
208
+ except Exception as exc:
209
+ elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
210
+ name = type(exc).__name__
211
+ lowered = name.lower()
212
+ if "timeout" in lowered or "cancel" in lowered:
213
+ category = "timeout"
214
+ elif "ssl" in lowered or "certificate" in lowered:
215
+ category = "tls"
216
+ elif "auth" in lowered or "password" in lowered:
217
+ category = "authentication"
218
+ elif "operational" in lowered or "connection" in lowered:
219
+ category = "connectivity"
220
+ else:
221
+ category = "database"
222
+ pgcode = getattr(exc, "pgcode", None)
223
+ _logger.error("RUM db probe failed type=%s category=%s elapsed_ms=%s", name, category, elapsed_ms)
224
+ return {
225
+ "ok": False,
226
+ "error_category": category,
227
+ "exception_type": name,
228
+ "sqlstate": pgcode[:5] if isinstance(pgcode, str) else None,
229
+ "latency_ms": elapsed_ms,
230
+ "tls_required": True,
231
+ "connect_timeout_s": 5,
232
+ "statement_timeout_ms": 5000,
233
+ }
234
+
235
+
236
+ extra_routers = (debug_router,)
237
+
238
+
239
  @router.get("/admin/summary", dependencies=[admin_dependency])
240
  async def performance_summary(
241
  from_time: datetime,
main.py CHANGED
@@ -189,6 +189,8 @@ for prefix, module_name in _ROUTER_MAP.items():
189
  module = importlib.import_module(f"api.{module_name}")
190
  if hasattr(module, "router"):
191
  app.include_router(module.router)
 
 
192
  _logger.info(f"✅ Route montata: /api/{prefix} (da api.{module_name})")
193
  else:
194
  _logger.warning(f"⚠️ Modulo api.{module_name} non ha un attributo 'router'")
 
189
  module = importlib.import_module(f"api.{module_name}")
190
  if hasattr(module, "router"):
191
  app.include_router(module.router)
192
+ for extra_router in getattr(module, "extra_routers", ()):
193
+ app.include_router(extra_router)
194
  _logger.info(f"✅ Route montata: /api/{prefix} (da api.{module_name})")
195
  else:
196
  _logger.warning(f"⚠️ Modulo api.{module_name} non ha un attributo 'router'")