kamau1 commited on
Commit
ac8d4a4
·
verified ·
1 Parent(s): a538f32

Upload 12 files

Browse files
Files changed (3) hide show
  1. app/api/routes/auth_router.py +54 -32
  2. app/utils/db_http.py +103 -36
  3. main.py +71 -225
app/api/routes/auth_router.py CHANGED
@@ -138,7 +138,7 @@ async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)
138
 
139
  # Routes
140
  @router.post("/register", response_model=UserResponse)
141
- async def register(request: Request, user: UserCreate):
142
  # Generate a unique identifier for this registration attempt
143
  registration_id = f"reg_{int(time.time())}"
144
  logger.info(f"[{registration_id}] Starting registration for email: {user.email}")
@@ -259,44 +259,66 @@ async def register(request: Request, user: UserCreate):
259
  # Step 4: Retrieve the full user record
260
  logger.info(f"[{registration_id}] Retrieving user record")
261
 
262
- new_user = db_http.get_record_by_id("users", user_id, operation_id=registration_id)
 
 
 
 
 
 
263
 
264
- if not new_user:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  logger.warning(f"[{registration_id}] User not found after insert, trying by email")
266
 
267
- # Try to get by email as fallback
268
- users = db_http.select_records(
269
- "users",
270
- condition="email = ?",
271
- condition_params=[{"type": "text", "value": user.email}],
272
- limit=1,
273
- operation_id=registration_id
274
- )
 
275
 
276
- if users:
277
- new_user = users[0]
278
- user_id = new_user.get("id")
279
- logger.info(f"[{registration_id}] Found user by email with ID: {user_id}")
280
- else:
281
- logger.error(f"[{registration_id}] User not found by email either")
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
- # Return minimal response with what we know
284
- return {
285
- "id": user_id or 0,
286
- "email": user.email,
287
- "is_admin": False,
288
- "created_at": datetime.now().isoformat()
289
- }
290
 
291
- # Step 5: Construct the response
292
- logger.info(f"[{registration_id}] Registration successful for user ID: {user_id}")
293
 
294
- return {
295
- "id": new_user.get("id", user_id),
296
- "email": new_user.get("email", user.email),
297
- "is_admin": bool(new_user.get("is_admin", 0)),
298
- "created_at": str(new_user.get("created_at", datetime.now().isoformat()))
299
- }
300
 
301
  except Exception as e:
302
  logger.error(f"[{registration_id}] Registration failed: {str(e)}")
 
138
 
139
  # Routes
140
  @router.post("/register", response_model=UserResponse)
141
+ async def register(user: UserCreate):
142
  # Generate a unique identifier for this registration attempt
143
  registration_id = f"reg_{int(time.time())}"
144
  logger.info(f"[{registration_id}] Starting registration for email: {user.email}")
 
259
  # Step 4: Retrieve the full user record
260
  logger.info(f"[{registration_id}] Retrieving user record")
261
 
262
+ # Create a default user object with what we know
263
+ default_user = {
264
+ "id": user_id or 0,
265
+ "email": user.email,
266
+ "is_admin": False,
267
+ "created_at": datetime.now().isoformat()
268
+ }
269
 
270
+ # Try to get the full user record
271
+ try:
272
+ if user_id:
273
+ new_user = db_http.get_record_by_id("users", user_id, operation_id=registration_id)
274
+
275
+ if new_user:
276
+ logger.info(f"[{registration_id}] Found user by ID: {user_id}")
277
+ return {
278
+ "id": new_user.get("id", user_id),
279
+ "email": new_user.get("email", user.email),
280
+ "is_admin": bool(new_user.get("is_admin", 0)),
281
+ "created_at": str(new_user.get("created_at", datetime.now().isoformat()))
282
+ }
283
+
284
+ # If we couldn't get by ID or user_id is None, try by email
285
  logger.warning(f"[{registration_id}] User not found after insert, trying by email")
286
 
287
+ try:
288
+ # Try to get by email as fallback
289
+ users = db_http.select_records(
290
+ "users",
291
+ condition="email = ?",
292
+ condition_params=[{"type": "text", "value": user.email}],
293
+ limit=1,
294
+ operation_id=f"{registration_id}_email_lookup"
295
+ )
296
 
