Add auth profile timing instrumentation
This commit is contained in:
+9
-3
@@ -1,6 +1,6 @@
|
||||
"""Authentication API routes."""
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import APIRouter, Request, Response
|
||||
|
||||
from web.core import ReferralApplyRequest, TelegramBindTokenRequest, TelegramLoginRequest
|
||||
from web.services.auth_api import (
|
||||
@@ -15,8 +15,14 @@ router = APIRouter(tags=["auth"])
|
||||
|
||||
|
||||
@router.get("/api/auth/me")
|
||||
async def auth_me(request: Request):
|
||||
return get_auth_me_payload(request)
|
||||
async def auth_me(request: Request, response: Response):
|
||||
payload = get_auth_me_payload(request)
|
||||
server_timing = str(
|
||||
getattr(request.state, "auth_me_server_timing", "") or ""
|
||||
).strip()
|
||||
if server_timing:
|
||||
response.headers["Server-Timing"] = server_timing
|
||||
return payload
|
||||
|
||||
|
||||
@router.post("/api/auth/telegram/login")
|
||||
|
||||
+310
-171
@@ -2,9 +2,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict
|
||||
import time
|
||||
from typing import Any, Callable, Dict, Optional, TypeVar
|
||||
|
||||
from fastapi import HTTPException, Request
|
||||
from loguru import logger
|
||||
|
||||
from src.auth.telegram_group_pricing import TelegramGroupPricing
|
||||
from src.database.db_manager import DBManager
|
||||
@@ -12,6 +14,70 @@ from web.core import ReferralApplyRequest, TelegramLoginRequest
|
||||
import web.routes as legacy_routes
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class _AuthMeTimer:
|
||||
def __init__(self, request: Request):
|
||||
self.request = request
|
||||
self.started = time.perf_counter()
|
||||
self.timings_ms: Dict[str, float] = {}
|
||||
|
||||
def measure(self, stage: str, action: Callable[[], T]) -> T:
|
||||
started = time.perf_counter()
|
||||
try:
|
||||
return action()
|
||||
finally:
|
||||
self.timings_ms[stage] = round(
|
||||
(time.perf_counter() - started) * 1000.0,
|
||||
1,
|
||||
)
|
||||
|
||||
def finish(
|
||||
self,
|
||||
*,
|
||||
authenticated: Optional[bool],
|
||||
outcome: str,
|
||||
status_code: int,
|
||||
subscription_active: Optional[bool],
|
||||
) -> None:
|
||||
self.timings_ms["total"] = round(
|
||||
(time.perf_counter() - self.started) * 1000.0,
|
||||
1,
|
||||
)
|
||||
server_timing = ", ".join(
|
||||
f"backend_{stage};dur={max(0.0, duration):.1f}"
|
||||
for stage, duration in self.timings_ms.items()
|
||||
)
|
||||
self.request.state.auth_me_server_timing = server_timing
|
||||
_log_auth_me_timing(
|
||||
authenticated=authenticated,
|
||||
outcome=outcome,
|
||||
status_code=status_code,
|
||||
subscription_active=subscription_active,
|
||||
timings_ms=self.timings_ms,
|
||||
)
|
||||
|
||||
|
||||
def _log_auth_me_timing(
|
||||
*,
|
||||
authenticated: Optional[bool],
|
||||
outcome: str,
|
||||
status_code: int,
|
||||
subscription_active: Optional[bool],
|
||||
timings_ms: Dict[str, float],
|
||||
) -> None:
|
||||
logger.info(
|
||||
"auth_me_timing outcome={} status_code={} authenticated={} "
|
||||
"subscription_active={} timings_ms={}",
|
||||
outcome,
|
||||
status_code,
|
||||
authenticated,
|
||||
subscription_active,
|
||||
timings_ms,
|
||||
)
|
||||
|
||||
|
||||
def _require_auth_identity_without_subscription_gate(request: Request) -> Dict[str, str]:
|
||||
request.state.skip_subscription_gate = True
|
||||
legacy_routes._assert_entitlement(request)
|
||||
@@ -27,180 +93,253 @@ def _subscription_row_is_trial(row: Any) -> bool:
|
||||
|
||||
|
||||
def get_auth_me_payload(request: Request) -> Dict[str, Any]:
|
||||
request.state.skip_subscription_gate = True
|
||||
legacy_routes._assert_entitlement(request)
|
||||
if not str(getattr(request.state, "auth_user_id", "") or "").strip():
|
||||
legacy_routes._bind_optional_supabase_identity(request)
|
||||
timer = _AuthMeTimer(request)
|
||||
authenticated_for_log: Optional[bool] = None
|
||||
outcome = "ok"
|
||||
status_code = 200
|
||||
subscription_active_for_log: Optional[bool] = None
|
||||
|
||||
user_id = getattr(request.state, "auth_user_id", None)
|
||||
email = getattr(request.state, "auth_email", None)
|
||||
subscription_required = bool(
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
and legacy_routes.SUPABASE_ENTITLEMENT.require_subscription
|
||||
)
|
||||
subscription_active = None
|
||||
subscription_plan_code = None
|
||||
subscription_source = None
|
||||
subscription_is_trial = False
|
||||
subscription_starts_at = None
|
||||
subscription_expires_at = None
|
||||
subscription_total_expires_at = None
|
||||
subscription_queued_days = 0
|
||||
subscription_queued_count = 0
|
||||
referral = None
|
||||
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled and user_id:
|
||||
try:
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.ensure_signup_trial(user_id, email)
|
||||
try:
|
||||
subscription_window = legacy_routes.SUPABASE_ENTITLEMENT.get_subscription_window(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
bypass_cache=True,
|
||||
unknown_on_error=True,
|
||||
)
|
||||
except TypeError:
|
||||
subscription_window = legacy_routes.SUPABASE_ENTITLEMENT.get_subscription_window(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
)
|
||||
latest_subscription = None
|
||||
latest_known_subscription = None
|
||||
subscription_window_unknown = (
|
||||
isinstance(subscription_window, dict)
|
||||
and subscription_window.get("unknown") is True
|
||||
try:
|
||||
request.state.skip_subscription_gate = True
|
||||
timer.measure("assert_entitlement", lambda: legacy_routes._assert_entitlement(request))
|
||||
if not str(getattr(request.state, "auth_user_id", "") or "").strip():
|
||||
timer.measure(
|
||||
"bind_identity",
|
||||
lambda: legacy_routes._bind_optional_supabase_identity(request),
|
||||
)
|
||||
subscription_window_known = (
|
||||
isinstance(subscription_window, dict)
|
||||
and not subscription_window_unknown
|
||||
)
|
||||
if subscription_window_known:
|
||||
current_subscription = subscription_window.get("current")
|
||||
if isinstance(current_subscription, dict):
|
||||
latest_subscription = current_subscription
|
||||
rows = subscription_window.get("rows")
|
||||
if not latest_subscription and isinstance(rows, list):
|
||||
latest_known_subscription = next(
|
||||
(row for row in rows if isinstance(row, dict)),
|
||||
None,
|
||||
)
|
||||
if (
|
||||
not latest_subscription
|
||||
and not latest_known_subscription
|
||||
and not subscription_window_unknown
|
||||
and not subscription_window_known
|
||||
and not subscription_required
|
||||
):
|
||||
latest_subscription = (
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.get_latest_active_subscription(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
)
|
||||
)
|
||||
|
||||
subscription_active = (
|
||||
None if subscription_window_unknown else bool(latest_subscription)
|
||||
)
|
||||
if (
|
||||
subscription_required
|
||||
and subscription_active is False
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="Subscription required")
|
||||
|
||||
if not subscription_window_unknown and not latest_known_subscription:
|
||||
latest_known_subscription = latest_subscription
|
||||
if not subscription_window_unknown and not latest_known_subscription:
|
||||
latest_known_subscription = (
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.get_latest_subscription_any_status(
|
||||
user_id
|
||||
)
|
||||
)
|
||||
if isinstance(latest_subscription, dict):
|
||||
subscription_plan_code = latest_subscription.get("plan_code")
|
||||
subscription_source = latest_subscription.get("source")
|
||||
subscription_is_trial = _subscription_row_is_trial(latest_subscription)
|
||||
subscription_starts_at = latest_subscription.get("starts_at")
|
||||
subscription_expires_at = latest_subscription.get("expires_at")
|
||||
elif isinstance(latest_known_subscription, dict):
|
||||
subscription_plan_code = latest_known_subscription.get("plan_code")
|
||||
subscription_source = latest_known_subscription.get("source")
|
||||
subscription_is_trial = _subscription_row_is_trial(latest_known_subscription)
|
||||
subscription_starts_at = latest_known_subscription.get("starts_at")
|
||||
subscription_expires_at = latest_known_subscription.get("expires_at")
|
||||
if subscription_window_known:
|
||||
subscription_total_expires_at = subscription_window.get("total_expires_at")
|
||||
subscription_queued_days = int(subscription_window.get("queued_days") or 0)
|
||||
subscription_queued_count = int(subscription_window.get("queued_count") or 0)
|
||||
referral = legacy_routes.SUPABASE_ENTITLEMENT.get_referral_summary(user_id)
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception:
|
||||
if subscription_required:
|
||||
raise HTTPException(status_code=403, detail="Subscription required")
|
||||
subscription_active = None
|
||||
subscription_plan_code = None
|
||||
subscription_source = None
|
||||
subscription_is_trial = False
|
||||
subscription_starts_at = None
|
||||
subscription_expires_at = None
|
||||
subscription_total_expires_at = None
|
||||
subscription_queued_days = 0
|
||||
subscription_queued_count = 0
|
||||
referral = None
|
||||
|
||||
points = legacy_routes._resolve_auth_points(request)
|
||||
weekly_profile = legacy_routes._resolve_weekly_profile(request)
|
||||
telegram_pricing = None
|
||||
if user_id:
|
||||
try:
|
||||
pricing = TelegramGroupPricing()
|
||||
if pricing.configured:
|
||||
linked = DBManager().get_user_by_supabase_user_id(user_id)
|
||||
telegram_id = (
|
||||
int(linked.get("telegram_id") or 0)
|
||||
if isinstance(linked, dict)
|
||||
else 0
|
||||
)
|
||||
telegram_pricing = pricing.resolve_price_for_telegram_id(
|
||||
telegram_id or None
|
||||
)
|
||||
except Exception:
|
||||
telegram_pricing = None
|
||||
|
||||
return {
|
||||
"authenticated": bool(user_id),
|
||||
"user_id": user_id,
|
||||
"email": email,
|
||||
"points": points,
|
||||
"weekly_points": weekly_profile["weekly_points"],
|
||||
"weekly_rank": weekly_profile["weekly_rank"],
|
||||
"entitlement_mode": (
|
||||
"supabase_required"
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
and legacy_routes._SUPABASE_AUTH_REQUIRED
|
||||
else "supabase_optional"
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
else "legacy_token"
|
||||
if legacy_routes._ENTITLEMENT_GUARD_ENABLED
|
||||
else "disabled"
|
||||
),
|
||||
"auth_required": bool(
|
||||
user_id = getattr(request.state, "auth_user_id", None)
|
||||
email = getattr(request.state, "auth_email", None)
|
||||
authenticated_for_log = bool(user_id)
|
||||
subscription_required = bool(
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
and legacy_routes._SUPABASE_AUTH_REQUIRED
|
||||
),
|
||||
"subscription_required": subscription_required,
|
||||
"subscription_active": subscription_active,
|
||||
"subscription_plan_code": subscription_plan_code,
|
||||
"subscription_source": subscription_source,
|
||||
"subscription_is_trial": subscription_is_trial,
|
||||
"subscription_starts_at": subscription_starts_at,
|
||||
"subscription_expires_at": subscription_expires_at,
|
||||
"subscription_total_expires_at": subscription_total_expires_at,
|
||||
"subscription_queued_days": subscription_queued_days,
|
||||
"subscription_queued_count": subscription_queued_count,
|
||||
"telegram_pricing": telegram_pricing,
|
||||
"referral": referral,
|
||||
}
|
||||
and legacy_routes.SUPABASE_ENTITLEMENT.require_subscription
|
||||
)
|
||||
subscription_active = None
|
||||
subscription_plan_code = None
|
||||
subscription_source = None
|
||||
subscription_is_trial = False
|
||||
subscription_starts_at = None
|
||||
subscription_expires_at = None
|
||||
subscription_total_expires_at = None
|
||||
subscription_queued_days = 0
|
||||
subscription_queued_count = 0
|
||||
referral = None
|
||||
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled and user_id:
|
||||
try:
|
||||
timer.measure(
|
||||
"ensure_signup_trial",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.ensure_signup_trial(
|
||||
user_id,
|
||||
email,
|
||||
),
|
||||
)
|
||||
try:
|
||||
subscription_window = timer.measure(
|
||||
"subscription_window",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.get_subscription_window(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
bypass_cache=True,
|
||||
unknown_on_error=True,
|
||||
),
|
||||
)
|
||||
except TypeError:
|
||||
subscription_window = timer.measure(
|
||||
"subscription_window",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.get_subscription_window(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
),
|
||||
)
|
||||
latest_subscription = None
|
||||
latest_known_subscription = None
|
||||
subscription_window_unknown = (
|
||||
isinstance(subscription_window, dict)
|
||||
and subscription_window.get("unknown") is True
|
||||
)
|
||||
subscription_window_known = (
|
||||
isinstance(subscription_window, dict)
|
||||
and not subscription_window_unknown
|
||||
)
|
||||
if subscription_window_known:
|
||||
current_subscription = subscription_window.get("current")
|
||||
if isinstance(current_subscription, dict):
|
||||
latest_subscription = current_subscription
|
||||
rows = subscription_window.get("rows")
|
||||
if not latest_subscription and isinstance(rows, list):
|
||||
latest_known_subscription = next(
|
||||
(row for row in rows if isinstance(row, dict)),
|
||||
None,
|
||||
)
|
||||
if (
|
||||
not latest_subscription
|
||||
and not latest_known_subscription
|
||||
and not subscription_window_unknown
|
||||
and not subscription_window_known
|
||||
and not subscription_required
|
||||
):
|
||||
latest_subscription = timer.measure(
|
||||
"latest_active_subscription",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.get_latest_active_subscription(
|
||||
user_id,
|
||||
respect_requirement=False,
|
||||
),
|
||||
)
|
||||
|
||||
subscription_active = (
|
||||
None if subscription_window_unknown else bool(latest_subscription)
|
||||
)
|
||||
subscription_active_for_log = subscription_active
|
||||
if subscription_required and subscription_active is False:
|
||||
raise HTTPException(status_code=403, detail="Subscription required")
|
||||
|
||||
if not subscription_window_unknown and not latest_known_subscription:
|
||||
latest_known_subscription = latest_subscription
|
||||
if not subscription_window_unknown and not latest_known_subscription:
|
||||
latest_known_subscription = timer.measure(
|
||||
"latest_subscription_history",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.get_latest_subscription_any_status(
|
||||
user_id
|
||||
),
|
||||
)
|
||||
if isinstance(latest_subscription, dict):
|
||||
subscription_plan_code = latest_subscription.get("plan_code")
|
||||
subscription_source = latest_subscription.get("source")
|
||||
subscription_is_trial = _subscription_row_is_trial(
|
||||
latest_subscription
|
||||
)
|
||||
subscription_starts_at = latest_subscription.get("starts_at")
|
||||
subscription_expires_at = latest_subscription.get("expires_at")
|
||||
elif isinstance(latest_known_subscription, dict):
|
||||
subscription_plan_code = latest_known_subscription.get("plan_code")
|
||||
subscription_source = latest_known_subscription.get("source")
|
||||
subscription_is_trial = _subscription_row_is_trial(
|
||||
latest_known_subscription
|
||||
)
|
||||
subscription_starts_at = latest_known_subscription.get("starts_at")
|
||||
subscription_expires_at = latest_known_subscription.get("expires_at")
|
||||
if subscription_window_known:
|
||||
subscription_total_expires_at = subscription_window.get(
|
||||
"total_expires_at"
|
||||
)
|
||||
subscription_queued_days = int(
|
||||
subscription_window.get("queued_days") or 0
|
||||
)
|
||||
subscription_queued_count = int(
|
||||
subscription_window.get("queued_count") or 0
|
||||
)
|
||||
referral = timer.measure(
|
||||
"referral_summary",
|
||||
lambda: legacy_routes.SUPABASE_ENTITLEMENT.get_referral_summary(
|
||||
user_id
|
||||
),
|
||||
)
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception:
|
||||
if subscription_required:
|
||||
raise HTTPException(status_code=403, detail="Subscription required")
|
||||
subscription_active = None
|
||||
subscription_active_for_log = None
|
||||
subscription_plan_code = None
|
||||
subscription_source = None
|
||||
subscription_is_trial = False
|
||||
subscription_starts_at = None
|
||||
subscription_expires_at = None
|
||||
subscription_total_expires_at = None
|
||||
subscription_queued_days = 0
|
||||
subscription_queued_count = 0
|
||||
referral = None
|
||||
|
||||
points = timer.measure(
|
||||
"auth_points",
|
||||
lambda: legacy_routes._resolve_auth_points(request),
|
||||
)
|
||||
weekly_profile = timer.measure(
|
||||
"weekly_profile",
|
||||
lambda: legacy_routes._resolve_weekly_profile(request),
|
||||
)
|
||||
|
||||
def resolve_telegram_pricing() -> Any:
|
||||
if not user_id:
|
||||
return None
|
||||
pricing = TelegramGroupPricing()
|
||||
if not pricing.configured:
|
||||
return None
|
||||
linked = DBManager().get_user_by_supabase_user_id(user_id)
|
||||
telegram_id = (
|
||||
int(linked.get("telegram_id") or 0) if isinstance(linked, dict) else 0
|
||||
)
|
||||
return pricing.resolve_price_for_telegram_id(telegram_id or None)
|
||||
|
||||
telegram_pricing = None
|
||||
if user_id:
|
||||
try:
|
||||
telegram_pricing = timer.measure(
|
||||
"telegram_pricing",
|
||||
resolve_telegram_pricing,
|
||||
)
|
||||
except Exception:
|
||||
telegram_pricing = None
|
||||
|
||||
payload = {
|
||||
"authenticated": bool(user_id),
|
||||
"user_id": user_id,
|
||||
"email": email,
|
||||
"points": points,
|
||||
"weekly_points": weekly_profile["weekly_points"],
|
||||
"weekly_rank": weekly_profile["weekly_rank"],
|
||||
"entitlement_mode": (
|
||||
"supabase_required"
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
and legacy_routes._SUPABASE_AUTH_REQUIRED
|
||||
else "supabase_optional"
|
||||
if legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
else "legacy_token"
|
||||
if legacy_routes._ENTITLEMENT_GUARD_ENABLED
|
||||
else "disabled"
|
||||
),
|
||||
"auth_required": bool(
|
||||
legacy_routes.SUPABASE_ENTITLEMENT.enabled
|
||||
and legacy_routes._SUPABASE_AUTH_REQUIRED
|
||||
),
|
||||
"subscription_required": subscription_required,
|
||||
"subscription_active": subscription_active,
|
||||
"subscription_plan_code": subscription_plan_code,
|
||||
"subscription_source": subscription_source,
|
||||
"subscription_is_trial": subscription_is_trial,
|
||||
"subscription_starts_at": subscription_starts_at,
|
||||
"subscription_expires_at": subscription_expires_at,
|
||||
"subscription_total_expires_at": subscription_total_expires_at,
|
||||
"subscription_queued_days": subscription_queued_days,
|
||||
"subscription_queued_count": subscription_queued_count,
|
||||
"telegram_pricing": telegram_pricing,
|
||||
"referral": referral,
|
||||
}
|
||||
authenticated_for_log = bool(payload["authenticated"])
|
||||
subscription_active_for_log = (
|
||||
payload["subscription_active"]
|
||||
if isinstance(payload["subscription_active"], bool)
|
||||
else None
|
||||
)
|
||||
return payload
|
||||
except HTTPException as exc:
|
||||
outcome = f"http_{exc.status_code}"
|
||||
status_code = exc.status_code
|
||||
raise
|
||||
except Exception:
|
||||
outcome = "exception"
|
||||
status_code = 500
|
||||
raise
|
||||
finally:
|
||||
timer.finish(
|
||||
authenticated=authenticated_for_log,
|
||||
outcome=outcome,
|
||||
status_code=status_code,
|
||||
subscription_active=subscription_active_for_log,
|
||||
)
|
||||
|
||||
|
||||
def apply_referral_code(request: Request, body: ReferralApplyRequest) -> Dict[str, Any]:
|
||||
|
||||
Reference in New Issue
Block a user