ipulse-shared-core-ftredge 23.1.1__tar.gz → 24.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ipulse-shared-core-ftredge might be problematic. Click here for more details.

Files changed (57) hide show
  1. {ipulse_shared_core_ftredge-23.1.1/src/ipulse_shared_core_ftredge.egg-info → ipulse_shared_core_ftredge-24.2.1}/PKG-INFO +2 -2
  2. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/setup.py +2 -2
  3. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/dependencies/auth_firebase_token_validation.py +1 -1
  4. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/__init__.py +1 -1
  5. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/__init__.py +1 -1
  6. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/user_permissions.py +4 -8
  7. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/userauth.py +46 -3
  8. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/userstatus.py +3 -3
  9. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/user_core_service.py +5 -5
  10. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/user_multistep_operations.py +7 -7
  11. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/userauth_operations.py +9 -4
  12. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1/src/ipulse_shared_core_ftredge.egg-info}/PKG-INFO +2 -2
  13. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge.egg-info/requires.txt +1 -1
  14. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/LICENCE +0 -0
  15. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/README.md +0 -0
  16. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/pyproject.toml +0 -0
  17. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/setup.cfg +0 -0
  18. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/__init__.py +0 -0
  19. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/cache/__init__.py +0 -0
  20. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/cache/shared_cache.py +0 -0
  21. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/dependencies/__init__.py +0 -0
  22. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/dependencies/auth_protected_router.py +0 -0
  23. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/dependencies/authz_for_apis.py +0 -0
  24. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/dependencies/firestore_client.py +0 -0
  25. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/exceptions/__init__.py +0 -0
  26. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/exceptions/base_exceptions.py +0 -0
  27. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/exceptions/user_exceptions.py +0 -0
  28. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/base_api_response.py +0 -0
  29. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/base_data_model.py +0 -0
  30. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/catalog/__init__.py +0 -0
  31. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/catalog/subscriptionplan.py +0 -0
  32. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/catalog/usertype.py +0 -0
  33. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/user_subscription.py +0 -0
  34. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/models/user/userprofile.py +0 -0
  35. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/monitoring/__init__.py +0 -0
  36. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/monitoring/tracemon.py +0 -0
  37. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/__init__.py +0 -0
  38. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/base/__init__.py +0 -0
  39. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/base/base_firestore_service.py +0 -0
  40. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/base/cache_aware_firestore_service.py +0 -0
  41. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/catalog/__init__.py +0 -0
  42. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/catalog/catalog_subscriptionplan_service.py +0 -0
  43. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/catalog/catalog_usertype_service.py +0 -0
  44. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/charging_processors.py +0 -0
  45. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/__init__.py +0 -0
  46. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/user_permissions_operations.py +0 -0
  47. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/user_subscription_operations.py +0 -0
  48. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/userprofile_operations.py +0 -0
  49. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user/userstatus_operations.py +0 -0
  50. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/services/user_charging_service.py +0 -0
  51. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/utils/__init__.py +0 -0
  52. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/utils/custom_json_encoder.py +0 -0
  53. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge/utils/json_encoder.py +0 -0
  54. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge.egg-info/SOURCES.txt +0 -0
  55. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge.egg-info/dependency_links.txt +0 -0
  56. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/src/ipulse_shared_core_ftredge.egg-info/top_level.txt +0 -0
  57. {ipulse_shared_core_ftredge-23.1.1 → ipulse_shared_core_ftredge-24.2.1}/tests/test_shared_cache.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ipulse_shared_core_ftredge
3
- Version: 23.1.1
3
+ Version: 24.2.1
4
4
  Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
5
5
  Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
6
6
  Author: Russlan Ramdowar
@@ -12,7 +12,7 @@ License-File: LICENCE
12
12
  Requires-Dist: pydantic[email]~=2.5
13
13
  Requires-Dist: python-dateutil~=2.8
14
14
  Requires-Dist: fastapi~=0.115.8
15
- Requires-Dist: ipulse_shared_base_ftredge==10.2.1
15
+ Requires-Dist: ipulse_shared_base_ftredge==11.1.1
16
16
  Dynamic: author
17
17
  Dynamic: classifier
18
18
  Dynamic: home-page
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
3
3
 