297
+ if users and len(users) > 0:
298
+ new_user = users[0]
299
+ user_id = new_user.get("id")
300
+ logger.info(f"[{registration_id}] Found user by email with ID: {user_id}")
301
+ return {
302
+ "id": new_user.get("id", user_id or 0),
303
+ "email": new_user.get("email", user.email),
304
+ "is_admin": bool(new_user.get("is_admin", 0)),
305
+ "created_at": str(new_user.get("created_at", datetime.now().isoformat()))
306
+ }
307
+ else:
308
+ logger.warning(f"[{registration_id}] User not found by email either")
309
+ except Exception as e:
310
+ logger.error(f"[{registration_id}] Error finding user by email: {str(e)}")
311
+
312
+ # If all else fails, return the default user object
313
+ logger.info(f"[{registration_id}] Returning default user object")
314
+ return default_user
315
 
316
+ except Exception as e:
317
+ logger.error(f"[{registration_id}] Error retrieving user record: {str(e)}")
318
+ # Return minimal response with what we know
319
+ return default_user
 
 
 
320
 
 
 
321
 
 
 
 
 
 
 
322
 
323
  except Exception as e:
324
  logger.error(f"[{registration_id}] Registration failed: {str(e)}")
app/utils/db_http.py CHANGED
@@ -178,16 +178,34 @@ def insert_record(table: str, data: Dict[str, Any], operation_id: str = None) ->
178
  return None
179
 
180
  # Try to get the last inserted ID with a separate query
181
- id_result = execute_query("SELECT last_insert_rowid()", operation_id=f"{operation_id}_get_id")
182
-
183
- last_id = None
184
- if "results" in id_result and len(id_result["results"]) > 0:
185
- if id_result["results"][0]["type"] == "ok":
186
- rows = id_result["results"][0]["response"]["result"]["rows"]
187
- if rows and len(rows) > 0:
188
- last_id = int(rows[0][0]["value"])
189
- logger.info(f"[{operation_id}] Record inserted with ID: {last_id}")
190
- return last_id
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  # If we can't get the ID, try to find it by other means
193
  logger.warning(f"[{operation_id}] Insert succeeded but couldn't get ID")
