diff --git a/api/controllers/console/app/workflow_trigger.py b/api/controllers/console/app/workflow_trigger.py index 0dabba1bd7..6b5f71797e 100644 --- a/api/controllers/console/app/workflow_trigger.py +++ b/api/controllers/console/app/workflow_trigger.py @@ -10,6 +10,7 @@ from configs import dify_config from controllers.console import api from controllers.console.app.wraps import get_app_model from controllers.console.wraps import account_initialization_required, setup_required +from core.model_runtime.utils.encoders import jsonable_encoder from extensions.ext_database import db from fields.workflow_trigger_fields import trigger_fields, triggers_list_fields, webhook_trigger_fields from libs.login import current_user, login_required @@ -31,10 +32,10 @@ class PluginTriggerApi(Resource): def post(self, app_model): """Create plugin trigger""" parser = reqparse.RequestParser() - parser.add_argument("node_id", type=str, required=True, help="Node ID is required") - parser.add_argument("provider_id", type=str, required=True, help="Provider ID is required") - parser.add_argument("trigger_name", type=str, required=True, help="Trigger name is required") - parser.add_argument("subscription_id", type=str, required=True, help="Subscription ID is required") + parser.add_argument("node_id", type=str, required=False, location="json") + parser.add_argument("provider_id", type=str, required=False, location="json") + parser.add_argument("trigger_name", type=str, required=False, location="json") + parser.add_argument("subscription_id", type=str, required=False, location="json") args = parser.parse_args() assert isinstance(current_user, Account) @@ -51,7 +52,7 @@ class PluginTriggerApi(Resource): subscription_id=args["subscription_id"], ) - return plugin_trigger + return jsonable_encoder(plugin_trigger) @setup_required @login_required @@ -68,7 +69,7 @@ class PluginTriggerApi(Resource): node_id=args["node_id"], ) - return plugin_trigger + return jsonable_encoder(plugin_trigger) @setup_required @login_required @@ -78,9 +79,7 @@ class PluginTriggerApi(Resource): """Update plugin trigger""" parser = reqparse.RequestParser() parser.add_argument("node_id", type=str, required=True, help="Node ID is required") - parser.add_argument("provider_id", type=str, required=False, help="Provider ID") - parser.add_argument("trigger_name", type=str, required=False, help="Trigger name") - parser.add_argument("subscription_id", type=str, required=False, help="Subscription ID") + parser.add_argument("subscription_id", type=str, required=True, location="json", help="Subscription ID") args = parser.parse_args() assert isinstance(current_user, Account) @@ -91,12 +90,10 @@ class PluginTriggerApi(Resource): plugin_trigger = WorkflowPluginTriggerService.update_plugin_trigger( app_id=app_model.id, node_id=args["node_id"], - provider_id=args.get("provider_id"), - trigger_name=args.get("trigger_name"), - subscription_id=args.get("subscription_id"), + subscription_id=args["subscription_id"], ) - return plugin_trigger + return jsonable_encoder(plugin_trigger) @setup_required @login_required diff --git a/api/migrations/versions/2025_09_05_1551-875c659da2f8_plugin_trigger_idx.py b/api/migrations/versions/2025_09_05_1551-875c659da2f8_plugin_trigger_idx.py new file mode 100644 index 0000000000..ce7985097f --- /dev/null +++ b/api/migrations/versions/2025_09_05_1551-875c659da2f8_plugin_trigger_idx.py @@ -0,0 +1,37 @@ +"""plugin_trigger_idx + +Revision ID: 875c659da2f8 +Revises: 86f068bf56fb +Create Date: 2025-09-05 15:51:08.635283 + +""" +from alembic import op +import models as models +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '875c659da2f8' +down_revision = '86f068bf56fb' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('workflow_plugin_triggers', schema=None) as batch_op: + batch_op.add_column(sa.Column('trigger_name', sa.String(length=255), nullable=False)) + batch_op.drop_index(batch_op.f('workflow_plugin_trigger_tenant_subscription_idx')) + batch_op.create_index('workflow_plugin_trigger_tenant_subscription_idx', ['tenant_id', 'subscription_id', 'trigger_name'], unique=False) + batch_op.drop_column('trigger_id') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('workflow_plugin_triggers', schema=None) as batch_op: + batch_op.add_column(sa.Column('trigger_id', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + batch_op.drop_index('workflow_plugin_trigger_tenant_subscription_idx') + batch_op.create_index(batch_op.f('workflow_plugin_trigger_tenant_subscription_idx'), ['tenant_id', 'subscription_id'], unique=False) + batch_op.drop_column('trigger_name') + # ### end Alembic commands ### diff --git a/api/models/workflow.py b/api/models/workflow.py index bdcea54506..6dfb83510b 100644 --- a/api/models/workflow.py +++ b/api/models/workflow.py @@ -1438,7 +1438,7 @@ class WorkflowPluginTrigger(Base): - node_id (varchar) Node ID which node in the workflow - tenant_id (uuid) Workspace ID - provider_id (varchar) Plugin provider ID - - trigger_id (varchar) trigger id (github_issues_trigger) + - trigger_name (varchar) trigger name (github_issues_trigger) - subscription_id (varchar) Subscription ID - created_at (timestamp) Creation time - updated_at (timestamp) Last update time @@ -1447,7 +1447,7 @@ class WorkflowPluginTrigger(Base): __tablename__ = "workflow_plugin_triggers" __table_args__ = ( sa.PrimaryKeyConstraint("id", name="workflow_plugin_trigger_pkey"), - sa.Index("workflow_plugin_trigger_tenant_subscription_idx", "tenant_id", "subscription_id", "trigger_id"), + sa.Index("workflow_plugin_trigger_tenant_subscription_idx", "tenant_id", "subscription_id", "trigger_name"), sa.UniqueConstraint("app_id", "node_id", name="uniq_app_node_subscription"), ) @@ -1456,7 +1456,7 @@ class WorkflowPluginTrigger(Base): node_id: Mapped[str] = mapped_column(String(64), nullable=False) tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_id: Mapped[str] = mapped_column(String(512), nullable=False) - trigger_id: Mapped[str] = mapped_column(String(255), nullable=False) + trigger_name: Mapped[str] = mapped_column(String(255), nullable=False) subscription_id: Mapped[str] = mapped_column(String(255), nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, server_default=func.current_timestamp()) updated_at: Mapped[datetime] = mapped_column( diff --git a/api/services/trigger_service.py b/api/services/trigger_service.py index b24ff66e39..2876ee53cd 100644 --- a/api/services/trigger_service.py +++ b/api/services/trigger_service.py @@ -176,7 +176,7 @@ class TriggerService: select(WorkflowPluginTrigger).where( WorkflowPluginTrigger.tenant_id == subscription.tenant_id, WorkflowPluginTrigger.subscription_id == subscription.id, - WorkflowPluginTrigger.trigger_id == trigger.identity.name, + WorkflowPluginTrigger.trigger_name == trigger.identity.name, ) ).all() return list(subscribers) diff --git a/api/services/workflow_plugin_trigger_service.py b/api/services/workflow_plugin_trigger_service.py index 9124e3653f..89429c3850 100644 --- a/api/services/workflow_plugin_trigger_service.py +++ b/api/services/workflow_plugin_trigger_service.py @@ -2,7 +2,7 @@ from typing import Optional from sqlalchemy import select from sqlalchemy.orm import Session -from werkzeug.exceptions import BadRequest, NotFound +from werkzeug.exceptions import NotFound from extensions.ext_database import db from models.trigger import TriggerSubscription @@ -38,9 +38,6 @@ class WorkflowPluginTriggerService: Raises: BadRequest: If plugin trigger already exists for this app and node """ - # Create trigger_id from provider_id and trigger_name - trigger_id = f"{provider_id}:{trigger_name}" - with Session(db.engine) as session: # Check if plugin trigger already exists for this app and node # Based on unique constraint: uniq_app_node @@ -52,7 +49,7 @@ class WorkflowPluginTriggerService: ) if existing_trigger: - raise BadRequest("Plugin trigger already exists for this app and node") + raise ValueError("Plugin trigger already exists for this app and node") # Check if subscription exists subscription = session.scalar( @@ -62,7 +59,7 @@ class WorkflowPluginTriggerService: ) if not subscription: - raise BadRequest("Subscription not found") + raise NotFound("Subscription not found") # Create new plugin trigger plugin_trigger = WorkflowPluginTrigger( @@ -70,7 +67,7 @@ class WorkflowPluginTriggerService: node_id=node_id, tenant_id=tenant_id, provider_id=provider_id, - trigger_id=trigger_id, + trigger_name=trigger_name, subscription_id=subscription_id, ) @@ -194,17 +191,13 @@ class WorkflowPluginTriggerService: cls, app_id: str, node_id: str, - provider_id: Optional[str] = None, - trigger_name: Optional[str] = None, - subscription_id: Optional[str] = None, + subscription_id: str, ) -> WorkflowPluginTrigger: """Update a plugin trigger Args: app_id: The app ID node_id: The node ID in the workflow - provider_id: The new provider ID (optional) - trigger_name: The new trigger name (optional) subscription_id: The new subscription ID (optional) Returns: @@ -225,17 +218,18 @@ class WorkflowPluginTriggerService: if not plugin_trigger: raise NotFound("Plugin trigger not found") - # Update fields if provided - if provider_id: - plugin_trigger.provider_id = provider_id + # Check if subscription exists + subscription = session.scalar( + select(TriggerSubscription).where( + TriggerSubscription.id == subscription_id, + ) + ) - if trigger_name: - # Update trigger_id if provider_id or trigger_name changed - provider_id = provider_id or plugin_trigger.provider_id - plugin_trigger.trigger_id = f"{provider_id}:{trigger_name}" + if not subscription: + raise NotFound("Subscription not found") - if subscription_id: - plugin_trigger.subscription_id = subscription_id + # Update subscription ID + plugin_trigger.subscription_id = subscription_id session.commit() session.refresh(plugin_trigger) @@ -285,7 +279,7 @@ class WorkflowPluginTriggerService: if trigger_name: # Update trigger_id if provider_id or trigger_name changed provider_id = provider_id or plugin_trigger.provider_id - plugin_trigger.trigger_id = f"{provider_id}:{trigger_name}" + plugin_trigger.trigger_name = f"{provider_id}:{trigger_name}" if new_subscription_id: plugin_trigger.subscription_id = new_subscription_id