chore: port WorkflowComment (#36039)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Asuka Minato 2026-05-11 18:17:12 +09:00 committed by GitHub
parent 6164408da1
commit a60cb3b800
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 28 deletions

View File

@ -1,19 +1,22 @@
"""Workflow comment models.""" """Workflow comment models."""
from __future__ import annotations
from datetime import datetime from datetime import datetime
from typing import Optional
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy import Index, func from sqlalchemy import Index, func
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from models.base import TypeBase
from .account import Account from .account import Account
from .base import Base, gen_uuidv7_string from .base import gen_uuidv7_string
from .engine import db from .engine import db
from .types import StringUUID from .types import StringUUID
class WorkflowComment(Base): class WorkflowComment(TypeBase):
"""Workflow comment model for canvas commenting functionality. """Workflow comment model for canvas commenting functionality.
Comments are associated with apps rather than specific workflow versions, Comments are associated with apps rather than specific workflow versions,
@ -42,27 +45,33 @@ class WorkflowComment(Base):
Index("workflow_comments_created_at_idx", "created_at"), Index("workflow_comments_created_at_idx", "created_at"),
) )
id: Mapped[str] = mapped_column(StringUUID, default=gen_uuidv7_string) id: Mapped[str] = mapped_column(StringUUID, default_factory=gen_uuidv7_string, init=False)
tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
app_id: Mapped[str] = mapped_column(StringUUID, nullable=False) app_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
position_x: Mapped[float] = mapped_column(sa.Float) position_x: Mapped[float] = mapped_column(sa.Float)
position_y: Mapped[float] = mapped_column(sa.Float) position_y: Mapped[float] = mapped_column(sa.Float)
content: Mapped[str] = mapped_column(sa.Text, nullable=False) content: Mapped[str] = mapped_column(sa.Text, nullable=False)
created_by: Mapped[str] = mapped_column(StringUUID, nullable=False) created_by: Mapped[str] = mapped_column(StringUUID, nullable=False)
created_at: Mapped[datetime] = mapped_column(sa.DateTime, nullable=False, server_default=func.current_timestamp()) created_at: Mapped[datetime] = mapped_column(
sa.DateTime, nullable=False, server_default=func.current_timestamp(), init=False
)
updated_at: Mapped[datetime] = mapped_column( updated_at: Mapped[datetime] = mapped_column(
sa.DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp() sa.DateTime,
nullable=False,
server_default=func.current_timestamp(),
onupdate=func.current_timestamp(),
init=False,
) )
resolved: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=sa.text("false")) resolved_at: Mapped[datetime | None] = mapped_column(sa.DateTime, default=None)
resolved_at: Mapped[datetime | None] = mapped_column(sa.DateTime) resolved_by: Mapped[str | None] = mapped_column(StringUUID, default=None)
resolved_by: Mapped[str | None] = mapped_column(StringUUID)
resolved: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=sa.text("false"), default=False)
# Relationships # Relationships
replies: Mapped[list["WorkflowCommentReply"]] = relationship( replies: Mapped[list[WorkflowCommentReply]] = relationship(
"WorkflowCommentReply", back_populates="comment", cascade="all, delete-orphan" lambda: WorkflowCommentReply, back_populates="comment", cascade="all, delete-orphan", init=False
) )
mentions: Mapped[list["WorkflowCommentMention"]] = relationship( mentions: Mapped[list[WorkflowCommentMention]] = relationship(
"WorkflowCommentMention", back_populates="comment", cascade="all, delete-orphan" lambda: WorkflowCommentMention, back_populates="comment", cascade="all, delete-orphan", init=False
) )
@property @property
@ -131,7 +140,7 @@ class WorkflowComment(Base):
return participants return participants
class WorkflowCommentReply(Base): class WorkflowCommentReply(TypeBase):
"""Workflow comment reply model. """Workflow comment reply model.
Attributes: Attributes:
@ -149,18 +158,24 @@ class WorkflowCommentReply(Base):
Index("comment_replies_created_at_idx", "created_at"), Index("comment_replies_created_at_idx", "created_at"),
) )
id: Mapped[str] = mapped_column(StringUUID, default=gen_uuidv7_string) id: Mapped[str] = mapped_column(StringUUID, default_factory=gen_uuidv7_string, init=False)
comment_id: Mapped[str] = mapped_column( comment_id: Mapped[str] = mapped_column(
StringUUID, sa.ForeignKey("workflow_comments.id", ondelete="CASCADE"), nullable=False StringUUID, sa.ForeignKey("workflow_comments.id", ondelete="CASCADE"), nullable=False
) )
content: Mapped[str] = mapped_column(sa.Text, nullable=False) content: Mapped[str] = mapped_column(sa.Text, nullable=False)
created_by: Mapped[str] = mapped_column(StringUUID, nullable=False) created_by: Mapped[str] = mapped_column(StringUUID, nullable=False)
created_at: Mapped[datetime] = mapped_column(sa.DateTime, nullable=False, server_default=func.current_timestamp()) created_at: Mapped[datetime] = mapped_column(
sa.DateTime, nullable=False, server_default=func.current_timestamp(), init=False
)
updated_at: Mapped[datetime] = mapped_column( updated_at: Mapped[datetime] = mapped_column(
sa.DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp() sa.DateTime,
nullable=False,
server_default=func.current_timestamp(),
onupdate=func.current_timestamp(),
init=False,
) )
# Relationships # Relationships
comment: Mapped["WorkflowComment"] = relationship("WorkflowComment", back_populates="replies") comment: Mapped[WorkflowComment] = relationship(lambda: WorkflowComment, back_populates="replies", init=False)
@property @property
def created_by_account(self): def created_by_account(self):
@ -174,7 +189,7 @@ class WorkflowCommentReply(Base):
self._created_by_account_cache = account self._created_by_account_cache = account
class WorkflowCommentMention(Base): class WorkflowCommentMention(TypeBase):
"""Workflow comment mention model. """Workflow comment mention model.
Mentions are only for internal accounts since end users Mentions are only for internal accounts since end users
@ -194,18 +209,18 @@ class WorkflowCommentMention(Base):
Index("comment_mentions_user_idx", "mentioned_user_id"), Index("comment_mentions_user_idx", "mentioned_user_id"),
) )
id: Mapped[str] = mapped_column(StringUUID, default=gen_uuidv7_string) id: Mapped[str] = mapped_column(StringUUID, default_factory=gen_uuidv7_string, init=False)
comment_id: Mapped[str] = mapped_column( comment_id: Mapped[str] = mapped_column(
StringUUID, sa.ForeignKey("workflow_comments.id", ondelete="CASCADE"), nullable=False StringUUID, sa.ForeignKey("workflow_comments.id", ondelete="CASCADE"), nullable=False
) )
reply_id: Mapped[str | None] = mapped_column(
StringUUID, sa.ForeignKey("workflow_comment_replies.id", ondelete="CASCADE"), nullable=True
)
mentioned_user_id: Mapped[str] = mapped_column(StringUUID, nullable=False) mentioned_user_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
reply_id: Mapped[str | None] = mapped_column(
StringUUID, sa.ForeignKey("workflow_comment_replies.id", ondelete="CASCADE"), nullable=True, default=None
)
# Relationships # Relationships
comment: Mapped["WorkflowComment"] = relationship("WorkflowComment", back_populates="mentions") comment: Mapped[WorkflowComment] = relationship(lambda: WorkflowComment, back_populates="mentions", init=False)
reply: Mapped[Optional["WorkflowCommentReply"]] = relationship("WorkflowCommentReply") reply: Mapped[WorkflowCommentReply | None] = relationship(lambda: WorkflowCommentReply, init=False)
@property @property
def mentioned_user_account(self): def mentioned_user_account(self):