@@ -357,23 +375,37 @@ def select_records(table: str, columns: List[str] = None, condition: str = None,
357
  for row in rows:
358
  record = {}
359
  for i, col in enumerate(cols):
360
- col_name = col["name"]
361
- value = row[i]["value"]
362
-
363
- # Convert value based on type
364
  try:
365
- if row[i]["type"] == "integer":
366
- value = int(value)
367
- elif row[i]["type"] == "float":
368
- value = float(value)
369
- elif row[i]["type"] == "null":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  value = None
371
 
 
372
  record[col_name] = value
373
- except (KeyError, TypeError, ValueError) as e:
374
- # Handle missing or invalid values
375
- logger.warning(f"Error converting value for column {col_name}: {str(e)}")
376
- record[col_name] = None
377
 
378
  records.append(record)
379
 
@@ -434,21 +466,36 @@ def get_record_by_id(table: str, id: int, columns: List[str] = None, operation_i
434
  record = {}
435
  for i, col in enumerate(cols):
436
  try:
437
- col_name = col["name"]
438
- value = row[i]["value"]
 
 
 
 
 
 
 
439
 
440
  # Convert value based on type
441
- if row[i]["type"] == "integer":
442
- value = int(value)
443
- elif row[i]["type"] == "float":
444
- value = float(value)
445
- elif row[i]["type"] == "null":
 
 
 
 
 
 
446
  value = None
447
 
 
448
  record[col_name] = value
449
- except (KeyError, TypeError, ValueError) as e:
450
- logger.warning(f"[{operation_id}] Error converting value for column {col['name'] if 'name' in col else i}: {str(e)}")
451
- continue
 
452
 
453
  logger.info(f"[{operation_id}] Found record by ID {id} using fallback: {record}")
454
  return record
@@ -496,9 +543,29 @@ def count_records(table: str, condition: str = None, condition_params: List[Dict
496
  # Extract the count
497
  response = result["results"][0]["response"]
498
  if "result" in response and "rows" in response["result"] and response["result"]["rows"]:
499
- count = int(response["result"]["rows"][0][0]["value"])
500
- logger.info(f"[{operation_id}] Counted {count} records")
501
- return count
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
 
503
  logger.warning(f"[{operation_id}] Count failed")
504
  return 0
 
178
  return None
179
 
180
  # Try to get the last inserted ID with a separate query
181
+ try:
182
+ id_result = execute_query("SELECT last_insert_rowid()", operation_id=f"{operation_id}_get_id")
183
+
184
+ last_id = None
185
+ if "results" in id_result and len(id_result["results"]) > 0:
186
+ if id_result["results"][0]["type"] == "ok":
187
+ response = id_result["results"][0]["response"]
188
+ if "result" in response and "rows" in response["result"] and len(response["result"]["rows"]) > 0:
189
+ row = response["result"]["rows"][0]
190
+
191
+ # Get the value safely
192
+ if len(row) > 0:
193
+ cell = row[0]
194
+ if isinstance(cell, dict) and "value" in cell:
195
+ try:
196
+ last_id = int(cell["value"])
197
+ logger.info(f"[{operation_id}] Record inserted with ID: {last_id}")
198
+ return last_id
199
+ except (ValueError, TypeError) as e:
200
+ logger.warning(f"[{operation_id}] Error converting ID to integer: {str(e)}")
201
+ # Try to return the value as is
202
+ return cell["value"]
203
+ else:
204
+ logger.warning(f"[{operation_id}] Unexpected cell format: {cell}")
205
+ else:
206
+ logger.warning(f"[{operation_id}] Empty row in last_insert_rowid result")
207
+ except Exception as e:
208
+ logger.error(f"[{operation_id}] Error getting last insert ID: {str(e)}")
209
 
210
  # If we can't get the ID, try to find it by other means
211
  logger.warning(f"[{operation_id}] Insert succeeded but couldn't get ID")
 
375
  for row in rows:
376
  record = {}
377
  for i, col in enumerate(cols):
 
 
 
 
378
  try:
379
+ # Get column name safely
380
+ col_name = col.get("name", f"column_{i}")
381
+
382
+ # Get cell data safely
383
+ cell = row[i] if i < len(row) else {}
384
+
385
+ # Get value and type safely
386
+ value = cell.get("value") if isinstance(cell, dict) else cell
387
+ cell_type = cell.get("type") if isinstance(cell, dict) else None
388
+
389
+ # Convert value based on type
390
+ if cell_type == "integer" and value is not None:
391
+ try:
392
+ value = int(value)
393
+ except (ValueError, TypeError):
394
+ value = 0
395
+ elif cell_type == "float" and value is not None:
396
+ try:
397
+ value = float(value)
398
+ except (ValueError, TypeError):
399
+ value = 0.0
400
+ elif cell_type == "null":
401
  value = None
402
 
403
+ # Store the value
404
  record[col_name] = value
405
+ except Exception as e:
406
+ # Handle any errors
407
+ logger.warning(f"[{operation_id}] Error processing column {i}: {str(e)}")
408
+ record[f"column_{i}"] = None
409
 
410
  records.append(record)
411
 
 
466
  record = {}
467
  for i, col in enumerate(cols):
468
  try:
469
+ # Get column name safely
470
+ col_name = col.get("name", f"column_{i}")
471
+
472
+ # Get cell data safely
473
+ cell = row[i] if i < len(row) else {}
474
+
475
+ # Get value and type safely
476
+ value = cell.get("value") if isinstance(cell, dict) else cell
477
+ cell_type = cell.get("type") if isinstance(cell, dict) else None
478
 
479
  # Convert value based on type
480
+ if cell_type == "integer" and value is not None:
481
+ try:
482
+ value = int(value)
483
+ except (ValueError, TypeError):
484
+ value = 0
485
+ elif cell_type == "float" and value is not None:
486
+ try:
487
+ value = float(value)
488
+ except (ValueError, TypeError):
489
+ value = 0.0
490
+ elif cell_type == "null":
491
  value = None
492
 
493
+ # Store the value
494
  record[col_name] = value
495
+ except Exception as e:
496
+ # Handle any errors
497
+ logger.warning(f"[{operation_id}] Error processing column {i}: {str(e)}")
498
+ record[f"column_{i}"] = None
499
 
500
  logger.info(f"[{operation_id}] Found record by ID {id} using fallback: {record}")
501
  return record
 
543
  # Extract the count
544
  response = result["results"][0]["response"]
545
  if "result" in response and "rows" in response["result"] and response["result"]["rows"]:
546
+ try:
547
+ row = response["result"]["rows"][0]
548
+
549
+ # Get the value safely
550
+ if len(row) > 0:
551
+ cell = row[0]
552
+ if isinstance(cell, dict) and "value" in cell:
553
+ try:
554
+ count = int(cell["value"])
555
+ logger.info(f"[{operation_id}] Counted {count} records")
556
+ return count
557
+ except (ValueError, TypeError) as e:
558
+ logger.warning(f"[{operation_id}] Error converting count to integer: {str(e)}")
559
+ return 0
560
+ else:
561
+ logger.warning(f"[{operation_id}] Unexpected cell format in count: {cell}")
562
+ return 0
563
+ else:
564
+ logger.warning(f"[{operation_id}] Empty row in count result")
565
+ return 0
566
+ except Exception as e:
567
+ logger.error(f"[{operation_id}] Error extracting count: {str(e)}")
568
+ return 0
569
 
570
  logger.warning(f"[{operation_id}] Count failed")
571
  return 0
main.py CHANGED
@@ -202,253 +202,99 @@ async def startup_db_client():
202
  hashed_password = pwd_context.hash(super_user_password)
203
  logger.info(f"[{operation_id}] Password hashed successfully")
204
 
205
- # Extract the database URL and auth token
206
- db_url = os.getenv("TURSO_DATABASE_URL", "")
207
- auth_token = os.getenv("TURSO_AUTH_TOKEN", "")
208
-
209
- # Convert URL from libsql:// to https://
210
- if db_url.startswith("libsql://"):
211
- http_url = db_url.replace("libsql://", "https://")
212
- else:
213
- http_url = db_url
214
-
215
- # Ensure the URL doesn't have a trailing slash
216
- http_url = http_url.rstrip('/')
217
-
218
- # Set up headers for the HTTP request
219
- headers = {
220
- "Authorization": f"Bearer {auth_token}",
221
- "Content-Type": "application/json"
222
- }
223
-
224
- logger.info(f"[{operation_id}] Using HTTP URL: {http_url}")
225
 
226
- # First, check if the user already exists
227
  logger.info(f"[{operation_id}] Checking if super user already exists")
 
 
 
 
 
 
 
228
 
229
- check_query = {
230
- "requests": [
231
- {
232
- "type": "execute",
233
- "stmt": {
234
- "sql": "SELECT COUNT(*) FROM users WHERE email = ?",
235
- "args": [
236
- {"type": "text", "value": super_user_email}
237
- ]
238
- }
239
- },
240
- {"type": "close"}
241
- ]
242
- }
243
-
244
- # Send the request to check if user exists
245
- check_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=check_query)
246
- check_response.raise_for_status()
247
- check_result = check_response.json()
248
-
249
- logger.info(f"[{operation_id}] Check response: {check_result}")
250
-
251
- # Parse the result to see if user exists
252
- user_exists = False
253
- if "results" in check_result and len(check_result["results"]) > 0:
254
- result = check_result["results"][0]
255
- if "rows" in result and len(result["rows"]) > 0:
256
- count = result["rows"][0]["values"][0]
257
- user_exists = count > 0
258
 
259
- if user_exists:
260
- logger.info(f"[{operation_id}] Super user already exists according to HTTP API")
261
 
262
- # Check if the user is an admin
263
- admin_query = {
264
- "requests": [
265
- {
266
- "type": "execute",
267
- "stmt": {
268
- "sql": "SELECT id, is_admin FROM users WHERE email = ?",
269
- "args": [
270
- {"type": "text", "value": super_user_email}
271
- ]
272
- }
273
- },
274
- {"type": "close"}
275
- ]
276
- }
277
 
278
- # Send the request to check if user is admin
279
- admin_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=admin_query)
280
- admin_response.raise_for_status()
281
- admin_result = admin_response.json()
282
-
283
- logger.info(f"[{operation_id}] Admin check response: {admin_result}")
284
-
285
- # Parse the result to see if user is admin
286
- is_admin = False
287
- user_id = None
288
- if "results" in admin_result and len(admin_result["results"]) > 0:
289
- result = admin_result["results"][0]
290
- if "rows" in result and len(result["rows"]) > 0:
291
- user_id = result["rows"][0]["values"][0]
292
- is_admin = result["rows"][0]["values"][1] == 1
293
-
294
- if user_id:
295
- logger.info(f"[{operation_id}] Found user with ID: {user_id}, is_admin: {is_admin}")
296
-
297
- # If user exists but is not admin, make them admin
298
- if not is_admin:
299
- logger.info(f"[{operation_id}] Updating user to have admin privileges")
300
-
301
- update_query = {
302
- "requests": [
303
- {
304
- "type": "execute",
305
- "stmt": {
306
- "sql": "UPDATE users SET is_admin = 1 WHERE id = ?",
307
- "args": [
308
- {"type": "integer", "value": str(user_id)}
309
- ]
310
- }
311
- },
312
- {"type": "close"}
313
- ]
314
- }
315
-
316
- # Send the request to update the user
317
- update_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=update_query)
318
- update_response.raise_for_status()
319
  logger.info(f"[{operation_id}] User updated to admin successfully")
 
 
320
 
321
  return
322
 
323
  # User doesn't exist, create it
324
  logger.info(f"[{operation_id}] Super user does not exist, creating now")
325
 
326
- # First, make sure the table exists
327
- create_table_query = {
328
- "requests": [
329
- {
330
- "type": "execute",
331
- "stmt": {
332
- "sql": """
333
- CREATE TABLE IF NOT EXISTS users (
334
- id INTEGER PRIMARY KEY AUTOINCREMENT,
335
- email TEXT NOT NULL UNIQUE,
336
- hashed_password TEXT NOT NULL,
337
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
338
- last_login DATETIME,
339
- is_admin INTEGER DEFAULT 0
340
- )
341
- """
342
- }
343
- },
344
- {"type": "close"}
345
- ]
346
- }
347
-
348
- # Send the request to create the table
349
- create_table_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=create_table_query)
350
- create_table_response.raise_for_status()
351
- logger.info(f"[{operation_id}] Table creation response: {create_table_response.status_code}")
352
-
353
  # Insert the super user
