api_workflow_node_execution_repository.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. """
  2. Service-layer repository protocol for WorkflowNodeExecutionModel operations.
  3. This module provides a protocol interface for service-layer operations on WorkflowNodeExecutionModel
  4. that abstracts database queries currently done directly in service classes. This repository is
  5. specifically designed for service-layer needs and is separate from the core domain repository.
  6. The service repository handles operations that require access to database-specific fields like
  7. tenant_id, app_id, triggered_from, etc., which are not part of the core domain model.
  8. """
  9. from collections.abc import Sequence
  10. from datetime import datetime
  11. from typing import Optional, Protocol
  12. from core.workflow.repositories.workflow_node_execution_repository import WorkflowNodeExecutionRepository
  13. from models.workflow import WorkflowNodeExecutionModel
  14. class DifyAPIWorkflowNodeExecutionRepository(WorkflowNodeExecutionRepository, Protocol):
  15. """
  16. Protocol for service-layer operations on WorkflowNodeExecutionModel.
  17. This repository provides database access patterns specifically needed by service classes,
  18. handling queries that involve database-specific fields and multi-tenancy concerns.
  19. Key responsibilities:
  20. - Manages database operations for workflow node executions
  21. - Handles multi-tenant data isolation
  22. - Provides batch processing capabilities
  23. - Supports execution lifecycle management
  24. Implementation notes:
  25. - Returns database models directly (WorkflowNodeExecutionModel)
  26. - Handles tenant/app filtering automatically
  27. - Provides service-specific query patterns
  28. - Focuses on database operations without domain logic
  29. - Supports cleanup and maintenance operations
  30. """
  31. def get_node_last_execution(
  32. self,
  33. tenant_id: str,
  34. app_id: str,
  35. workflow_id: str,
  36. node_id: str,
  37. ) -> Optional[WorkflowNodeExecutionModel]:
  38. """
  39. Get the most recent execution for a specific node.
  40. This method finds the latest execution of a specific node within a workflow,
  41. ordered by creation time. Used primarily for debugging and inspection purposes.
  42. Args:
  43. tenant_id: The tenant identifier
  44. app_id: The application identifier
  45. workflow_id: The workflow identifier
  46. node_id: The node identifier
  47. Returns:
  48. The most recent WorkflowNodeExecutionModel for the node, or None if not found
  49. """
  50. ...
  51. def get_executions_by_workflow_run(
  52. self,
  53. tenant_id: str,
  54. app_id: str,
  55. workflow_run_id: str,
  56. ) -> Sequence[WorkflowNodeExecutionModel]:
  57. """
  58. Get all node executions for a specific workflow run.
  59. This method retrieves all node executions that belong to a specific workflow run,
  60. ordered by index in descending order for proper trace visualization.
  61. Args:
  62. tenant_id: The tenant identifier
  63. app_id: The application identifier
  64. workflow_run_id: The workflow run identifier
  65. Returns:
  66. A sequence of WorkflowNodeExecutionModel instances ordered by index (desc)
  67. """
  68. ...
  69. def get_execution_by_id(
  70. self,
  71. execution_id: str,
  72. tenant_id: Optional[str] = None,
  73. ) -> Optional[WorkflowNodeExecutionModel]:
  74. """
  75. Get a workflow node execution by its ID.
  76. This method retrieves a specific execution by its unique identifier.
  77. Tenant filtering is optional for cases where the execution ID is globally unique.
  78. When `tenant_id` is None, it's the caller's responsibility to ensure proper data isolation between tenants.
  79. If the `execution_id` comes from untrusted sources (e.g., retrieved from an API request), the caller should
  80. set `tenant_id` to prevent horizontal privilege escalation.
  81. Args:
  82. execution_id: The execution identifier
  83. tenant_id: Optional tenant identifier for additional filtering
  84. Returns:
  85. The WorkflowNodeExecutionModel if found, or None if not found
  86. """
  87. ...
  88. def delete_expired_executions(
  89. self,
  90. tenant_id: str,
  91. before_date: datetime,
  92. batch_size: int = 1000,
  93. ) -> int:
  94. """
  95. Delete workflow node executions that are older than the specified date.
  96. This method is used for cleanup operations to remove expired executions
  97. in batches to avoid overwhelming the database.
  98. Args:
  99. tenant_id: The tenant identifier
  100. before_date: Delete executions created before this date
  101. batch_size: Maximum number of executions to delete in one batch
  102. Returns:
  103. The number of executions deleted
  104. """
  105. ...
  106. def delete_executions_by_app(
  107. self,
  108. tenant_id: str,
  109. app_id: str,
  110. batch_size: int = 1000,
  111. ) -> int:
  112. """
  113. Delete all workflow node executions for a specific app.
  114. This method is used when removing an app and all its related data.
  115. Executions are deleted in batches to avoid overwhelming the database.
  116. Args:
  117. tenant_id: The tenant identifier
  118. app_id: The application identifier
  119. batch_size: Maximum number of executions to delete in one batch
  120. Returns:
  121. The total number of executions deleted
  122. """
  123. ...
  124. def get_expired_executions_batch(
  125. self,
  126. tenant_id: str,
  127. before_date: datetime,
  128. batch_size: int = 1000,
  129. ) -> Sequence[WorkflowNodeExecutionModel]:
  130. """
  131. Get a batch of expired workflow node executions for backup purposes.
  132. This method retrieves expired executions without deleting them,
  133. allowing the caller to backup the data before deletion.
  134. Args:
  135. tenant_id: The tenant identifier
  136. before_date: Get executions created before this date
  137. batch_size: Maximum number of executions to retrieve
  138. Returns:
  139. A sequence of WorkflowNodeExecutionModel instances
  140. """
  141. ...
  142. def delete_executions_by_ids(
  143. self,
  144. execution_ids: Sequence[str],
  145. ) -> int:
  146. """
  147. Delete workflow node executions by their IDs.
  148. This method deletes specific executions by their IDs,
  149. typically used after backing up the data.
  150. This method does not perform tenant isolation checks. The caller is responsible for ensuring proper
  151. data isolation between tenants. When execution IDs come from untrusted sources (e.g., API requests),
  152. additional tenant validation should be implemented to prevent unauthorized access.
  153. Args:
  154. execution_ids: List of execution IDs to delete
  155. Returns:
  156. The number of executions deleted
  157. """
  158. ...