import os from supabase import create_client, Client FREE_LIMIT = 8 PLAN_LIMITS = { "free": FREE_LIMIT, "starter": 80, "pro": float("inf"), # unlimited } def get_supabase() -> Client: url = os.getenv("SUPABASE_URL") key = os.getenv("SUPABASE_SERVICE_ROLE_KEY") or os.getenv("SUPABASE_SERVICE_KEY") if not url or not key: raise ValueError("Supabase credentials not set.") return create_client(url, key) from postgrest.exceptions import APIError def get_user_profile(user_id: str) -> dict: """Fetch user profile from Supabase, creating a default one if it doesn't exist.""" client = get_supabase() try: result = client.table("profiles").select("*").eq("id", user_id).single().execute() return result.data except APIError as e: if e.code == "PGRST116": new_profile = { "id": user_id, "plan": "free", "humanization_count": 0, "razorpay_subscription_id": None } client.table("profiles").insert(new_profile).execute() return new_profile raise e def check_usage_limit(user_id: str) -> dict: """ Check if user has remaining humanizations. Returns: { "allowed": bool, "count": int, "limit": int, "plan": str } """ profile = get_user_profile(user_id) plan = profile.get("plan", "free") count = profile.get("humanization_count", 0) limit = PLAN_LIMITS.get(plan, 2) return { "allowed": count < limit, "count": count, "limit": limit, "plan": plan, } def increment_usage(user_id: str) -> None: """Increment humanization count for user atomically.""" client = get_supabase() client.rpc('increment_humanization_count', {'uid': user_id}).execute() def upgrade_user_plan(user_id: str, plan: str) -> None: """Update user plan for a one-time order and reset usage.""" client = get_supabase() client.table("profiles").update({ "plan": plan, "humanization_count": 0 }).eq("id", user_id).execute() def cancel_user_subscription(user_id: str) -> None: """Revert user to free plan and clear subscription.""" client = get_supabase() client.table("profiles").update({ "plan": "free", "razorpay_subscription_id": None }).eq("id", user_id).execute()