354
- insert_query = {
355
- "requests": [
356
- {
357
- "type": "execute",
358
- "stmt": {
359
- "sql": "INSERT INTO users (email, hashed_password, is_admin) VALUES (?, ?, 1)",
360
- "args": [
361
- {"type": "text", "value": super_user_email},
362
- {"type": "text", "value": hashed_password}
363
- ]
364
- }
365
- },
366
- {
367
- "type": "execute",
368
- "stmt": {"sql": "SELECT last_insert_rowid()"}
369
- },
370
- {"type": "close"}
371
- ]
372
  }
373
 
374
- # Send the request to insert the user
375
- insert_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=insert_query)
376
- insert_response.raise_for_status()
377
- insert_result = insert_response.json()
378
-
379
- logger.info(f"[{operation_id}] Insert response: {insert_result}")
380
 
381
- # Try to get the last inserted ID
382
- last_id = None
383
- if "results" in insert_result and len(insert_result["results"]) > 1:
384
- result = insert_result["results"][1]
385
- if "rows" in result and len(result["rows"]) > 0:
386
- last_id = result["rows"][0]["values"][0]
387
- logger.info(f"[{operation_id}] Last inserted ID: {last_id}")
388
-
389
- # Verify the user was created
390
- verify_query = {
391
- "requests": [
392
- {
393
- "type": "execute",
394
- "stmt": {
395
- "sql": "SELECT * FROM users WHERE email = ?",
396
- "args": [
397
- {"type": "text", "value": super_user_email}
398
- ]
399
- }
400
- },
401
- {"type": "close"}
402
- ]
403
- }
404
 
