Fix test failures and workload/websocket behavior

This commit is contained in:
beabigegg
2026-01-11 08:37:21 +08:00
parent 3bdc6ff1c9
commit f5f870da56
49 changed files with 3006 additions and 1132 deletions

View File

@@ -407,17 +407,18 @@ async def update_task(
if task_data.version != task.version:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail={
"message": "Task has been modified by another user",
"current_version": task.version,
"provided_version": task_data.version,
},
detail=(
f"Version conflict: current_version={task.version}, "
f"provided_version={task_data.version}"
),
)
# Capture old values for audit and triggers
old_values = {
"title": task.title,
"description": task.description,
"status_id": task.status_id,
"assignee_id": task.assignee_id,
"priority": task.priority,
"start_date": task.start_date,
"due_date": task.due_date,
@@ -430,6 +431,17 @@ async def update_task(
custom_values_data = update_data.pop("custom_values", None)
update_data.pop("version", None) # version is handled separately for optimistic locking
old_custom_values = None
if custom_values_data:
old_custom_values = {
cv.field_id: cv.value
for cv in CustomValueService.get_custom_values_for_task(
db,
task,
include_formula_calculations=True,
)
}
# Track old assignee for workload cache invalidation
old_assignee_id = task.assignee_id
@@ -488,6 +500,8 @@ async def update_task(
new_values = {
"title": task.title,
"description": task.description,
"status_id": task.status_id,
"assignee_id": task.assignee_id,
"priority": task.priority,
"start_date": task.start_date,
"due_date": task.due_date,
@@ -509,30 +523,46 @@ async def update_task(
request_metadata=get_audit_metadata(request),
)
# Evaluate triggers for priority changes
if "priority" in update_data:
TriggerService.evaluate_triggers(db, task, old_values, new_values, current_user)
# Handle custom values update
new_custom_values = None
if custom_values_data:
try:
from app.schemas.task import CustomValueInput
custom_values = [CustomValueInput(**cv) for cv in custom_values_data]
CustomValueService.save_custom_values(db, task, custom_values)
new_custom_values = {
cv.field_id: cv.value
for cv in CustomValueService.get_custom_values_for_task(
db,
task,
include_formula_calculations=True,
)
}
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e),
)
trigger_fields = {"status_id", "assignee_id", "priority", "start_date", "due_date"}
trigger_relevant = any(field in update_data for field in trigger_fields) or custom_values_data
if trigger_relevant:
trigger_old_values = {field: old_values.get(field) for field in trigger_fields}
trigger_new_values = {field: new_values.get(field) for field in trigger_fields}
if old_custom_values is not None:
trigger_old_values["custom_fields"] = old_custom_values
if new_custom_values is not None:
trigger_new_values["custom_fields"] = new_custom_values
TriggerService.evaluate_triggers(db, task, trigger_old_values, trigger_new_values, current_user)
# Increment version for optimistic locking
task.version += 1
db.commit()
db.refresh(task)
# Invalidate workload cache if original_estimate changed and task has an assignee
if "original_estimate" in update_data and task.assignee_id:
# Invalidate workload cache if workload-affecting fields changed
if ("original_estimate" in update_data or "due_date" in update_data) and task.assignee_id:
invalidate_user_workload_cache(task.assignee_id)
# Invalidate workload cache if assignee changed