diff --git a/web/services/ops_api.py b/web/services/ops_api.py index 495139cb..cd858784 100644 --- a/web/services/ops_api.py +++ b/web/services/ops_api.py @@ -451,6 +451,66 @@ def extend_ops_subscription( raise HTTPException(status_code=500, detail=f"Supabase update failed: {patch_resp.text[:200]}") +def get_ops_user_subscriptions( + request: Request, + email: str, +) -> dict[str, Any]: + """Return ALL subscription rows for a user (by email), regardless of status.""" + _require_ops(request) + import os + import requests as _requests + + supabase_url = str(os.getenv("SUPABASE_URL") or "").strip().rstrip("/") + service_role_key = str(os.getenv("SUPABASE_SERVICE_ROLE_KEY") or "").strip() + if not supabase_url or not service_role_key: + raise HTTPException(status_code=503, detail="Supabase not configured") + + normalized_email = str(email or "").strip().lower() + if not normalized_email: + raise HTTPException(status_code=400, detail="email is required") + + headers = { + "apikey": service_role_key, + "Authorization": f"Bearer {service_role_key}", + "Content-Type": "application/json", + } + + # Resolve user_id from email via auth admin API + user_resp = _requests.get( + f"{supabase_url}/auth/v1/admin/users", + headers=headers, + params={"filter": f"email.eq.{normalized_email}"}, + timeout=10, + ) + users = user_resp.json().get("users", []) if user_resp.ok else [] + user_id = users[0].get("id") if users else None + if not user_id: + raise HTTPException(status_code=404, detail=f"user not found: {normalized_email}") + + # Fetch all subscription rows for this user (no status filter) + subs_resp = _requests.get( + f"{supabase_url}/rest/v1/subscriptions", + headers=headers, + params={ + "select": "id,user_id,status,plan_code,source,starts_at,expires_at,created_at,updated_at", + "user_id": f"eq.{user_id}", + "order": "created_at.desc", + "limit": "50", + }, + timeout=10, + ) + rows = subs_resp.json() if subs_resp.ok and subs_resp.content else [] + if not isinstance(rows, list): + rows = [] + + return { + "email": normalized_email, + "user_id": user_id, + "subscriptions": rows, + "count": len(rows), + } + + # ── Logs ──────────────────────────────────────────────────────────── def get_ops_logs( @@ -619,7 +679,7 @@ def get_ops_health_check(request: Request) -> dict[str, Any]: results["singapore_mss"] = {"ok": False, "error": str(e)[:100]} # CWA (Taiwan Central Weather Administration) - cwa_key = str(os.getenv("CWA_API_KEY") or "").strip() + cwa_key = str(os.getenv("CWA_API_KEY") or os.getenv("CWA_OPEN_DATA_AUTH") or os.getenv("CWA_OPEN_DATA_API_KEY") or "").strip() if cwa_key: try: t0 = _time.perf_counter()