405
- # Send the request to verify the user
406
- verify_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=verify_query)
407
- verify_response.raise_for_status()
408
- verify_result = verify_response.json()
409
-
410
- logger.info(f"[{operation_id}] Verify response: {verify_result}")
411
-
412
- # Check if the user was found
413
- user_found = False
414
- user_id = None
415
- if "results" in verify_result and len(verify_result["results"]) > 0:
416
- result = verify_result["results"][0]
417
- if "rows" in result and len(result["rows"]) > 0:
418
- user_found = True
419
- user_id = result["rows"][0]["values"][0]
420
- logger.info(f"[{operation_id}] User found with ID: {user_id}")
421
-
422
- if user_found:
423
- logger.info(f"[{operation_id}] Super user created successfully")
424
- else:
425
- # List all users for diagnostic purposes
426
- list_query = {
427
- "requests": [
428
- {
429
- "type": "execute",
430
- "stmt": {"sql": "SELECT id, email FROM users"}
431
- },
432
- {"type": "close"}
433
- ]
434
- }
435
 
436
- # Send the request to list all users
437
- list_response = requests.post(f"{http_url}/v2/pipeline", headers=headers, json=list_query)
438
- list_response.raise_for_status()
439
- list_result = list_response.json()
 
440
 
441
- logger.info(f"[{operation_id}] List response: {list_result}")
 
 
 
 
 
 
 
442
 
