Skip to content

Commit 165a839

Browse files
Merge pull request #1140 from microsoft/psl-duplicateTeamIssue
fix: updated the team upload functionality while rerunning the post deployment script to fix duplicate team issue
2 parents da0d8e5 + f9a7cd7 commit 165a839

3 files changed

Lines changed: 30 additions & 28 deletions

File tree

infra/scripts/post-provision/upload_team_config.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,6 @@ def check_team_exists(backend_url, team_id, user_principal_id):
115115
for filename, team_id in candidate_files:
116116
file_path = os.path.join(directory_path, filename)
117117
print(f"Uploading file: {filename}")
118-
team_exists = check_team_exists(backend_url, team_id, user_principal_id)
119-
if team_exists:
120-
# Delete existing team to allow re-upload with updated config
121-
print(f"Team (ID: {team_id}) already exists. Deleting to re-upload with latest config...")
122-
delete_endpoint = backend_url.rstrip('/') + f'/api/v4/team_configs/{team_id}'
123-
headers = {
124-
'x-ms-client-principal-id': user_principal_id
125-
}
126-
try:
127-
delete_response = request_with_retry("DELETE", delete_endpoint, headers=headers)
128-
if delete_response.status_code == 200:
129-
print(f"Successfully deleted existing team (ID: {team_id}).")
130-
else:
131-
print(f"Warning: Could not delete existing team (ID: {team_id}). Status: {delete_response.status_code}. Will attempt upload anyway.")
132-
except Exception as e:
133-
print(f"Warning: Exception deleting team (ID: {team_id}): {str(e)}. Will attempt upload anyway.")
134118

135119
try:
136120
with open(file_path, 'rb') as file_data:

src/backend/api/router.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,15 +1008,15 @@ async def upload_team_config(
10081008
{
10091009
"status": "failed",
10101010
"user_id": user_id,
1011-
"filename": file.filename,
1011+
"file_name": file.filename,
10121012
"reason": rai_error,
10131013
},
10141014
)
10151015
raise HTTPException(status_code=400, detail=rai_error)
10161016

10171017
track_event_if_configured(
10181018
"Config_RAI_Validation_Passed",
1019-
{"status": "passed", "user_id": user_id, "filename": file.filename},
1019+
{"status": "passed", "user_id": user_id, "file_name": file.filename},
10201020
)
10211021
team_service = TeamService(memory_store)
10221022

@@ -1034,15 +1034,15 @@ async def upload_team_config(
10341034
{
10351035
"status": "failed",
10361036
"user_id": user_id,
1037-
"filename": file.filename,
1037+
"file_name": file.filename,
10381038
"missing_models": missing_models,
10391039
},
10401040
)
10411041
raise HTTPException(status_code=400, detail=error_message)
10421042

10431043
track_event_if_configured(
10441044
"Config_Model_Validation_Passed",
1045-
{"status": "passed", "user_id": user_id, "filename": file.filename},
1045+
{"status": "passed", "user_id": user_id, "file_name": file.filename},
10461046
)
10471047

10481048
# Validate search indexes
@@ -1061,7 +1061,7 @@ async def upload_team_config(
10611061
{
10621062
"status": "failed",
10631063
"user_id": user_id,
1064-
"filename": file.filename,
1064+
"file_name": file.filename,
10651065
"search_errors": search_errors,
10661066
},
10671067
)
@@ -1070,7 +1070,7 @@ async def upload_team_config(
10701070
logger.info(f"Search validation passed for user: {user_id}")
10711071
track_event_if_configured(
10721072
"Config_Search_Validation_Passed",
1073-
{"status": "passed", "user_id": user_id, "filename": file.filename},
1073+
{"status": "passed", "user_id": user_id, "file_name": file.filename},
10741074
)
10751075

10761076
# Validate and parse the team configuration

src/backend/services/team_service.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,19 +164,37 @@ async def save_team_configuration(self, team_config: TeamConfiguration) -> str:
164164
"""
165165
Save team configuration to the database.
166166
167+
Idempotent by team_id: if a team with the same team_id already exists
168+
(including shared default teams), reuse its document id and partition
169+
key (session_id) and upsert; otherwise create a new document. This
170+
prevents duplicate rows accumulating on re-runs of the seed script.
171+
167172
Args:
168173
team_config: TeamConfiguration object to save
169174
170175
Returns:
171176
The unique ID of the saved configuration
172177
"""
173178
try:
174-
# Use the specific add_team method from cosmos memory context
175-
await self.memory_context.add_team(team_config)
176-
177-
self.logger.info(
178-
"Successfully saved team configuration with ID: %s", team_config.id
179-
)
179+
existing = await self.memory_context.get_team(team_config.team_id)
180+
if existing is not None:
181+
# Preserve immutable identity fields; partition key (session_id)
182+
# cannot change on an upsert.
183+
team_config.id = existing.id
184+
team_config.session_id = existing.session_id
185+
team_config.created = existing.created
186+
team_config.created_by = existing.created_by
187+
await self.memory_context.update_team(team_config)
188+
self.logger.info(
189+
"Successfully updated team configuration with ID: %s",
190+
team_config.id,
191+
)
192+
else:
193+
await self.memory_context.add_team(team_config)
194+
self.logger.info(
195+
"Successfully saved team configuration with ID: %s",
196+
team_config.id,
197+
)
180198
return team_config.id
181199

182200
except Exception as e:

0 commit comments

Comments
 (0)