Improve the frontend and fix TODOs
This commit is contained in:
@@ -127,31 +127,135 @@ class TenantMemberRepository(TenantBaseRepository):
|
||||
raise DatabaseError(f"Failed to get membership: {str(e)}")
|
||||
|
||||
async def get_tenant_members(
|
||||
self,
|
||||
tenant_id: str,
|
||||
self,
|
||||
tenant_id: str,
|
||||
active_only: bool = True,
|
||||
role: str = None
|
||||
role: str = None,
|
||||
include_user_info: bool = False
|
||||
) -> List[TenantMember]:
|
||||
"""Get all members of a tenant"""
|
||||
"""Get all members of a tenant with optional user info enrichment"""
|
||||
try:
|
||||
filters = {"tenant_id": tenant_id}
|
||||
|
||||
|
||||
if active_only:
|
||||
filters["is_active"] = True
|
||||
|
||||
|
||||
if role:
|
||||
filters["role"] = role
|
||||
|
||||
return await self.get_multi(
|
||||
|
||||
members = await self.get_multi(
|
||||
filters=filters,
|
||||
order_by="joined_at",
|
||||
order_desc=False
|
||||
)
|
||||
|
||||
# If include_user_info is True, enrich with user data from auth service
|
||||
if include_user_info and members:
|
||||
members = await self._enrich_members_with_user_info(members)
|
||||
|
||||
return members
|
||||
except Exception as e:
|
||||
logger.error("Failed to get tenant members",
|
||||
tenant_id=tenant_id,
|
||||
error=str(e))
|
||||
raise DatabaseError(f"Failed to get members: {str(e)}")
|
||||
|
||||
async def _enrich_members_with_user_info(self, members: List[TenantMember]) -> List[TenantMember]:
|
||||
"""Enrich member objects with user information from auth service using batch endpoint"""
|
||||
try:
|
||||
import httpx
|
||||
import os
|
||||
|
||||
if not members:
|
||||
return members
|
||||
|
||||
# Get unique user IDs
|
||||
user_ids = list(set([str(member.user_id) for member in members]))
|
||||
|
||||
if not user_ids:
|
||||
return members
|
||||
|
||||
# Fetch user data from auth service using batch endpoint
|
||||
# Using internal service communication
|
||||
auth_service_url = os.getenv('AUTH_SERVICE_URL', 'http://auth-service:8000')
|
||||
|
||||
user_data_map = {}
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
# Use batch endpoint for efficiency
|
||||
response = await client.post(
|
||||
f"{auth_service_url}/api/v1/auth/users/batch",
|
||||
json={"user_ids": user_ids},
|
||||
timeout=10.0,
|
||||
headers={"X-Internal-Service": "tenant-service"}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
batch_result = response.json()
|
||||
user_data_map = batch_result.get("users", {})
|
||||
logger.info(
|
||||
"Batch user fetch successful",
|
||||
requested_count=len(user_ids),
|
||||
found_count=batch_result.get("found_count", 0)
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
"Batch user fetch failed, falling back to individual calls",
|
||||
status_code=response.status_code
|
||||
)
|
||||
# Fallback to individual calls if batch fails
|
||||
for user_id in user_ids:
|
||||
try:
|
||||
response = await client.get(
|
||||
f"{auth_service_url}/api/v1/auth/users/{user_id}",
|
||||
timeout=5.0,
|
||||
headers={"X-Internal-Service": "tenant-service"}
|
||||
)
|
||||
if response.status_code == 200:
|
||||
user_data = response.json()
|
||||
user_data_map[user_id] = user_data
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to fetch user data for {user_id}", error=str(e))
|
||||
continue
|
||||
|
||||
except Exception as e:
|
||||
logger.warning("Batch user fetch failed, falling back to individual calls", error=str(e))
|
||||
# Fallback to individual calls
|
||||
for user_id in user_ids:
|
||||
try:
|
||||
response = await client.get(
|
||||
f"{auth_service_url}/api/v1/auth/users/{user_id}",
|
||||
timeout=5.0,
|
||||
headers={"X-Internal-Service": "tenant-service"}
|
||||
)
|
||||
if response.status_code == 200:
|
||||
user_data = response.json()
|
||||
user_data_map[user_id] = user_data
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to fetch user data for {user_id}", error=str(e))
|
||||
continue
|
||||
|
||||
# Enrich members with user data
|
||||
for member in members:
|
||||
user_id_str = str(member.user_id)
|
||||
if user_id_str in user_data_map and user_data_map[user_id_str] is not None:
|
||||
user_data = user_data_map[user_id_str]
|
||||
# Add user fields as attributes to the member object
|
||||
member.user_email = user_data.get("email")
|
||||
member.user_full_name = user_data.get("full_name")
|
||||
member.user = user_data # Store full user object for compatibility
|
||||
else:
|
||||
# Set defaults for missing users
|
||||
member.user_email = None
|
||||
member.user_full_name = "Unknown User"
|
||||
member.user = None
|
||||
|
||||
return members
|
||||
|
||||
except Exception as e:
|
||||
logger.warning("Failed to enrich members with user info", error=str(e))
|
||||
# Return members without enrichment if it fails
|
||||
return members
|
||||
|
||||
async def get_user_memberships(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user