MukeshKapoor25 commited on
Commit
df8187a
·
1 Parent(s): 90064f2

refactor(logging): change debug to info level for operational logs

Browse files

Standardize logging level to INFO across application components to ensure important operational logs are captured in production. This provides better visibility into system behavior while reducing noise from debug logs.

app/app.py CHANGED
@@ -8,14 +8,15 @@ from app.middleware.security_middleware import SecurityMiddleware
8
  import logging
9
  import sys
10
 
11
- # Configure logging
12
  logging.basicConfig(
13
- level=logging.DEBUG,
14
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
15
  handlers=[
16
  logging.StreamHandler(sys.stdout),
17
  logging.FileHandler('app.log')
18
- ]
 
19
  )
20
 
21
  # Set specific logger levels
 
8
  import logging
9
  import sys
10
 
11
+ # Configure logging (force ensures this overrides any prior configs)
12
  logging.basicConfig(
13
+ level=logging.INFO,
14
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
15
  handlers=[
16
  logging.StreamHandler(sys.stdout),
17
  logging.FileHandler('app.log')
18
+ ],
19
+ force=True,
20
  )
21
 
22
  # Set specific logger levels
app/middleware/security_middleware.py CHANGED
@@ -6,8 +6,7 @@ import logging
6
  from typing import Dict, Any
7
  from app.core.nosql_client import db
8
 
9
- # Configure logging
10
- logging.basicConfig(level=logging.INFO)
11
  logger = logging.getLogger(__name__)
12
 
13
  class SecurityMiddleware(BaseHTTPMiddleware):
 
6
  from typing import Dict, Any
7
  from app.core.nosql_client import db
8
 
9
+ # Use app-level logging configuration
 
10
  logger = logging.getLogger(__name__)
11
 
12
  class SecurityMiddleware(BaseHTTPMiddleware):
app/models/favorite_model.py CHANGED
@@ -165,7 +165,7 @@ class BookMyServiceFavoriteModel:
165
  @staticmethod
166
  async def is_favorite(customer_id: str, merchant_id: str) -> bool:
167
  """Check if a merchant is in user's favorites"""
168
- logger.debug(f"Checking if merchant {merchant_id} is favorite for customer {customer_id}")
169
 
170
  try:
171
  favorite = await BookMyServiceFavoriteModel.collection.find_one({
 
165
  @staticmethod
166
  async def is_favorite(customer_id: str, merchant_id: str) -> bool:
167
  """Check if a merchant is in user's favorites"""
168
+ logger.info(f"Checking if merchant {merchant_id} is favorite for customer {customer_id}")
169
 
170
  try:
171
  favorite = await BookMyServiceFavoriteModel.collection.find_one({
app/models/otp_model.py CHANGED
@@ -23,7 +23,7 @@ class BookMyServiceOTPModel:
23
 
24
  try:
25
  redis = await get_redis()
26
- logger.debug(f"Redis connection established for OTP storage")
27
 
28
  # Check if account is locked
29
  if await BookMyServiceOTPModel.is_account_locked(identifier):
@@ -32,14 +32,14 @@ class BookMyServiceOTPModel:
32
 
33
  # Rate limit: max 3 OTPs per identifier per 10 minutes
34
  rate_key = f"otp_rate_limit:{identifier}"
35
- logger.debug(f"Checking rate limit with key: {rate_key}")
36
 
37
  attempts = await redis.incr(rate_key)
38
- logger.debug(f"Current OTP attempts for {identifier}: {attempts}")
39
 
40
  if attempts == 1:
41
  await redis.expire(rate_key, BookMyServiceOTPModel.RATE_LIMIT_WINDOW)
42
- logger.debug(f"Set rate limit expiry for {identifier}")
43
  elif attempts > BookMyServiceOTPModel.RATE_LIMIT_MAX:
44
  logger.warning(f"Rate limit exceeded for {identifier}: {attempts} attempts")
45
  raise HTTPException(status_code=429, detail="Too many OTP requests. Try again later.")
@@ -85,11 +85,11 @@ class BookMyServiceOTPModel:
85
  @staticmethod
86
  async def verify_otp(identifier: str, otp: str, client_ip: str = None):
87
  logger.info(f"Verifying OTP for identifier: {identifier}, IP: {client_ip}")
88
- logger.debug(f"Provided OTP: {otp}")
89
 
90
  try:
91
  redis = await get_redis()
92
- logger.debug("Redis connection established for OTP verification")
93
 
94
  # Check if account is locked
95
  if await BookMyServiceOTPModel.is_account_locked(identifier):
@@ -97,19 +97,19 @@ class BookMyServiceOTPModel:
97
  raise HTTPException(status_code=423, detail="Account temporarily locked due to too many failed attempts")
98
 
99
  key = f"bms_otp:{identifier}"
100
- logger.debug(f"Looking up OTP with key: {key}")
101
 
102
  stored = await redis.get(key)
103
- logger.debug(f"Stored OTP value: {stored}")
104
 
105
  if stored:
106
- logger.debug(f"OTP found in Redis. Comparing: provided='{otp}' vs stored='{stored}'")
107
  if stored == otp:
108
  logger.info(f"OTP verification successful for {identifier}")
109
  await redis.delete(key)
110
  # Clear failed attempts on successful verification
111
  await BookMyServiceOTPModel.clear_failed_attempts(identifier)
112
- logger.debug(f"OTP deleted from Redis after successful verification")
113
  return True
114
  else:
115
  logger.warning(f"OTP mismatch for {identifier}: provided='{otp}' vs stored='{stored}'")
@@ -166,7 +166,7 @@ class BookMyServiceOTPModel:
166
  if ip_attempts == 1:
167
  await redis.expire(ip_failed_key, BookMyServiceOTPModel.FAILED_ATTEMPTS_WINDOW)
168
 
169
- logger.debug(f"IP {client_ip} failed attempts: {ip_attempts}")
170
 
171
  except Exception as e:
172
  logger.error(f"Error tracking failed attempt for {identifier}: {str(e)}", exc_info=True)
@@ -178,7 +178,7 @@ class BookMyServiceOTPModel:
178
  redis = await get_redis()
179
  failed_key = f"failed_otp:{identifier}"
180
  await redis.delete(failed_key)
181
- logger.debug(f"Cleared failed attempts for {identifier}")
182
  except Exception as e:
183
  logger.error(f"Error clearing failed attempts for {identifier}: {str(e)}", exc_info=True)
184
 
 
23
 
24
  try:
25
  redis = await get_redis()
26
+ logger.info(f"Redis connection established for OTP storage")
27
 
28
  # Check if account is locked
29
  if await BookMyServiceOTPModel.is_account_locked(identifier):
 
32
 
33
  # Rate limit: max 3 OTPs per identifier per 10 minutes
34
  rate_key = f"otp_rate_limit:{identifier}"
35
+ logger.info(f"Checking rate limit with key: {rate_key}")
36
 
37
  attempts = await redis.incr(rate_key)
38
+ logger.info(f"Current OTP attempts for {identifier}: {attempts}")
39
 
40
  if attempts == 1:
41
  await redis.expire(rate_key, BookMyServiceOTPModel.RATE_LIMIT_WINDOW)
42
+ logger.info(f"Set rate limit expiry for {identifier}")
43
  elif attempts > BookMyServiceOTPModel.RATE_LIMIT_MAX:
44
  logger.warning(f"Rate limit exceeded for {identifier}: {attempts} attempts")
45
  raise HTTPException(status_code=429, detail="Too many OTP requests. Try again later.")
 
85
  @staticmethod
86
  async def verify_otp(identifier: str, otp: str, client_ip: str = None):
87
  logger.info(f"Verifying OTP for identifier: {identifier}, IP: {client_ip}")
88
+ logger.info(f"Provided OTP: {otp}")
89
 
90
  try:
91
  redis = await get_redis()
92
+ logger.info("Redis connection established for OTP verification")
93
 
94
  # Check if account is locked
95
  if await BookMyServiceOTPModel.is_account_locked(identifier):
 
97
  raise HTTPException(status_code=423, detail="Account temporarily locked due to too many failed attempts")
98
 
99
  key = f"bms_otp:{identifier}"
100
+ logger.info(f"Looking up OTP with key: {key}")
101
 
102
  stored = await redis.get(key)
103
+ logger.info(f"Stored OTP value: {stored}")
104
 
105
  if stored:
106
+ logger.info(f"OTP found in Redis. Comparing: provided='{otp}' vs stored='{stored}'")
107
  if stored == otp:
108
  logger.info(f"OTP verification successful for {identifier}")
109
  await redis.delete(key)
110
  # Clear failed attempts on successful verification
111
  await BookMyServiceOTPModel.clear_failed_attempts(identifier)
112
+ logger.info(f"OTP deleted from Redis after successful verification")
113
  return True
114
  else:
115
  logger.warning(f"OTP mismatch for {identifier}: provided='{otp}' vs stored='{stored}'")
 
166
  if ip_attempts == 1:
167
  await redis.expire(ip_failed_key, BookMyServiceOTPModel.FAILED_ATTEMPTS_WINDOW)
168
 
169
+ logger.info(f"IP {client_ip} failed attempts: {ip_attempts}")
170
 
171
  except Exception as e:
172
  logger.error(f"Error tracking failed attempt for {identifier}: {str(e)}", exc_info=True)
 
178
  redis = await get_redis()
179
  failed_key = f"failed_otp:{identifier}"
180
  await redis.delete(failed_key)
181
+ logger.info(f"Cleared failed attempts for {identifier}")
182
  except Exception as e:
183
  logger.error(f"Error clearing failed attempts for {identifier}: {str(e)}", exc_info=True)
184
 
app/models/social_security_model.py CHANGED
@@ -52,7 +52,7 @@ class SocialSecurityModel:
52
  if count == 1:
53
  await redis.expire(rate_key, SocialSecurityModel.OAUTH_RATE_LIMIT_WINDOW)
54
 
55
- logger.debug(f"OAuth rate limit count for {client_ip}:{provider} = {count}")
56
 
57
  except Exception as e:
58
  logger.error(f"Error incrementing OAuth rate limit: {str(e)}", exc_info=True)
@@ -76,7 +76,7 @@ class SocialSecurityModel:
76
  await SocialSecurityModel.lock_oauth_ip(client_ip, provider)
77
  logger.warning(f"IP {client_ip} locked for provider {provider} after {attempts} failed attempts")
78
 
79
- logger.debug(f"OAuth failed attempts for {client_ip}:{provider} = {attempts}")
80
 
81
  except Exception as e:
82
  logger.error(f"Error tracking OAuth failed attempt: {str(e)}", exc_info=True)
@@ -117,7 +117,7 @@ class SocialSecurityModel:
117
  redis = await get_redis()
118
  failed_key = f"oauth_failed:{client_ip}:{provider}"
119
  await redis.delete(failed_key)
120
- logger.debug(f"Cleared OAuth failed attempts for {client_ip}:{provider}")
121
  except Exception as e:
122
  logger.error(f"Error clearing OAuth failed attempts: {str(e)}", exc_info=True)
123
 
 
52
  if count == 1:
53
  await redis.expire(rate_key, SocialSecurityModel.OAUTH_RATE_LIMIT_WINDOW)
54
 
55
+ logger.info(f"OAuth rate limit count for {client_ip}:{provider} = {count}")
56
 
57
  except Exception as e:
58
  logger.error(f"Error incrementing OAuth rate limit: {str(e)}", exc_info=True)
 
76
  await SocialSecurityModel.lock_oauth_ip(client_ip, provider)
77
  logger.warning(f"IP {client_ip} locked for provider {provider} after {attempts} failed attempts")
78
 
79
+ logger.info(f"OAuth failed attempts for {client_ip}:{provider} = {attempts}")
80
 
81
  except Exception as e:
82
  logger.error(f"Error tracking OAuth failed attempt: {str(e)}", exc_info=True)
 
117
  redis = await get_redis()
118
  failed_key = f"oauth_failed:{client_ip}:{provider}"
119
  await redis.delete(failed_key)
120
+ logger.info(f"Cleared OAuth failed attempts for {client_ip}:{provider}")
121
  except Exception as e:
122
  logger.error(f"Error clearing OAuth failed attempts: {str(e)}", exc_info=True)
123
 
app/models/user_model.py CHANGED
@@ -11,13 +11,13 @@ class BookMyServiceUserModel:
11
 
12
  @staticmethod
13
  async def find_by_email(email: str):
14
- logger.debug(f"Searching for user by email: {email}")
15
  try:
16
  user = await BookMyServiceUserModel.collection.find_one({"email": email})
17
  if user:
18
- logger.debug(f"User found by email: {email}")
19
  else:
20
- logger.debug(f"No user found with email: {email}")
21
  return user
22
  except Exception as e:
23
  logger.error(f"Error finding user by email {email}: {str(e)}", exc_info=True)
@@ -25,13 +25,13 @@ class BookMyServiceUserModel:
25
 
26
  @staticmethod
27
  async def find_by_phone(phone: str):
28
- logger.debug(f"Searching for user by phone: {phone}")
29
  try:
30
  user = await BookMyServiceUserModel.collection.find_one({"phone": phone})
31
  if user:
32
- logger.debug(f"User found by phone: {phone}")
33
  else:
34
- logger.debug(f"No user found with phone: {phone}")
35
  return user
36
  except Exception as e:
37
  logger.error(f"Error finding user by phone {phone}: {str(e)}", exc_info=True)
@@ -40,7 +40,7 @@ class BookMyServiceUserModel:
40
  @staticmethod
41
  async def find_by_mobile(mobile: str):
42
  """Legacy method for backward compatibility - redirects to find_by_phone"""
43
- logger.debug(f"Legacy find_by_mobile called, redirecting to find_by_phone for: {mobile}")
44
  return await BookMyServiceUserModel.find_by_phone(mobile)
45
 
46
  @staticmethod
@@ -50,13 +50,13 @@ class BookMyServiceUserModel:
50
  try:
51
  # Validate and determine identifier type
52
  identifier_type = validate_identifier(identifier)
53
- logger.debug(f"Identifier type determined: {identifier_type}")
54
 
55
  if identifier_type == "email":
56
- logger.debug(f"Searching by email for identifier: {identifier}")
57
  user = await BookMyServiceUserModel.find_by_email(identifier)
58
  elif identifier_type == "phone":
59
- logger.debug(f"Searching by phone for identifier: {identifier}")
60
  user = await BookMyServiceUserModel.find_by_phone(identifier)
61
  else:
62
  logger.error(f"Invalid identifier type: {identifier_type}")
@@ -67,7 +67,7 @@ class BookMyServiceUserModel:
67
  raise HTTPException(status_code=404, detail="User not found with this email or phone")
68
 
69
  logger.info(f"User found successfully for identifier: {identifier}")
70
- logger.debug(f"User data keys: {list(user.keys()) if user else 'None'}")
71
  return user
72
 
73
  except ValueError as ve:
 
11
 
12
  @staticmethod
13
  async def find_by_email(email: str):
14
+ logger.info(f"Searching for user by email: {email}")
15
  try:
16
  user = await BookMyServiceUserModel.collection.find_one({"email": email})
17
  if user:
18
+ logger.info(f"User found by email: {email}")
19
  else:
20
+ logger.info(f"No user found with email: {email}")
21
  return user
22
  except Exception as e:
23
  logger.error(f"Error finding user by email {email}: {str(e)}", exc_info=True)
 
25
 
26
  @staticmethod
27
  async def find_by_phone(phone: str):
28
+ logger.info(f"Searching for user by phone: {phone}")
29
  try:
30
  user = await BookMyServiceUserModel.collection.find_one({"phone": phone})
31
  if user:
32
+ logger.info(f"User found by phone: {phone}")
33
  else:
34
+ logger.info(f"No user found with phone: {phone}")
35
  return user
36
  except Exception as e:
37
  logger.error(f"Error finding user by phone {phone}: {str(e)}", exc_info=True)
 
40
  @staticmethod
41
  async def find_by_mobile(mobile: str):
42
  """Legacy method for backward compatibility - redirects to find_by_phone"""
43
+ logger.info(f"Legacy find_by_mobile called, redirecting to find_by_phone for: {mobile}")
44
  return await BookMyServiceUserModel.find_by_phone(mobile)
45
 
46
  @staticmethod
 
50
  try:
51
  # Validate and determine identifier type
52
  identifier_type = validate_identifier(identifier)
53
+ logger.info(f"Identifier type determined: {identifier_type}")
54
 
55
  if identifier_type == "email":
56
+ logger.info(f"Searching by email for identifier: {identifier}")
57
  user = await BookMyServiceUserModel.find_by_email(identifier)
58
  elif identifier_type == "phone":
59
+ logger.info(f"Searching by phone for identifier: {identifier}")
60
  user = await BookMyServiceUserModel.find_by_phone(identifier)
61
  else:
62
  logger.error(f"Invalid identifier type: {identifier_type}")
 
67
  raise HTTPException(status_code=404, detail="User not found with this email or phone")
68
 
69
  logger.info(f"User found successfully for identifier: {identifier}")
70
+ logger.info(f"User data keys: {list(user.keys()) if user else 'None'}")
71
  return user
72
 
73
  except ValueError as ve:
app/routers/user_router.py CHANGED
@@ -40,7 +40,7 @@ def get_bearer_token(api_key: str = Security(api_key_scheme)) -> str:
40
  )
41
 
42
  # If "Bearer " prefix is included, strip it
43
- logger.debug(f"Received Authorization header: {api_key}")
44
  if api_key.lower().startswith("bearer "):
45
  return api_key[7:] # Remove "Bearer " prefix
46
 
@@ -67,7 +67,7 @@ async def send_otp_login_handler(payload: OTPRequestWithLogin):
67
  # Validate identifier format
68
  try:
69
  identifier_type = validate_identifier(payload.login_input)
70
- logger.debug(f"Login input type: {identifier_type}")
71
  except ValueError as ve:
72
  logger.error(f"Invalid login input format: {str(ve)}")
73
  raise HTTPException(status_code=400, detail=str(ve))
@@ -79,22 +79,22 @@ async def send_otp_login_handler(payload: OTPRequestWithLogin):
79
  elif identifier_type == "phone":
80
  user_exists = await BookMyServiceUserModel.exists_by_email_or_phone(phone=payload.login_input)
81
 
82
- logger.debug(f"User existence check result: {user_exists}")
83
 
84
  # Send OTP via service
85
- logger.debug(f"Calling UserService.send_otp with identifier: {payload.login_input}")
86
  await UserService.send_otp(payload.login_input)
87
  logger.info(f"OTP sent successfully to: {payload.login_input}")
88
 
89
  # Create temporary token
90
- logger.debug("Creating temporary token for OTP verification")
91
  temp_token = create_temp_token({
92
  "sub": payload.login_input,
93
  "type": "otp_verification"
94
  }, expires_minutes=10)
95
 
96
  logger.info(f"Temporary token created for: {payload.login_input}")
97
- logger.debug(f"Temp token (first 20 chars): {temp_token[:20]}...")
98
 
99
  return {
100
  "message": "OTP sent",
@@ -116,13 +116,13 @@ async def otp_login_handler(
116
  temp_token: str = Depends(get_bearer_token)
117
  ):
118
  logger.info(f"OTP login attempt started - login_input: {payload.login_input}")
119
- logger.debug(f"Received temp_token: {temp_token[:20]}..." if temp_token else "No temp_token received")
120
 
121
  try:
122
  # Decode and validate temporary token
123
- logger.debug("Attempting to decode temporary token")
124
  decoded = decode_token(temp_token)
125
- logger.debug(f"Decoded token payload: {decoded}")
126
 
127
  if not decoded:
128
  logger.warning("Failed to decode temporary token - token is invalid or expired")
@@ -131,7 +131,7 @@ async def otp_login_handler(
131
  # Validate token subject matches login input
132
  token_sub = decoded.get("sub")
133
  token_type = decoded.get("type")
134
- logger.debug(f"Token subject: {token_sub}, Token type: {token_type}")
135
 
136
  if token_sub != payload.login_input:
137
  logger.warning(f"Token subject mismatch - token_sub: {token_sub}, login_input: {payload.login_input}")
@@ -144,7 +144,7 @@ async def otp_login_handler(
144
  logger.info(f"Temporary token validation successful for: {payload.login_input}")
145
 
146
  # Call user service for OTP verification and login
147
- logger.debug(f"Calling UserService.otp_login_handler with identifier: {payload.login_input}, otp: {payload.otp}")
148
  result = await UserService.otp_login_handler(payload.login_input, payload.otp)
149
 
150
  logger.info(f"OTP login successful for: {payload.login_input}")
@@ -257,7 +257,7 @@ async def oauth_login_handler(payload: OAuthLoginRequest, request: Request):
257
  }, expires_minutes=10)
258
 
259
  # Log temporary OAuth session token (truncated)
260
- logger.debug(f"OAuth temp token generated (first 25 chars): {temp_token[:25]}...")
261
 
262
  return {"access_token": temp_token, "token_type": "bearer", "user_exists": user_exists}
263
 
@@ -291,9 +291,9 @@ async def register_user(
291
  at = result.get("access_token")
292
  rt = result.get("refresh_token")
293
  if at:
294
- logger.debug(f"Register access token (first 25 chars): {at[:25]}...")
295
  if rt:
296
- logger.debug(f"Register refresh token (first 25 chars): {rt[:25]}...")
297
  return result
298
 
299
  # 🔄 Refresh access token using refresh token
@@ -304,7 +304,7 @@ async def refresh_token_handler(refresh_token: str = Depends(get_bearer_token)):
304
  try:
305
  # Decode and validate refresh token
306
  decoded = decode_token(refresh_token)
307
- logger.debug(f"Decoded refresh token payload: {decoded}")
308
 
309
  if not decoded:
310
  logger.warning("Failed to decode refresh token - token is invalid or expired")
 
40
  )
41
 
42
  # If "Bearer " prefix is included, strip it
43
+ logger.info(f"Received Authorization header: {api_key}")
44
  if api_key.lower().startswith("bearer "):
45
  return api_key[7:] # Remove "Bearer " prefix
46
 
 
67
  # Validate identifier format
68
  try:
69
  identifier_type = validate_identifier(payload.login_input)
70
+ logger.info(f"Login input type: {identifier_type}")
71
  except ValueError as ve:
72
  logger.error(f"Invalid login input format: {str(ve)}")
73
  raise HTTPException(status_code=400, detail=str(ve))
 
79
  elif identifier_type == "phone":
80
  user_exists = await BookMyServiceUserModel.exists_by_email_or_phone(phone=payload.login_input)
81
 
82
+ logger.info(f"User existence check result: {user_exists}")
83
 
84
  # Send OTP via service
85
+ logger.info(f"Calling UserService.send_otp with identifier: {payload.login_input}")
86
  await UserService.send_otp(payload.login_input)
87
  logger.info(f"OTP sent successfully to: {payload.login_input}")
88
 
89
  # Create temporary token
90
+ logger.info("Creating temporary token for OTP verification")
91
  temp_token = create_temp_token({
92
  "sub": payload.login_input,
93
  "type": "otp_verification"
94
  }, expires_minutes=10)
95
 
96
  logger.info(f"Temporary token created for: {payload.login_input}")
97
+ logger.info(f"Temp token (first 20 chars): {temp_token[:20]}...")
98
 
99
  return {
100
  "message": "OTP sent",
 
116
  temp_token: str = Depends(get_bearer_token)
117
  ):
118
  logger.info(f"OTP login attempt started - login_input: {payload.login_input}")
119
+ logger.info(f"Received temp_token: {temp_token[:20]}..." if temp_token else "No temp_token received")
120
 
121
  try:
122
  # Decode and validate temporary token
123
+ logger.info("Attempting to decode temporary token")
124
  decoded = decode_token(temp_token)
125
+ logger.info(f"Decoded token payload: {decoded}")
126
 
127
  if not decoded:
128
  logger.warning("Failed to decode temporary token - token is invalid or expired")
 
131
  # Validate token subject matches login input
132
  token_sub = decoded.get("sub")
133
  token_type = decoded.get("type")
134
+ logger.info(f"Token subject: {token_sub}, Token type: {token_type}")
135
 
136
  if token_sub != payload.login_input:
137
  logger.warning(f"Token subject mismatch - token_sub: {token_sub}, login_input: {payload.login_input}")
 
144
  logger.info(f"Temporary token validation successful for: {payload.login_input}")
145
 
146
  # Call user service for OTP verification and login
147
+ logger.info(f"Calling UserService.otp_login_handler with identifier: {payload.login_input}, otp: {payload.otp}")
148
  result = await UserService.otp_login_handler(payload.login_input, payload.otp)
149
 
150
  logger.info(f"OTP login successful for: {payload.login_input}")
 
257
  }, expires_minutes=10)
258
 
259
  # Log temporary OAuth session token (truncated)
260
+ logger.info(f"OAuth temp token generated (first 25 chars): {temp_token[:25]}...")
261
 
262
  return {"access_token": temp_token, "token_type": "bearer", "user_exists": user_exists}
263
 
 
291
  at = result.get("access_token")
292
  rt = result.get("refresh_token")
293
  if at:
294
+ logger.info(f"Register access token (first 25 chars): {at[:25]}...")
295
  if rt:
296
+ logger.info(f"Register refresh token (first 25 chars): {rt[:25]}...")
297
  return result
298
 
299
  # 🔄 Refresh access token using refresh token
 
304
  try:
305
  # Decode and validate refresh token
306
  decoded = decode_token(refresh_token)
307
+ logger.info(f"Decoded refresh token payload: {decoded}")
308
 
309
  if not decoded:
310
  logger.warning("Failed to decode refresh token - token is invalid or expired")
app/services/user_service.py CHANGED
@@ -24,7 +24,7 @@ class UserService:
24
  try:
25
  # Validate identifier format
26
  identifier_type = validate_identifier(identifier)
27
- logger.debug(f"Identifier type: {identifier_type}")
28
 
29
  # Enhanced rate limiting by IP and identifier
30
  if client_ip:
@@ -46,7 +46,7 @@ class UserService:
46
 
47
  # Generate OTP - hardcoded for testing purposes
48
  otp = '777777'
49
- logger.debug(f"Generated hardcoded OTP for identifier: {identifier}")
50
 
51
  await BookMyServiceOTPModel.store_otp(identifier, phone_number, otp)
52
 
@@ -55,7 +55,7 @@ class UserService:
55
  await BookMyServiceOTPModel.increment_rate_limit(ip_rate_key, 3600) # 1 hour window
56
 
57
  logger.info(f"OTP stored successfully for identifier: {identifier}")
58
- logger.debug(f"OTP sent to {identifier}")
59
 
60
  except ValueError as ve:
61
  logger.error(f"Validation error for identifier {identifier}: {str(ve)}")
@@ -71,7 +71,7 @@ class UserService:
71
  try:
72
  # Validate identifier format
73
  identifier_type = validate_identifier(identifier)
74
- logger.debug(f"Identifier type: {identifier_type}")
75
 
76
  # Check if account is locked
77
  if await BookMyServiceOTPModel.is_account_locked(identifier):
@@ -79,9 +79,9 @@ class UserService:
79
  raise HTTPException(status_code=423, detail="Account temporarily locked due to too many failed attempts")
80
 
81
  # Verify OTP with client IP tracking
82
- logger.debug(f"Verifying OTP for identifier: {identifier}")
83
  otp_valid = await BookMyServiceOTPModel.verify_otp(identifier, otp, client_ip)
84
- logger.debug(f"OTP verification result: {otp_valid}")
85
 
86
  if not otp_valid:
87
  logger.warning(f"Invalid or expired OTP for identifier: {identifier}")
@@ -94,9 +94,9 @@ class UserService:
94
  logger.info(f"OTP verification successful for identifier: {identifier}")
95
 
96
  # Find user by identifier
97
- logger.debug(f"Looking up user by identifier: {identifier}")
98
  user = await BookMyServiceUserModel.find_by_identifier(identifier)
99
- logger.debug(f"User lookup result: {user is not None}")
100
 
101
  if not user:
102
  logger.warning(f"No user found for identifier: {identifier}")
@@ -105,12 +105,12 @@ class UserService:
105
  logger.info(f"User found for identifier: {identifier}, customer_id: {user.get('customer_id')}")
106
 
107
  # Create JWT token
108
- logger.debug("Creating JWT token for authenticated user")
109
  token_data = {
110
  "sub": user.get("customer_id"),
111
  "exp": datetime.utcnow() + timedelta(hours=8)
112
  }
113
- logger.debug(f"Token data: {token_data}")
114
 
115
  access_token = jwt.encode(token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
116
 
@@ -122,8 +122,8 @@ class UserService:
122
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
123
 
124
  # Log generated tokens (truncated for security)
125
- logger.debug(f"Access token generated (first 25 chars): {access_token[:25]}...")
126
- logger.debug(f"Refresh token generated (first 25 chars): {refresh_token[:25]}...")
127
 
128
  logger.info(f"JWT tokens created successfully for user: {user.get('customer_id')}")
129
 
@@ -174,7 +174,7 @@ class UserService:
174
  identifier_type = validate_identifier(identifier)
175
  if identifier_type != "phone":
176
  raise ValueError("Phone number format is invalid")
177
- logger.debug(f"Registration identifier type: {identifier_type}")
178
  except ValueError as ve:
179
  logger.error(f"Invalid phone format during registration: {str(ve)}")
180
  raise HTTPException(status_code=400, detail=str(ve))
@@ -230,8 +230,8 @@ class UserService:
230
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
231
 
232
  # Log generated tokens for existing linked user (truncated)
233
- logger.debug(f"Access token for existing user (first 25 chars): {access_token[:25]}...")
234
- logger.debug(f"Refresh token for existing user (first 25 chars): {refresh_token[:25]}...")
235
 
236
  return {
237
  "access_token": access_token,
@@ -297,8 +297,8 @@ class UserService:
297
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
298
 
299
  # Log generated tokens for new registration (truncated)
300
- logger.debug(f"Access token on register (first 25 chars): {access_token[:25]}...")
301
- logger.debug(f"Refresh token on register (first 25 chars): {refresh_token[:25]}...")
302
 
303
  return {
304
  "access_token": access_token,
 
24
  try:
25
  # Validate identifier format
26
  identifier_type = validate_identifier(identifier)
27
+ logger.info(f"Identifier type: {identifier_type}")
28
 
29
  # Enhanced rate limiting by IP and identifier
30
  if client_ip:
 
46
 
47
  # Generate OTP - hardcoded for testing purposes
48
  otp = '777777'
49
+ logger.info(f"Generated hardcoded OTP for identifier: {identifier}")
50
 
51
  await BookMyServiceOTPModel.store_otp(identifier, phone_number, otp)
52
 
 
55
  await BookMyServiceOTPModel.increment_rate_limit(ip_rate_key, 3600) # 1 hour window
56
 
57
  logger.info(f"OTP stored successfully for identifier: {identifier}")
58
+ logger.info(f"OTP sent to {identifier}")
59
 
60
  except ValueError as ve:
61
  logger.error(f"Validation error for identifier {identifier}: {str(ve)}")
 
71
  try:
72
  # Validate identifier format
73
  identifier_type = validate_identifier(identifier)
74
+ logger.info(f"Identifier type: {identifier_type}")
75
 
76
  # Check if account is locked
77
  if await BookMyServiceOTPModel.is_account_locked(identifier):
 
79
  raise HTTPException(status_code=423, detail="Account temporarily locked due to too many failed attempts")
80
 
81
  # Verify OTP with client IP tracking
82
+ logger.info(f"Verifying OTP for identifier: {identifier}")
83
  otp_valid = await BookMyServiceOTPModel.verify_otp(identifier, otp, client_ip)
84
+ logger.info(f"OTP verification result: {otp_valid}")
85
 
86
  if not otp_valid:
87
  logger.warning(f"Invalid or expired OTP for identifier: {identifier}")
 
94
  logger.info(f"OTP verification successful for identifier: {identifier}")
95
 
96
  # Find user by identifier
97
+ logger.info(f"Looking up user by identifier: {identifier}")
98
  user = await BookMyServiceUserModel.find_by_identifier(identifier)
99
+ logger.info(f"User lookup result: {user is not None}")
100
 
101
  if not user:
102
  logger.warning(f"No user found for identifier: {identifier}")
 
105
  logger.info(f"User found for identifier: {identifier}, customer_id: {user.get('customer_id')}")
106
 
107
  # Create JWT token
108
+ logger.info("Creating JWT token for authenticated user")
109
  token_data = {
110
  "sub": user.get("customer_id"),
111
  "exp": datetime.utcnow() + timedelta(hours=8)
112
  }
113
+ logger.info(f"Token data: {token_data}")
114
 
115
  access_token = jwt.encode(token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
116
 
 
122
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
123
 
124
  # Log generated tokens (truncated for security)
125
+ logger.info(f"Access token generated (first 25 chars): {access_token[:25]}...")
126
+ logger.info(f"Refresh token generated (first 25 chars): {refresh_token[:25]}...")
127
 
128
  logger.info(f"JWT tokens created successfully for user: {user.get('customer_id')}")
129
 
 
174
  identifier_type = validate_identifier(identifier)
175
  if identifier_type != "phone":
176
  raise ValueError("Phone number format is invalid")
177
+ logger.info(f"Registration identifier type: {identifier_type}")
178
  except ValueError as ve:
179
  logger.error(f"Invalid phone format during registration: {str(ve)}")
180
  raise HTTPException(status_code=400, detail=str(ve))
 
230
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
231
 
232
  # Log generated tokens for existing linked user (truncated)
233
+ logger.info(f"Access token for existing user (first 25 chars): {access_token[:25]}...")
234
+ logger.info(f"Refresh token for existing user (first 25 chars): {refresh_token[:25]}...")
235
 
236
  return {
237
  "access_token": access_token,
 
297
  refresh_token = jwt.encode(refresh_token_data, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
298
 
299
  # Log generated tokens for new registration (truncated)
300
+ logger.info(f"Access token on register (first 25 chars): {access_token[:25]}...")
301
+ logger.info(f"Refresh token on register (first 25 chars): {refresh_token[:25]}...")
302
 
303
  return {
304
  "access_token": access_token,