View File

@ -4,7 +4,15 @@ from models.comment import WorkflowComment, WorkflowCommentMention, WorkflowComm
def test_workflow_comment_account_properties_and_cache() -> None: def test_workflow_comment_account_properties_and_cache() -> None:
comment = WorkflowComment(created_by="user-1", resolved_by="user-2", content="hello", position_x=1, position_y=2) comment = WorkflowComment(
created_by="user-1",
resolved_by="user-2",
content="hello",
position_x=1,
position_y=2,
tenant_id="xxx",
app_id="yyy",
)
created_account = Mock(id="user-1") created_account = Mock(id="user-1")
resolved_account = Mock(id="user-2") resolved_account = Mock(id="user-2")
@ -21,6 +29,8 @@ def test_workflow_comment_account_properties_and_cache() -> None:
get_mock.assert_not_called() get_mock.assert_not_called()
comment_without_resolver = WorkflowComment( comment_without_resolver = WorkflowComment(
tenant_id="xxx",
app_id="yyy",
created_by="user-1", created_by="user-1",
resolved_by=None, resolved_by=None,
content="hello", content="hello",
@ -37,7 +47,15 @@ def test_workflow_comment_counts_and_participants() -> None:
reply_2 = WorkflowCommentReply(comment_id="comment-1", content="reply-2", created_by="user-2") reply_2 = WorkflowCommentReply(comment_id="comment-1", content="reply-2", created_by="user-2")
mention_1 = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-3") mention_1 = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-3")
mention_2 = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-4") mention_2 = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-4")
comment = WorkflowComment(created_by="user-1", resolved_by=None, content="hello", position_x=1, position_y=2) comment = WorkflowComment(
created_by="user-1",
resolved_by=None,
content="hello",
position_x=1,
position_y=2,
tenant_id="xxx",
app_id="yyy",
)
comment.replies = [reply_1, reply_2] comment.replies = [reply_1, reply_2]
comment.mentions = [mention_1, mention_2] comment.mentions = [mention_1, mention_2]
@ -63,7 +81,15 @@ def test_workflow_comment_counts_and_participants() -> None:
def test_workflow_comment_participants_use_cached_accounts() -> None: def test_workflow_comment_participants_use_cached_accounts() -> None:
reply = WorkflowCommentReply(comment_id="comment-1", content="reply-1", created_by="user-2") reply = WorkflowCommentReply(comment_id="comment-1", content="reply-1", created_by="user-2")
mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-3") mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-3")
comment = WorkflowComment(created_by="user-1", resolved_by=None, content="hello", position_x=1, position_y=2) comment = WorkflowComment(
created_by="user-1",
resolved_by=None,
content="hello",
position_x=1,
position_y=2,
tenant_id="xxx",
app_id="yyy",
)
comment.replies = [reply] comment.replies = [reply]
comment.mentions = [mention] comment.mentions = [mention]