443
- # Extract the list of users
444
- all_users = []
445
- if "results" in list_result and len(list_result["results"]) > 0:
446
- result = list_result["results"][0]
447
- if "rows" in result:
448
- for row in result["rows"]:
449
- all_users.append(row["values"])
450
 
451
- logger.warning(f"[{operation_id}] Super user was not found after creation. All users: {all_users}")
 
 
 
452
 
453
  except Exception as e:
454
  logger.error(f"[{operation_id}] Error creating super user with HTTP API: {str(e)}")
 
202
  hashed_password = pwd_context.hash(super_user_password)
203
  logger.info(f"[{operation_id}] Password hashed successfully")
204
 
205
+ # First, make sure the users table exists
206
+ logger.info(f"[{operation_id}] Creating users table if it doesn't exist")
207
+ db_http.create_table_if_not_exists(
208
+ "users",
209
+ """
210
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
211
+ email TEXT NOT NULL UNIQUE,
212
+ hashed_password TEXT NOT NULL,
213
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
214
+ last_login DATETIME,
215
+ is_admin INTEGER DEFAULT 0
216
+ """,
217
+ operation_id=f"{operation_id}_create_table"
218
+ )
 
 
 
 
 
 
219
 
220
+ # Check if the super user already exists
221
  logger.info(f"[{operation_id}] Checking if super user already exists")
222
+ users = db_http.select_records(
223
+ "users",
224
+ condition="email = ?",
225
+ condition_params=[{"type": "text", "value": super_user_email}],
226
+ limit=1,
227
+ operation_id=f"{operation_id}_check"
228
+ )
229
 
230
+ if users and len(users) > 0:
231
+ # User exists, check if they're an admin
232
+ user = users[0]
233
+ user_id = user.get("id")
234
+ is_admin = bool(user.get("is_admin", 0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ logger.info(f"[{operation_id}] Super user already exists with ID: {user_id}, is_admin: {is_admin}")
 
237
 
238
+ # If user exists but is not admin, make them admin
239
+ if not is_admin:
240
+ logger.info(f"[{operation_id}] Updating user to have admin privileges")
241
+
242
+ update_result = db_http.update_record(
243
+ "users",
244
+ {"is_admin": 1},
245
+ "id = ?",
246
+ [{"type": "integer", "value": str(user_id)}],
247
+ operation_id=f"{operation_id}_update"
248
+ )
 
 
 
 
249
 
250
+ if update_result:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  logger.info(f"[{operation_id}] User updated to admin successfully")
252
+ else:
253
+ logger.warning(f"[{operation_id}] Failed to update user to admin")
254
 
255
  return
256
 
257
  # User doesn't exist, create it
258
  logger.info(f"[{operation_id}] Super user does not exist, creating now")
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  # Insert the super user
261
+ user_data = {
262
+ "email": super_user_email,
263
+ "hashed_password": hashed_password,
264
+ "is_admin": 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
 
267
+ user_id = db_http.insert_record("users", user_data, operation_id=f"{operation_id}_insert")
 
 
 
 
 
268
 
269
+ if user_id:
270
+ logger.info(f"[{operation_id}] Super user created successfully with ID: {user_id}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
+ # Verify the user was created
273
+ new_user = db_http.get_record_by_id("users", user_id, operation_id=f"{operation_id}_verify")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
+ if new_user:
276
+ logger.info(f"[{operation_id}] Super user verified with ID: {user_id}")
277
+ return
278
+ else:
279
+ logger.warning(f"[{operation_id}] Super user not found by ID after creation")
280
 
281
+ # Try to find by email
282
+ users = db_http.select_records(
283
+ "users",
284
+ condition="email = ?",
285
+ condition_params=[{"type": "text", "value": super_user_email}],
286
+ limit=1,
287
+ operation_id=f"{operation_id}_verify_email"
288
+ )
289
 
290
+ if users and len(users) > 0:
291
+ logger.info(f"[{operation_id}] Super user found by email after creation")
292
+ return
 
 
 
 
293
 
294
+ # If we get here, we couldn't verify the user was created
295
+ # List all users for diagnostic purposes
296
+ all_users = db_http.select_records("users", operation_id=f"{operation_id}_list_all")
297
+ logger.warning(f"[{operation_id}] Super user was not found after creation. All users: {all_users}")
298
 
299
  except Exception as e:
300
  logger.error(f"[{operation_id}] Error creating super user with HTTP API: {str(e)}")