4
4
  setup(
5
5
  name='ipulse_shared_core_ftredge',
6
- version='23.1.1',
6
+ version='24.2.1',
7
7
  package_dir={'': 'src'}, # Specify the source directory
8
8
  packages=find_packages(where='src'), # Look for packages in 'src'
9
9
  install_requires=[
@@ -11,7 +11,7 @@ setup(
11
11
  'pydantic[email]~=2.5',
12
12
  'python-dateutil~=2.8',
13
13
  'fastapi~=0.115.8',
14
- 'ipulse_shared_base_ftredge==10.2.1',
14
+ 'ipulse_shared_base_ftredge==11.1.1',
15
15
  ],
16
16
  author='Russlan Ramdowar',
17
17
  description='Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.',
@@ -72,7 +72,7 @@ async def verify_firebase_token(
72
72
  email=email,
73
73
  password=None, # No password for token-based auth
74
74
  display_name=decoded_token.get('name'),
75
- firebase_uid=decoded_token.get('uid'),
75
+ user_uid=decoded_token.get('uid'),
76
76
  email_verified=decoded_token.get('email_verified', False),
77
77
  custom_claims=decoded_token.get('custom_claims', {}),
78
78
  phone_number=decoded_token.get('phone_number'),
@@ -1,4 +1,4 @@
1
1
  from .base_data_model import BaseDataModel
2
2
  from .base_api_response import BaseAPIResponse , CustomJSONResponse, CreditChargeableAPIResponse, UserCreditBalance, UpdatedUserCreditInfo
3
- from .user import UserProfile, UserSubscription, UserStatus, UserAuth, UserPermission
3
+ from .user import UserProfile, UserSubscription, UserStatus, UserAuth, UserAuthCreateNew, UserPermission
4
4
  from .catalog import SubscriptionPlan, ProrationMethod, PlanUpgradePath, UserType
@@ -2,4 +2,4 @@ from .userprofile import UserProfile
2
2
  from .user_subscription import UserSubscription
3
3
  from .user_permissions import UserPermission
4
4
  from .userstatus import UserStatus
5
- from .userauth import UserAuth
5
+ from .userauth import UserAuth, UserAuthCreateNew
@@ -28,9 +28,9 @@ class UserPermission(BaseModel):
28
28
  ...,
29
29
  description="Source of this assignment (e.g., subscription plan ID, 'manual_grant')"
30
30
  )
31
- expires_at: Optional[datetime] = Field(
32
- default=None,
33
- description="When this assignment expires (None for permanent)"
31
+ expires_at: datetime = Field(
32
+ ...,
33
+ description="When this assignment expires (mandatory - no permanent permissions)"
34
34
  )
35
35
  granted_at: datetime = Field(
36
36
  default_factory=lambda: datetime.now(timezone.utc),
@@ -47,9 +47,6 @@ class UserPermission(BaseModel):
47
47
 
48
48
  def is_valid(self) -> bool:
49
49
  """Check if the permission is currently valid (not expired)."""
50
- if self.expires_at is None:
51
- return True
52
-
53
50
  # Ensure both datetimes are timezone-aware for comparison
54
51
  current_time = datetime.now(timezone.utc)
55
52
  expires_time = self.expires_at
@@ -62,5 +59,4 @@ class UserPermission(BaseModel):
62
59
 
63
60
  def __str__(self) -> str:
64
61
  """Human-readable representation of the permission."""
65
- expiry = f" (expires: {self.expires_at})" if self.expires_at else " (permanent)"
66
- return f"{self.domain}/{self.iam_unit_type}/{self.permission_ref} from {self.source}{expiry}"
62
+ return f"{self.domain}/{self.iam_unit_type}/{self.permission_ref} from {self.source} (expires: {self.expires_at})"
@@ -2,17 +2,60 @@ from typing import Optional, Dict, Any, List
2
2
  from datetime import datetime
3
3
  from pydantic import BaseModel, Field, EmailStr, ConfigDict, field_validator, model_validator
4
4
 
5
+ class UserAuthCreateNew(BaseModel):
6
+ """Model for creating new Firebase Auth users - does not include user_uid"""
7
+ model_config = ConfigDict(extra="forbid")
8
+
9
+ # Core authentication fields for new user creation
10
+ email: EmailStr = Field(..., description="User's email address")
11
+ password: str = Field(..., min_length=6, description="User's password (min 6 characters)")
12
+ display_name: Optional[str] = Field(None, description="User's display name")
13
+ phone_number: Optional[str] = Field(None, description="Phone number in E.164 format (e.g. +1234567890)")
14
+ email_verified: bool = Field(default=False, description="Whether the email is already verified")
15
+ disabled: bool = Field(default=False, description="Whether the user should be disabled on creation")
16
+
17
+ # Custom claims for new user
18
+ custom_claims: Dict[str, Any] = Field(default_factory=dict, description="Firebase custom claims")
19
+
20
+ @field_validator('phone_number')
21
+ @classmethod
22
+ def validate_phone_number(cls, v: Optional[str]) -> Optional[str]:
23
+ """Validate phone number format if provided"""
24
+ if v is None:
25
+ return v
26
+ # Basic E.164 format validation
27
+ if not v.startswith('+') or not v[1:].isdigit() or len(v) < 8 or len(v) > 16:
28
+ raise ValueError('Phone number must be in E.164 format (+1234567890)')
29
+ return v
30
+
31
+ @field_validator('custom_claims')
32
+ @classmethod
33
+ def validate_custom_claims(cls, v: Dict[str, Any]) -> Dict[str, Any]:
34
+ """Validate custom claims don't contain reserved Firebase claims"""
35
+ reserved_claims = {
36
+ 'iss', 'aud', 'auth_time', 'user_id', 'sub', 'iat', 'exp', 'email',
37
+ 'email_verified', 'phone_number', 'name', 'picture', 'firebase'
38
+ }
39
+
40
+ for claim in v.keys():
41
+ if claim in reserved_claims:
42
+ raise ValueError(f'Custom claim "{claim}" is reserved by Firebase')
43
+
44
+ return v
45
+
5
46
  class UserAuth(BaseModel):
6
- """Comprehensive authentication model for user credentials and auth operations"""
47
+ """Comprehensive authentication model for existing user credentials and auth operations"""
7
48
  model_config = ConfigDict(extra="forbid")
8
49
 
50
+ # Firebase UID - required for existing users (generated by Firebase when user was created)
51
+ user_uid: str = Field(..., description="Firebase Auth UID - required for existing users")
52
+
9
53
  # Core authentication fields
10
54
  email: EmailStr = Field(..., description="User's email address")
11
55
  display_name: Optional[str] = Field(None, description="User's display name")
12
- password: Optional[str] = Field(None, min_length=6, description="User's password (for creation/update only)")
56
+ password: Optional[str] = Field(None, min_length=6, description="User's password (for updates only)")
13
57
 
14
58
  # Firebase Auth specific fields
15
- firebase_uid: Optional[str] = Field(default=None, description="Firebase Auth UID")
16
59
  provider_id: str = Field(default="password", description="Authentication provider ID")
17
60
  email_verified: bool = Field(default=False, description="Whether email is verified")
18
61
  disabled: bool = Field(default=False, description="Whether user account is disabled")
@@ -187,7 +187,7 @@ class UserStatus(BaseDataModel):
187
187
  iam_unit_type: IAMUnit,
188
188
  permission_ref: str,
189
189
  source: str,
190
- expires_at: Optional[datetime] = None,
190
+ expires_at: datetime,
191
191
  granted_by: Optional[str] = None,
192
192
  metadata: Optional[Dict[str, Any]] = None
193
193
  ) -> None:
@@ -199,7 +199,7 @@ class UserStatus(BaseDataModel):
199
199
  iam_unit_type: Type of IAM assignment (GROUP, ROLE, etc.)
200
200
  permission_ref: The name/identifier of the permission to add
201
201
  source: Source identifier for this assignment (e.g., subscription ID)
202
- expires_at: Optional expiration date
202
+ expires_at: Expiration date (mandatory - no permanent permissions)
203
203
  granted_by: Who granted this permission
204
204
  metadata: Optional metadata for the assignment
205
205
  """
@@ -329,7 +329,7 @@ class UserStatus(BaseDataModel):
329
329
  iam_unit_type=permission.iam_unit_type,
330
330
  permission_ref=permission.permission_ref,
331
331
  source=source,
332
- expires_at=subscription.cycle_end_datetime,
332
+ expires_at=subscription.cycle_end_datetime_safe,
333
333
  granted_by=granted_by
334
334
  )
335
335
  added_count += 1
@@ -18,7 +18,7 @@ from datetime import datetime
18
18
  from google.cloud import firestore
19
19
  from firebase_admin.auth import UserRecord
20
20
  from ipulse_shared_base_ftredge import ApprovalStatus, IAMUnit, IAMUserType
21
- from ...models import UserProfile, UserStatus, UserAuth, UserSubscription, UserType, SubscriptionPlan, UserPermission
21
+ from ...models import UserProfile, UserStatus, UserAuth, UserAuthCreateNew, UserSubscription, UserType, SubscriptionPlan, UserPermission
22
22
 
23
23
 
24
24
  # Import specialized operation classes
@@ -132,7 +132,7 @@ class UserCoreService:
132
132
  self,
133
133
  userprofile: UserProfile,
134
134
  userstatus: UserStatus,
135
- userauth: Optional[UserAuth] = None,
135
+ userauth: Optional[UserAuthCreateNew] = None,
136
136
  validate_userauth_consistency: bool = False,
137
137
  validate_userauth_exists: bool = False
138
138
  ) -> Tuple[str, UserProfile, UserStatus]:
@@ -153,7 +153,7 @@ class UserCoreService:
153
153
  self,
154
154
  userprofile: UserProfile,
155
155
  usertype: UserType,
156
- userauth: Optional[UserAuth] = None,
156
+ userauth: Optional[UserAuthCreateNew] = None,
157
157
  extra_insight_credits_override: Optional[int] = None,
158
158
  voting_credits_override: Optional[int] = None,
159
159
  subscriptionplan_id_override: Optional[str] = None,
@@ -184,7 +184,7 @@ class UserCoreService:
184
184
  self,
185
185
  usertype_id: str,
186
186
  userprofile: UserProfile,
187
- userauth: Optional[UserAuth] = None,
187
+ userauth: Optional[UserAuthCreateNew] = None,
188
188
  extra_insight_credits_override: Optional[int] = None,
189
189
  voting_credits_override: Optional[int] = None,
190
190
  subscriptionplan_id_override: Optional[str] = None,
@@ -294,7 +294,7 @@ class UserCoreService:
294
294
  ######################### UserAuth Operations ########################
295
295
  ######################################################################
296
296
 
297
- async def create_userauth(self, userauth: UserAuth) -> str:
297
+ async def create_userauth(self, userauth: UserAuthCreateNew) -> str:
298
298
  """Create a Firebase Auth user"""
299
299
  return await self.userauth_ops.create_userauth(user_auth=userauth)
300
300
 
@@ -8,7 +8,7 @@ import asyncio
8
8
  import logging
9
9
  from typing import Dict, Any, Optional, List, Tuple, cast
10
10
  from ipulse_shared_base_ftredge.enums import IAMUserType
11
- from ...models import UserProfile, UserStatus, UserAuth, UserType
11
+ from ...models import UserProfile, UserStatus, UserAuth, UserAuthCreateNew, UserType
12
12
  from .userauth_operations import UserauthOperations
13
13
  from .userprofile_operations import UserprofileOperations
14
14
  from .userstatus_operations import UserstatusOperations
@@ -130,12 +130,12 @@ class UsermultistepOperations:
130
130
  self,
131
131
  userprofile: UserProfile,
132
132
  userstatus: UserStatus,
133
- userauth: Optional[UserAuth] = None,
133
+ userauth: Optional[UserAuthCreateNew] = None,
134
134
  validate_userauth_consistency: bool = False,
135
135
  validate_userauth_exists: bool = False
136
136
  ) -> Tuple[str, UserProfile, UserStatus]:
137
137
  """
138
- Create a complete user from ready UserAuth, UserProfile, and UserStatus models.
138
+ Create a complete user from ready UserAuthCreateNew, UserProfile, and UserStatus models.
139
139
 
140
140
  This method efficiently commits pre-configured models to database.
141
141
 
@@ -151,7 +151,7 @@ class UsermultistepOperations:
151
151
  Args:
152
152
  userprofile: Complete UserProfile model (template for new user, or ready for existing user)
153
153
  userstatus: Complete UserStatus model (template for new user, or ready for existing user)
154
- userauth: Optional UserAuth model. If provided, creates new Firebase Auth user
154
+ userauth: Optional UserAuthCreateNew model. If provided, creates new Firebase Auth user
155
155
  validate_userauth_consistency: If True, validates userauth is consistent with userprofile
156
156
  validate_userauth_exists: If True, validates userauth exists in Firebase Auth
157
157
 
@@ -242,7 +242,7 @@ class UsermultistepOperations:
242
242
  self,
243
243
  userprofile: UserProfile,
244
244
  usertype: UserType,
245
- userauth: Optional[UserAuth] = None,
245
+ userauth: Optional[UserAuthCreateNew] = None,
246
246
  extra_insight_credits_override: Optional[int] = None,
247
247
  voting_credits_override: Optional[int] = None,
248
248
  subscriptionplan_id_override: Optional[str] = None,
@@ -344,7 +344,7 @@ class UsermultistepOperations:
344
344
  self,
345
345
  usertype_id: str,
346
346
  userprofile: UserProfile,
347
- userauth: Optional[UserAuth] = None,
347
+ userauth: Optional[UserAuthCreateNew] = None,
348
348
  extra_insight_credits_override: Optional[int] = None,
349
349
  voting_credits_override: Optional[int] = None,
350
350
  subscriptionplan_id_override: Optional[str] = None,
@@ -647,7 +647,7 @@ class UsermultistepOperations:
647
647
  validation_results["validation_errors"].append("User email is not verified")
648
648
 
649
649
  # 3. UID consistency validation
650
- auth_uid = getattr(userauth_record, 'uid', None) or getattr(userauth_record, 'firebase_uid', None)
650
+ auth_uid = getattr(userauth_record, 'uid', None) or getattr(userauth_record, 'user_uid', None)
651
651
  uids_consistent = (
652
652
  auth_uid == user_uid and
653
653
  userprofile.user_uid == user_uid and
@@ -9,7 +9,7 @@ from typing import Dict, Any, Optional, Union
9
9
  from firebase_admin import auth
10
10
  from google.cloud import firestore
11
11
  from ipulse_shared_base_ftredge.enums import ApprovalStatus
12
- from ...models import UserAuth
12
+ from ...models import UserAuth, UserAuthCreateNew
13
13
  from ...exceptions import UserAuthError
14
14
  from ..base import BaseFirestoreService
15
15
 
@@ -48,9 +48,14 @@ class UserauthOperations:
48
48
 
49
49
  async def create_userauth(
50
50
  self,
51
- user_auth: UserAuth
51
+ user_auth: UserAuthCreateNew
52
52
  ) -> str:
53
- """Creates a new Firebase Auth user and returns the UID."""
53
+ """
54
+ Creates a new Firebase Auth user and returns the UID.
55
+
56
+ Args:
57
+ user_auth: UserAuthCreateNew model for new user creation
58
+ """
54
59
  self.logger.info(f"Creating Firebase Auth user for email: {user_auth.email}")
55
60
  try:
56
61
  # Create user synchronously
@@ -191,7 +196,7 @@ class UserauthOperations:
191
196
  userauth_data = {
192
197
  "email": user_record.email,
193
198
  "display_name": user_record.display_name,
194
- "firebase_uid": user_record.uid,
199
+ "user_uid": user_record.uid,
195
200
  "email_verified": user_record.email_verified,
196
201
  "disabled": user_record.disabled,
197
202
  "phone_number": user_record.phone_number,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ipulse_shared_core_ftredge
3
- Version: 23.1.1
3
+ Version: 24.2.1
4
4
  Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
5
5
  Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
6
6
  Author: Russlan Ramdowar
@@ -12,7 +12,7 @@ License-File: LICENCE
12
12
  Requires-Dist: pydantic[email]~=2.5
13
13
  Requires-Dist: python-dateutil~=2.8
14
14
  Requires-Dist: fastapi~=0.115.8
15
- Requires-Dist: ipulse_shared_base_ftredge==10.2.1
15
+ Requires-Dist: ipulse_shared_base_ftredge==11.1.1
16
16
  Dynamic: author
17
17
  Dynamic: classifier
18
18
  Dynamic: home-page
@@ -1,4 +1,4 @@
1
1
  pydantic[email]~=2.5
2
2
  python-dateutil~=2.8
3
3
  fastapi~=0.115.8
4
- ipulse_shared_base_ftredge==10.2.1
4
+ ipulse_shared_base_ftredge==11.1.1