Hamdy005 commited on
Commit
c480aa4
·
1 Parent(s): dc64ef1

feat: improve profile synchronization to prevent usage counter resets

Browse files
Files changed (1) hide show
  1. auth/routes.py +19 -7
auth/routes.py CHANGED
@@ -55,15 +55,24 @@ async def get_profile(
55
  data["display_name"] = real_name
56
 
57
  try:
58
- res_upd = _table_supabase("profiles").insert(data).execute()
 
 
 
 
 
 
 
59
  if res_upd.data:
60
  user = _map_profile(res_upd.data[0])
61
  except Exception:
62
- # Profile row probably already exists do a targeted update instead
63
  try:
 
 
64
  res_upd = (
65
  _table_supabase("profiles")
66
- .update(data)
67
  .eq("id", user_id)
68
  .execute()
69
  )
@@ -75,19 +84,22 @@ async def get_profile(
75
  pass
76
 
77
  if not user:
78
- # Last resort: synthetic profile from the JWT claims so the UI doesn't break
 
79
  user_obj = current_user
80
  uid = getattr(user_obj, "id", None) or (user_obj.get("id") if isinstance(user_obj, dict) else None)
81
  if uid:
82
- from src.store import _map_profile
83
  meta = getattr(user_obj, "user_metadata", {}) or {}
 
 
84
  user = _map_profile({
85
  "id": uid,
86
  "display_name": meta.get("full_name") or meta.get("name") or "User",
87
  "email": getattr(user_obj, "email", "") or "",
88
  "avatar_url": "",
89
- "daily_requests": 0,
90
- "last_request_date": "",
91
  "_is_fallback": True,
92
  })
93
 
 
55
  data["display_name"] = real_name
56
 
57
  try:
58
+ # Use upsert so we NEVER overwrite daily_requests / last_request_date
59
+ # on subsequent sign-ins. Only id/email/display_name are safe to set.
60
+ client = supabase # already resolved above
61
+ res_upd = (
62
+ client.table("profiles")
63
+ .upsert(data, on_conflict="id", ignore_duplicates=False)
64
+ .execute()
65
+ )
66
  if res_upd.data:
67
  user = _map_profile(res_upd.data[0])
68
  except Exception:
69
+ # Upsert failed fall back to a plain update (never resets usage)
70
  try:
71
+ # Strip the id from the update payload to avoid PK conflicts
72
+ update_data = {k: v for k, v in data.items() if k != "id"}
73
  res_upd = (
74
  _table_supabase("profiles")
75
+ .update(update_data)
76
  .eq("id", user_id)
77
  .execute()
78
  )
 
84
  pass
85
 
86
  if not user:
87
+ # Last resort: synthetic profile from the JWT claims so the UI doesn't break.
88
+ # We still try to fetch real usage from the DB to avoid resetting the counter.
89
  user_obj = current_user
90
  uid = getattr(user_obj, "id", None) or (user_obj.get("id") if isinstance(user_obj, dict) else None)
91
  if uid:
92
+ from src.store import _map_profile, get_usage
93
  meta = getattr(user_obj, "user_metadata", {}) or {}
94
+ # Fetch real usage so the fallback profile doesn't reset the counter to 0
95
+ real_usage = get_usage(uid)
96
  user = _map_profile({
97
  "id": uid,
98
  "display_name": meta.get("full_name") or meta.get("name") or "User",
99
  "email": getattr(user_obj, "email", "") or "",
100
  "avatar_url": "",
101
+ "daily_requests": real_usage.get("used", 0),
102
+ "last_request_date": __import__('datetime').date.today().isoformat(),
103
  "_is_fallback": True,
104
  })
105