diff --git a/api/controllers/console/app/workflow_comment.py b/api/controllers/console/app/workflow_comment.py index e9004effb7..6088cfbbf9 100644 --- a/api/controllers/console/app/workflow_comment.py +++ b/api/controllers/console/app/workflow_comment.py @@ -87,19 +87,23 @@ class WorkflowCommentDetailApi(Resource): """Update a workflow comment.""" parser = reqparse.RequestParser() parser.add_argument("content", type=str, required=True, location="json") + parser.add_argument("position_x", type=float, required=False, location="json") + parser.add_argument("position_y", type=float, required=False, location="json") parser.add_argument("mentioned_user_ids", type=list, location="json", default=[]) args = parser.parse_args() - comment = WorkflowCommentService.update_comment( + result = WorkflowCommentService.update_comment( tenant_id=current_user.current_tenant_id, app_id=app_model.id, comment_id=comment_id, user_id=current_user.id, content=args.content, + position_x=args.position_x, + position_y=args.position_y, mentioned_user_ids=args.mentioned_user_ids, ) - return comment + return result @login_required @setup_required diff --git a/api/fields/workflow_comment_fields.py b/api/fields/workflow_comment_fields.py index 33b1fc8067..f4f22d4c49 100644 --- a/api/fields/workflow_comment_fields.py +++ b/api/fields/workflow_comment_fields.py @@ -72,12 +72,10 @@ workflow_comment_create_fields = { "created_at": TimestampField, } -# Comment update response fields +# Comment update response fields (simplified) workflow_comment_update_fields = { "id": fields.String, - "content": fields.String, "updated_at": TimestampField, - "mentions": fields.List(fields.Nested(workflow_comment_mention_fields)), } # Comment resolve response fields diff --git a/api/services/workflow_comment_service.py b/api/services/workflow_comment_service.py index cb6ee09d4b..d727020d4d 100644 --- a/api/services/workflow_comment_service.py +++ b/api/services/workflow_comment_service.py @@ -102,44 +102,70 @@ class WorkflowCommentService: comment_id: str, user_id: str, content: str, + position_x: Optional[float] = None, + position_y: Optional[float] = None, mentioned_user_ids: Optional[list[str]] = None, - ) -> WorkflowComment: + ) -> dict: """Update a workflow comment.""" - - comment = WorkflowCommentService.get_comment(tenant_id, app_id, comment_id) - - # Only the creator can update the comment - if comment.created_by != user_id: - raise Forbidden("Only the comment creator can update it") - if len(content.strip()) == 0: raise ValueError("Comment content cannot be empty") if len(content) > 1000: raise ValueError("Comment content cannot exceed 1000 characters") - comment.content = content - - # Update mentions - first remove existing mentions - existing_mentions = ( - db.session.query(WorkflowCommentMention).filter(WorkflowCommentMention.comment_id == comment.id).all() - ) - for mention in existing_mentions: - db.session.delete(mention) - - # Add new mentions - mentioned_user_ids = mentioned_user_ids or [] - for user_id_str in mentioned_user_ids: - if isinstance(user_id_str, str) and uuid_value(user_id_str): - mention = WorkflowCommentMention( - comment_id=comment.id, - reply_id=None, # This is a comment mention - mentioned_user_id=user_id_str + with Session(db.engine) as session: + # Get comment with validation + stmt = ( + select(WorkflowComment) + .where( + WorkflowComment.id == comment_id, + WorkflowComment.tenant_id == tenant_id, + WorkflowComment.app_id == app_id, ) - db.session.add(mention) + ) + comment = session.scalar(stmt) + + if not comment: + raise NotFound("Comment not found") - db.session.commit() - return comment + # Only the creator can update the comment + if comment.created_by != user_id: + raise Forbidden("Only the comment creator can update it") + + # Update comment fields + comment.content = content + if position_x is not None: + comment.position_x = position_x + if position_y is not None: + comment.position_y = position_y + + # Update mentions - first remove existing mentions for this comment only (not replies) + existing_mentions = session.scalars( + select(WorkflowCommentMention).where( + WorkflowCommentMention.comment_id == comment.id, + WorkflowCommentMention.reply_id.is_(None) # Only comment mentions, not reply mentions + ) + ).all() + for mention in existing_mentions: + session.delete(mention) + + # Add new mentions + mentioned_user_ids = mentioned_user_ids or [] + for user_id_str in mentioned_user_ids: + if isinstance(user_id_str, str) and uuid_value(user_id_str): + mention = WorkflowCommentMention( + comment_id=comment.id, + reply_id=None, # This is a comment mention + mentioned_user_id=user_id_str + ) + session.add(mention) + + session.commit() + + return { + "id": comment.id, + "updated_at": comment.updated_at + } @staticmethod def delete_comment(tenant_id: str, app_id: str, comment_id: str, user_id: str) -> None: