From f9a7cd7855692f1ba646ab42d8d6d23e24e935f1 Mon Sep 17 00:00:00 2001 From: Dhruvkumar-Microsoft Date: Thu, 13 Aug 2026 19:11:30 +0530 Subject: [PATCH] updated the team upload funcationality while rerunning the postdeployment script --- .../post-provision/upload_team_config.py | 16 ---------- src/backend/api/router.py | 12 ++++---- src/backend/services/team_service.py | 30 +++++++++++++++---- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/infra/scripts/post-provision/upload_team_config.py b/infra/scripts/post-provision/upload_team_config.py index 9d4b85952..111986a35 100644 --- a/infra/scripts/post-provision/upload_team_config.py +++ b/infra/scripts/post-provision/upload_team_config.py @@ -115,22 +115,6 @@ def check_team_exists(backend_url, team_id, user_principal_id): for filename, team_id in candidate_files: file_path = os.path.join(directory_path, filename) print(f"Uploading file: {filename}") - team_exists = check_team_exists(backend_url, team_id, user_principal_id) - if team_exists: - # Delete existing team to allow re-upload with updated config - print(f"Team (ID: {team_id}) already exists. Deleting to re-upload with latest config...") - delete_endpoint = backend_url.rstrip('/') + f'/api/v4/team_configs/{team_id}' - headers = { - 'x-ms-client-principal-id': user_principal_id - } - try: - delete_response = request_with_retry("DELETE", delete_endpoint, headers=headers) - if delete_response.status_code == 200: - print(f"Successfully deleted existing team (ID: {team_id}).") - else: - print(f"Warning: Could not delete existing team (ID: {team_id}). Status: {delete_response.status_code}. Will attempt upload anyway.") - except Exception as e: - print(f"Warning: Exception deleting team (ID: {team_id}): {str(e)}. Will attempt upload anyway.") try: with open(file_path, 'rb') as file_data: diff --git a/src/backend/api/router.py b/src/backend/api/router.py index 2297e9571..dc169fec8 100644 --- a/src/backend/api/router.py +++ b/src/backend/api/router.py @@ -1008,7 +1008,7 @@ async def upload_team_config( { "status": "failed", "user_id": user_id, - "filename": file.filename, + "file_name": file.filename, "reason": rai_error, }, ) @@ -1016,7 +1016,7 @@ async def upload_team_config( track_event_if_configured( "Config_RAI_Validation_Passed", - {"status": "passed", "user_id": user_id, "filename": file.filename}, + {"status": "passed", "user_id": user_id, "file_name": file.filename}, ) team_service = TeamService(memory_store) @@ -1034,7 +1034,7 @@ async def upload_team_config( { "status": "failed", "user_id": user_id, - "filename": file.filename, + "file_name": file.filename, "missing_models": missing_models, }, ) @@ -1042,7 +1042,7 @@ async def upload_team_config( track_event_if_configured( "Config_Model_Validation_Passed", - {"status": "passed", "user_id": user_id, "filename": file.filename}, + {"status": "passed", "user_id": user_id, "file_name": file.filename}, ) # Validate search indexes @@ -1061,7 +1061,7 @@ async def upload_team_config( { "status": "failed", "user_id": user_id, - "filename": file.filename, + "file_name": file.filename, "search_errors": search_errors, }, ) @@ -1070,7 +1070,7 @@ async def upload_team_config( logger.info(f"Search validation passed for user: {user_id}") track_event_if_configured( "Config_Search_Validation_Passed", - {"status": "passed", "user_id": user_id, "filename": file.filename}, + {"status": "passed", "user_id": user_id, "file_name": file.filename}, ) # Validate and parse the team configuration diff --git a/src/backend/services/team_service.py b/src/backend/services/team_service.py index 66a56c967..c7dea543d 100644 --- a/src/backend/services/team_service.py +++ b/src/backend/services/team_service.py @@ -164,6 +164,11 @@ async def save_team_configuration(self, team_config: TeamConfiguration) -> str: """ Save team configuration to the database. + Idempotent by team_id: if a team with the same team_id already exists + (including shared default teams), reuse its document id and partition + key (session_id) and upsert; otherwise create a new document. This + prevents duplicate rows accumulating on re-runs of the seed script. + Args: team_config: TeamConfiguration object to save @@ -171,12 +176,25 @@ async def save_team_configuration(self, team_config: TeamConfiguration) -> str: The unique ID of the saved configuration """ try: - # Use the specific add_team method from cosmos memory context - await self.memory_context.add_team(team_config) - - self.logger.info( - "Successfully saved team configuration with ID: %s", team_config.id - ) + existing = await self.memory_context.get_team(team_config.team_id) + if existing is not None: + # Preserve immutable identity fields; partition key (session_id) + # cannot change on an upsert. + team_config.id = existing.id + team_config.session_id = existing.session_id + team_config.created = existing.created + team_config.created_by = existing.created_by + await self.memory_context.update_team(team_config) + self.logger.info( + "Successfully updated team configuration with ID: %s", + team_config.id, + ) + else: + await self.memory_context.add_team(team_config) + self.logger.info( + "Successfully saved team configuration with ID: %s", + team_config.id, + ) return team_config.id except Exception as e: