tasker-engine 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (605) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +443 -0
  4. data/Rakefile +10 -0
  5. data/app/controllers/tasker/analytics_controller.rb +179 -0
  6. data/app/controllers/tasker/application_controller.rb +45 -0
  7. data/app/controllers/tasker/graphql_controller.rb +193 -0
  8. data/app/controllers/tasker/handlers_controller.rb +217 -0
  9. data/app/controllers/tasker/health_controller.rb +229 -0
  10. data/app/controllers/tasker/metrics_controller.rb +111 -0
  11. data/app/controllers/tasker/page_sort.rb +97 -0
  12. data/app/controllers/tasker/task_diagrams_controller.rb +30 -0
  13. data/app/controllers/tasker/tasks_controller.rb +123 -0
  14. data/app/controllers/tasker/workflow_steps_controller.rb +69 -0
  15. data/app/graphql/examples/all_tasks.graphql +22 -0
  16. data/app/graphql/examples/pending_tasks.graphql +23 -0
  17. data/app/graphql/tasker/graph_ql_types/annotation_type.rb +14 -0
  18. data/app/graphql/tasker/graph_ql_types/base_argument.rb +9 -0
  19. data/app/graphql/tasker/graph_ql_types/base_connection.rb +11 -0
  20. data/app/graphql/tasker/graph_ql_types/base_edge.rb +10 -0
  21. data/app/graphql/tasker/graph_ql_types/base_enum.rb +9 -0
  22. data/app/graphql/tasker/graph_ql_types/base_field.rb +10 -0
  23. data/app/graphql/tasker/graph_ql_types/base_input_object.rb +10 -0
  24. data/app/graphql/tasker/graph_ql_types/base_interface.rb +14 -0
  25. data/app/graphql/tasker/graph_ql_types/base_object.rb +10 -0
  26. data/app/graphql/tasker/graph_ql_types/base_scalar.rb +9 -0
  27. data/app/graphql/tasker/graph_ql_types/base_union.rb +11 -0
  28. data/app/graphql/tasker/graph_ql_types/dependent_system_object_map_type.rb +18 -0
  29. data/app/graphql/tasker/graph_ql_types/dependent_system_type.rb +13 -0
  30. data/app/graphql/tasker/graph_ql_types/mutation_type.rb +16 -0
  31. data/app/graphql/tasker/graph_ql_types/named_step_type.rb +16 -0
  32. data/app/graphql/tasker/graph_ql_types/named_task_type.rb +14 -0
  33. data/app/graphql/tasker/graph_ql_types/named_tasks_named_step_type.rb +19 -0
  34. data/app/graphql/tasker/graph_ql_types/node_type.rb +12 -0
  35. data/app/graphql/tasker/graph_ql_types/query_type.rb +20 -0
  36. data/app/graphql/tasker/graph_ql_types/task_annotation_type.rb +17 -0
  37. data/app/graphql/tasker/graph_ql_types/task_interface.rb +17 -0
  38. data/app/graphql/tasker/graph_ql_types/task_type.rb +26 -0
  39. data/app/graphql/tasker/graph_ql_types/workflow_step_type.rb +154 -0
  40. data/app/graphql/tasker/graph_ql_types.rb +42 -0
  41. data/app/graphql/tasker/mutations/base_mutation.rb +13 -0
  42. data/app/graphql/tasker/mutations/cancel_step.rb +29 -0
  43. data/app/graphql/tasker/mutations/cancel_task.rb +29 -0
  44. data/app/graphql/tasker/mutations/create_task.rb +52 -0
  45. data/app/graphql/tasker/mutations/update_step.rb +36 -0
  46. data/app/graphql/tasker/mutations/update_task.rb +41 -0
  47. data/app/graphql/tasker/queries/all_annotation_types.rb +17 -0
  48. data/app/graphql/tasker/queries/all_tasks.rb +23 -0
  49. data/app/graphql/tasker/queries/base_query.rb +9 -0
  50. data/app/graphql/tasker/queries/helpers.rb +16 -0
  51. data/app/graphql/tasker/queries/one_step.rb +24 -0
  52. data/app/graphql/tasker/queries/one_task.rb +18 -0
  53. data/app/graphql/tasker/queries/tasks_by_annotation.rb +31 -0
  54. data/app/graphql/tasker/queries/tasks_by_status.rb +30 -0
  55. data/app/graphql/tasker/tasker_rails_schema.rb +52 -0
  56. data/app/jobs/tasker/application_job.rb +8 -0
  57. data/app/jobs/tasker/metrics_export_job.rb +252 -0
  58. data/app/jobs/tasker/task_runner_job.rb +224 -0
  59. data/app/models/tasker/annotation_type.rb +26 -0
  60. data/app/models/tasker/application_record.rb +70 -0
  61. data/app/models/tasker/dependent_system.rb +26 -0
  62. data/app/models/tasker/dependent_system_object_map.rb +64 -0
  63. data/app/models/tasker/diagram/edge.rb +106 -0
  64. data/app/models/tasker/diagram/flowchart.rb +137 -0
  65. data/app/models/tasker/diagram/node.rb +99 -0
  66. data/app/models/tasker/named_step.rb +41 -0
  67. data/app/models/tasker/named_task.rb +121 -0
  68. data/app/models/tasker/named_tasks_named_step.rb +82 -0
  69. data/app/models/tasker/step_dag_relationship.rb +65 -0
  70. data/app/models/tasker/step_readiness_status.rb +59 -0
  71. data/app/models/tasker/task.rb +424 -0
  72. data/app/models/tasker/task_annotation.rb +36 -0
  73. data/app/models/tasker/task_diagram.rb +332 -0
  74. data/app/models/tasker/task_execution_context.rb +29 -0
  75. data/app/models/tasker/task_namespace.rb +41 -0
  76. data/app/models/tasker/task_transition.rb +235 -0
  77. data/app/models/tasker/workflow_step.rb +461 -0
  78. data/app/models/tasker/workflow_step_edge.rb +94 -0
  79. data/app/models/tasker/workflow_step_transition.rb +434 -0
  80. data/app/serializers/tasker/annotation_type_serializer.rb +8 -0
  81. data/app/serializers/tasker/handler_serializer.rb +109 -0
  82. data/app/serializers/tasker/task_annotation_serializer.rb +32 -0
  83. data/app/serializers/tasker/task_serializer.rb +168 -0
  84. data/app/serializers/tasker/workflow_step_serializer.rb +27 -0
  85. data/app/services/tasker/analytics_service.rb +409 -0
  86. data/app/views/tasker/task/_diagram.html.erb +32 -0
  87. data/config/initializers/dry_struct.rb +11 -0
  88. data/config/initializers/statesman.rb +6 -0
  89. data/config/initializers/tasker_orchestration.rb +17 -0
  90. data/config/initializers/time_formats.rb +4 -0
  91. data/config/routes.rb +34 -0
  92. data/config/tasker/subscriptions/example_integrations.yml +67 -0
  93. data/config/tasker/system_events.yml +305 -0
  94. data/db/functions/calculate_dependency_levels_v01.sql +45 -0
  95. data/db/functions/get_analytics_metrics_v01.sql +137 -0
  96. data/db/functions/get_slowest_steps_v01.sql +82 -0
  97. data/db/functions/get_slowest_tasks_v01.sql +96 -0
  98. data/db/functions/get_step_readiness_status_batch_v01.sql +140 -0
  99. data/db/functions/get_step_readiness_status_v01.sql +139 -0
  100. data/db/functions/get_system_health_counts_v01.sql +108 -0
  101. data/db/functions/get_task_execution_context_v01.sql +108 -0
  102. data/db/functions/get_task_execution_contexts_batch_v01.sql +104 -0
  103. data/db/init/schema.sql +2277 -0
  104. data/db/migrate/20250701165431_initial_tasker_schema.rb +116 -0
  105. data/db/views/tasker_step_dag_relationships_v01.sql +69 -0
  106. data/docs/APPLICATION_GENERATOR.md +384 -0
  107. data/docs/AUTH.md +1780 -0
  108. data/docs/CIRCUIT_BREAKER.md +224 -0
  109. data/docs/DEVELOPER_GUIDE.md +2665 -0
  110. data/docs/EVENT_SYSTEM.md +637 -0
  111. data/docs/EXECUTION_CONFIGURATION.md +341 -0
  112. data/docs/FLOW_CHART.md +149 -0
  113. data/docs/HEALTH.md +542 -0
  114. data/docs/METRICS.md +731 -0
  115. data/docs/OPTIMIZATION_PLAN.md +1479 -0
  116. data/docs/OVERVIEW.md +552 -0
  117. data/docs/QUICK_START.md +270 -0
  118. data/docs/REGISTRY_SYSTEMS.md +373 -0
  119. data/docs/REST_API.md +632 -0
  120. data/docs/ROADMAP.md +221 -0
  121. data/docs/SQL_FUNCTIONS.md +1408 -0
  122. data/docs/TASK_DIAGRAM.md +252 -0
  123. data/docs/TASK_EXECUTION_CONTROL_FLOW.md +237 -0
  124. data/docs/TELEMETRY.md +795 -0
  125. data/docs/TROUBLESHOOTING.md +756 -0
  126. data/docs/TaskHandlerGenerator.html +255 -0
  127. data/docs/Tasker/Analysis/RuntimeGraphAnalyzer.html +907 -0
  128. data/docs/Tasker/Analysis/TemplateGraphAnalyzer.html +1236 -0
  129. data/docs/Tasker/Analysis.html +117 -0
  130. data/docs/Tasker/AnalyticsController.html +450 -0
  131. data/docs/Tasker/AnalyticsService/BottleneckAnalytics.html +816 -0
  132. data/docs/Tasker/AnalyticsService/PerformanceAnalytics.html +586 -0
  133. data/docs/Tasker/AnalyticsService.html +2221 -0
  134. data/docs/Tasker/AnnotationType.html +137 -0
  135. data/docs/Tasker/AnnotationTypeSerializer.html +124 -0
  136. data/docs/Tasker/ApplicationController.html +147 -0
  137. data/docs/Tasker/ApplicationJob.html +128 -0
  138. data/docs/Tasker/ApplicationRecord.html +378 -0
  139. data/docs/Tasker/Authentication/AuthenticationError.html +124 -0
  140. data/docs/Tasker/Authentication/ConfigurationError.html +124 -0
  141. data/docs/Tasker/Authentication/Coordinator.html +242 -0
  142. data/docs/Tasker/Authentication/Interface.html +560 -0
  143. data/docs/Tasker/Authentication/InterfaceError.html +124 -0
  144. data/docs/Tasker/Authentication/NoneAuthenticator.html +338 -0
  145. data/docs/Tasker/Authentication.html +119 -0
  146. data/docs/Tasker/Authorization/AuthorizationError.html +139 -0
  147. data/docs/Tasker/Authorization/BaseCoordinator.html +927 -0
  148. data/docs/Tasker/Authorization/ConfigurationError.html +153 -0
  149. data/docs/Tasker/Authorization/ResourceConstants/ACTIONS.html +428 -0
  150. data/docs/Tasker/Authorization/ResourceConstants/RESOURCES.html +365 -0
  151. data/docs/Tasker/Authorization/ResourceConstants.html +146 -0
  152. data/docs/Tasker/Authorization/ResourceRegistry.html +882 -0
  153. data/docs/Tasker/Authorization/UnauthorizedError.html +153 -0
  154. data/docs/Tasker/Authorization.html +582 -0
  155. data/docs/Tasker/CacheCapabilities.html +167 -0
  156. data/docs/Tasker/CacheStrategy.html +1297 -0
  157. data/docs/Tasker/Concerns/Authenticatable.html +116 -0
  158. data/docs/Tasker/Concerns/Authorizable/AdminStatusChecker.html +256 -0
  159. data/docs/Tasker/Concerns/Authorizable.html +816 -0
  160. data/docs/Tasker/Concerns/ControllerAuthorizable.html +157 -0
  161. data/docs/Tasker/Concerns/EventPublisher.html +4023 -0
  162. data/docs/Tasker/Concerns/IdempotentStateTransitions.html +806 -0
  163. data/docs/Tasker/Concerns/LifecycleEventHelpers.html +129 -0
  164. data/docs/Tasker/Concerns/OrchestrationPublisher.html +129 -0
  165. data/docs/Tasker/Concerns/StateMachineBase/ClassMethods.html +1075 -0
  166. data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase/ClassMethods.html +191 -0
  167. data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase.html +126 -0
  168. data/docs/Tasker/Concerns/StateMachineBase.html +153 -0
  169. data/docs/Tasker/Concerns/StructuredLogging.html +1413 -0
  170. data/docs/Tasker/Concerns.html +117 -0
  171. data/docs/Tasker/Configuration/AuthConfiguration.html +1023 -0
  172. data/docs/Tasker/Configuration/ConfigurationProxy.html +581 -0
  173. data/docs/Tasker/Configuration/DatabaseConfiguration.html +475 -0
  174. data/docs/Tasker/Configuration/EngineConfiguration.html +1265 -0
  175. data/docs/Tasker/Configuration/HealthConfiguration.html +791 -0
  176. data/docs/Tasker/Configuration/TelemetryConfiguration.html +1308 -0
  177. data/docs/Tasker/Configuration/TelemetryConfigurationProxy.html +388 -0
  178. data/docs/Tasker/Configuration.html +1669 -0
  179. data/docs/Tasker/ConfigurationError.html +143 -0
  180. data/docs/Tasker/ConfiguredTask.html +514 -0
  181. data/docs/Tasker/Constants/EventDefinitions.html +590 -0
  182. data/docs/Tasker/Constants/LifecycleEvents.html +137 -0
  183. data/docs/Tasker/Constants/ObservabilityEvents/Step.html +152 -0
  184. data/docs/Tasker/Constants/ObservabilityEvents/Task.html +142 -0
  185. data/docs/Tasker/Constants/ObservabilityEvents.html +126 -0
  186. data/docs/Tasker/Constants/RegistryEvents.html +285 -0
  187. data/docs/Tasker/Constants/StepEvents.html +177 -0
  188. data/docs/Tasker/Constants/TaskEvents.html +167 -0
  189. data/docs/Tasker/Constants/TaskExecution/ExecutionStatus.html +207 -0
  190. data/docs/Tasker/Constants/TaskExecution/HealthStatus.html +191 -0
  191. data/docs/Tasker/Constants/TaskExecution/RecommendedAction.html +207 -0
  192. data/docs/Tasker/Constants/TaskExecution.html +126 -0
  193. data/docs/Tasker/Constants/TaskFinalization/ErrorMessages.html +132 -0
  194. data/docs/Tasker/Constants/TaskFinalization/PendingReasons.html +207 -0
  195. data/docs/Tasker/Constants/TaskFinalization/ReenqueueReasons.html +239 -0
  196. data/docs/Tasker/Constants/TaskFinalization.html +126 -0
  197. data/docs/Tasker/Constants/TaskStatuses.html +223 -0
  198. data/docs/Tasker/Constants/TestEvents.html +163 -0
  199. data/docs/Tasker/Constants/WorkflowEvents.html +222 -0
  200. data/docs/Tasker/Constants/WorkflowStepStatuses.html +223 -0
  201. data/docs/Tasker/Constants.html +561 -0
  202. data/docs/Tasker/DependentSystem.html +137 -0
  203. data/docs/Tasker/DependentSystemObjectMap.html +250 -0
  204. data/docs/Tasker/DetectorRegistry.html +598 -0
  205. data/docs/Tasker/Diagram/Edge.html +1191 -0
  206. data/docs/Tasker/Diagram/Flowchart.html +1539 -0
  207. data/docs/Tasker/Diagram/Node.html +1165 -0
  208. data/docs/Tasker/Diagram.html +117 -0
  209. data/docs/Tasker/Engine.html +215 -0
  210. data/docs/Tasker/Error.html +139 -0
  211. data/docs/Tasker/Events/Bus.html +1226 -0
  212. data/docs/Tasker/Events/Catalog/CatalogPrinter.html +258 -0
  213. data/docs/Tasker/Events/Catalog/CustomEventRegistrar.html +276 -0
  214. data/docs/Tasker/Events/Catalog/ExamplePayloadGenerator.html +294 -0
  215. data/docs/Tasker/Events/Catalog.html +1291 -0
  216. data/docs/Tasker/Events/CustomRegistry.html +943 -0
  217. data/docs/Tasker/Events/DefinitionLoader.html +575 -0
  218. data/docs/Tasker/Events/EventPayloadBuilder/ErrorInfoExtractor.html +286 -0
  219. data/docs/Tasker/Events/EventPayloadBuilder/StepPayloadBuilder.html +312 -0
  220. data/docs/Tasker/Events/EventPayloadBuilder.html +664 -0
  221. data/docs/Tasker/Events/Publisher.html +365 -0
  222. data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer/ErrorTypeClassifier.html +1128 -0
  223. data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer.html +270 -0
  224. data/docs/Tasker/Events/Subscribers/BaseSubscriber/MetricTagsExtractor.html +266 -0
  225. data/docs/Tasker/Events/Subscribers/BaseSubscriber.html +2556 -0
  226. data/docs/Tasker/Events/Subscribers/MetricsSubscriber.html +723 -0
  227. data/docs/Tasker/Events/Subscribers/TelemetrySubscriber.html +2251 -0
  228. data/docs/Tasker/Events/Subscribers.html +117 -0
  229. data/docs/Tasker/Events/SubscriptionLoader.html +493 -0
  230. data/docs/Tasker/Events.html +294 -0
  231. data/docs/Tasker/EventsGenerator.html +459 -0
  232. data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics/AnalyticsMetrics.html +135 -0
  233. data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics.html +412 -0
  234. data/docs/Tasker/Functions/FunctionBasedDependencyLevels.html +598 -0
  235. data/docs/Tasker/Functions/FunctionBasedSlowestSteps/SlowestStep.html +135 -0
  236. data/docs/Tasker/Functions/FunctionBasedSlowestSteps.html +453 -0
  237. data/docs/Tasker/Functions/FunctionBasedSlowestTasks/SlowestTask.html +135 -0
  238. data/docs/Tasker/Functions/FunctionBasedSlowestTasks.html +453 -0
  239. data/docs/Tasker/Functions/FunctionBasedStepReadinessStatus.html +1457 -0
  240. data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts/HealthMetrics.html +135 -0
  241. data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts.html +370 -0
  242. data/docs/Tasker/Functions/FunctionBasedTaskExecutionContext.html +1250 -0
  243. data/docs/Tasker/Functions/FunctionWrapper.html +479 -0
  244. data/docs/Tasker/Functions.html +117 -0
  245. data/docs/Tasker/Generators/AuthenticatorGenerator/UsageInstructionsFormatter.html +244 -0
  246. data/docs/Tasker/Generators/AuthenticatorGenerator.html +373 -0
  247. data/docs/Tasker/Generators/AuthorizationCoordinatorGenerator.html +430 -0
  248. data/docs/Tasker/Generators/SubscriberGenerator.html +377 -0
  249. data/docs/Tasker/Generators/TaskHandlerGenerator.html +263 -0
  250. data/docs/Tasker/Generators.html +117 -0
  251. data/docs/Tasker/GraphQLTypes/AnnotationType.html +132 -0
  252. data/docs/Tasker/GraphQLTypes/BaseArgument.html +124 -0
  253. data/docs/Tasker/GraphQLTypes/BaseConnection.html +124 -0
  254. data/docs/Tasker/GraphQLTypes/BaseEdge.html +130 -0
  255. data/docs/Tasker/GraphQLTypes/BaseEnum.html +124 -0
  256. data/docs/Tasker/GraphQLTypes/BaseField.html +124 -0
  257. data/docs/Tasker/GraphQLTypes/BaseInputObject.html +124 -0
  258. data/docs/Tasker/GraphQLTypes/BaseInterface.html +116 -0
  259. data/docs/Tasker/GraphQLTypes/BaseObject.html +128 -0
  260. data/docs/Tasker/GraphQLTypes/BaseScalar.html +124 -0
  261. data/docs/Tasker/GraphQLTypes/BaseUnion.html +124 -0
  262. data/docs/Tasker/GraphQLTypes/DependentSystemObjectMapType.html +132 -0
  263. data/docs/Tasker/GraphQLTypes/DependentSystemType.html +132 -0
  264. data/docs/Tasker/GraphQLTypes/MutationType.html +132 -0
  265. data/docs/Tasker/GraphQLTypes/NamedStepType.html +132 -0
  266. data/docs/Tasker/GraphQLTypes/NamedTaskType.html +132 -0
  267. data/docs/Tasker/GraphQLTypes/NamedTasksNamedStepType.html +132 -0
  268. data/docs/Tasker/GraphQLTypes/NodeType.html +118 -0
  269. data/docs/Tasker/GraphQLTypes/QueryType.html +139 -0
  270. data/docs/Tasker/GraphQLTypes/TaskAnnotationType.html +132 -0
  271. data/docs/Tasker/GraphQLTypes/TaskInterface.html +111 -0
  272. data/docs/Tasker/GraphQLTypes/TaskType.html +201 -0
  273. data/docs/Tasker/GraphQLTypes/WorkflowStepType.html +694 -0
  274. data/docs/Tasker/GraphQLTypes.html +130 -0
  275. data/docs/Tasker/GraphqlController.html +251 -0
  276. data/docs/Tasker/HandlerFactory.html +1518 -0
  277. data/docs/Tasker/HandlerSerializer.html +682 -0
  278. data/docs/Tasker/HandlersController.html +574 -0
  279. data/docs/Tasker/HashIdentityStrategy.html +278 -0
  280. data/docs/Tasker/Health/ReadinessChecker.html +712 -0
  281. data/docs/Tasker/Health/StatusChecker.html +653 -0
  282. data/docs/Tasker/Health.html +117 -0
  283. data/docs/Tasker/HealthController.html +523 -0
  284. data/docs/Tasker/IdentityStrategy.html +276 -0
  285. data/docs/Tasker/InvalidTaskHandlerConfig.html +135 -0
  286. data/docs/Tasker/LifecycleEvents/Events/Step.html +162 -0
  287. data/docs/Tasker/LifecycleEvents/Events/Task.html +162 -0
  288. data/docs/Tasker/LifecycleEvents/Events.html +204 -0
  289. data/docs/Tasker/LifecycleEvents/Publisher.html +132 -0
  290. data/docs/Tasker/LifecycleEvents.html +799 -0
  291. data/docs/Tasker/Logging/CorrelationIdGenerator.html +688 -0
  292. data/docs/Tasker/Logging.html +115 -0
  293. data/docs/Tasker/MetricsController.html +293 -0
  294. data/docs/Tasker/MetricsExportJob.html +414 -0
  295. data/docs/Tasker/Mutations/BaseMutation.html +128 -0
  296. data/docs/Tasker/Mutations/CancelStep.html +219 -0
  297. data/docs/Tasker/Mutations/CancelTask.html +221 -0
  298. data/docs/Tasker/Mutations/CreateTask.html +243 -0
  299. data/docs/Tasker/Mutations/UpdateStep.html +243 -0
  300. data/docs/Tasker/Mutations/UpdateTask.html +243 -0
  301. data/docs/Tasker/Mutations.html +117 -0
  302. data/docs/Tasker/NamedStep.html +216 -0
  303. data/docs/Tasker/NamedTask.html +910 -0
  304. data/docs/Tasker/NamedTasksNamedStep.html +435 -0
  305. data/docs/Tasker/Orchestration/BackoffCalculator.html +404 -0
  306. data/docs/Tasker/Orchestration/ConnectionBuilder/ConfigValidator.html +258 -0
  307. data/docs/Tasker/Orchestration/ConnectionBuilder.html +435 -0
  308. data/docs/Tasker/Orchestration/ConnectionPoolIntelligence.html +513 -0
  309. data/docs/Tasker/Orchestration/Coordinator.html +641 -0
  310. data/docs/Tasker/Orchestration/FutureStateAnalyzer.html +1045 -0
  311. data/docs/Tasker/Orchestration/Orchestrator.html +679 -0
  312. data/docs/Tasker/Orchestration/PluginIntegration.html +1127 -0
  313. data/docs/Tasker/Orchestration/ResponseProcessor.html +504 -0
  314. data/docs/Tasker/Orchestration/RetryHeaderParser.html +304 -0
  315. data/docs/Tasker/Orchestration/StepExecutor.html +995 -0
  316. data/docs/Tasker/Orchestration/StepSequenceFactory.html +644 -0
  317. data/docs/Tasker/Orchestration/TaskFinalizer/BlockageChecker.html +264 -0
  318. data/docs/Tasker/Orchestration/TaskFinalizer/ContextManager.html +254 -0
  319. data/docs/Tasker/Orchestration/TaskFinalizer/DelayCalculator.html +556 -0
  320. data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationDecisionMaker.html +348 -0
  321. data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationProcessor.html +286 -0
  322. data/docs/Tasker/Orchestration/TaskFinalizer/ReasonDeterminer.html +432 -0
  323. data/docs/Tasker/Orchestration/TaskFinalizer/ReenqueueManager.html +296 -0
  324. data/docs/Tasker/Orchestration/TaskFinalizer/UnclearStateHandler.html +314 -0
  325. data/docs/Tasker/Orchestration/TaskFinalizer.html +1212 -0
  326. data/docs/Tasker/Orchestration/TaskInitializer.html +766 -0
  327. data/docs/Tasker/Orchestration/TaskReenqueuer.html +506 -0
  328. data/docs/Tasker/Orchestration/ViableStepDiscovery.html +442 -0
  329. data/docs/Tasker/Orchestration/WorkflowCoordinator.html +510 -0
  330. data/docs/Tasker/Orchestration.html +130 -0
  331. data/docs/Tasker/PageSort/PageSortParamsBuilder.html +296 -0
  332. data/docs/Tasker/PageSort.html +247 -0
  333. data/docs/Tasker/PermanentError.html +518 -0
  334. data/docs/Tasker/ProceduralError.html +147 -0
  335. data/docs/Tasker/Queries/AllAnnotationTypes.html +217 -0
  336. data/docs/Tasker/Queries/AllTasks.html +221 -0
  337. data/docs/Tasker/Queries/BaseQuery.html +128 -0
  338. data/docs/Tasker/Queries/Helpers.html +187 -0
  339. data/docs/Tasker/Queries/OneStep.html +225 -0
  340. data/docs/Tasker/Queries/OneTask.html +217 -0
  341. data/docs/Tasker/Queries/TasksByAnnotation.html +231 -0
  342. data/docs/Tasker/Queries/TasksByStatus.html +233 -0
  343. data/docs/Tasker/Queries.html +119 -0
  344. data/docs/Tasker/Railtie.html +124 -0
  345. data/docs/Tasker/Registry/BaseRegistry.html +1690 -0
  346. data/docs/Tasker/Registry/EventPublisher.html +667 -0
  347. data/docs/Tasker/Registry/InterfaceValidator.html +569 -0
  348. data/docs/Tasker/Registry/RegistrationError.html +132 -0
  349. data/docs/Tasker/Registry/RegistryError.html +139 -0
  350. data/docs/Tasker/Registry/StatisticsCollector.html +841 -0
  351. data/docs/Tasker/Registry/SubscriberRegistry.html +1504 -0
  352. data/docs/Tasker/Registry/ValidationError.html +132 -0
  353. data/docs/Tasker/Registry.html +119 -0
  354. data/docs/Tasker/RetryableError.html +515 -0
  355. data/docs/Tasker/StateMachine/Compatibility.html +282 -0
  356. data/docs/Tasker/StateMachine/InvalidStateTransition.html +135 -0
  357. data/docs/Tasker/StateMachine/StepStateMachine/StandardizedPayloadBuilder.html +260 -0
  358. data/docs/Tasker/StateMachine/StepStateMachine.html +2215 -0
  359. data/docs/Tasker/StateMachine/TaskStateMachine.html +734 -0
  360. data/docs/Tasker/StateMachine.html +602 -0
  361. data/docs/Tasker/StepDagRelationship.html +657 -0
  362. data/docs/Tasker/StepHandler/Api/Config.html +1091 -0
  363. data/docs/Tasker/StepHandler/Api.html +884 -0
  364. data/docs/Tasker/StepHandler/AutomaticEventPublishing.html +321 -0
  365. data/docs/Tasker/StepHandler/Base.html +970 -0
  366. data/docs/Tasker/StepHandler.html +119 -0
  367. data/docs/Tasker/StepReadinessStatus.html +836 -0
  368. data/docs/Tasker/Task.html +2575 -0
  369. data/docs/Tasker/TaskAnnotation.html +137 -0
  370. data/docs/Tasker/TaskAnnotationSerializer.html +124 -0
  371. data/docs/Tasker/TaskBuilder/StepNameValidator.html +264 -0
  372. data/docs/Tasker/TaskBuilder/StepTemplateDefiner.html +264 -0
  373. data/docs/Tasker/TaskBuilder.html +764 -0
  374. data/docs/Tasker/TaskDiagram/StepToStepEdgeBuilder.html +260 -0
  375. data/docs/Tasker/TaskDiagram/TaskToRootStepEdgeBuilder.html +290 -0
  376. data/docs/Tasker/TaskDiagram.html +548 -0
  377. data/docs/Tasker/TaskDiagramsController.html +240 -0
  378. data/docs/Tasker/TaskExecutionContext.html +469 -0
  379. data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/ClassBasedEventRegistrar.html +238 -0
  380. data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/YamlEventRegistrar.html +254 -0
  381. data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner.html +988 -0
  382. data/docs/Tasker/TaskHandler/ClassMethods.html +357 -0
  383. data/docs/Tasker/TaskHandler/InstanceMethods.html +1396 -0
  384. data/docs/Tasker/TaskHandler/StepGroup.html +1748 -0
  385. data/docs/Tasker/TaskHandler.html +271 -0
  386. data/docs/Tasker/TaskNamespace.html +312 -0
  387. data/docs/Tasker/TaskRunnerJob.html +406 -0
  388. data/docs/Tasker/TaskSerializer.html +474 -0
  389. data/docs/Tasker/TaskTransition.html +1517 -0
  390. data/docs/Tasker/TaskWorkflowSummary.html +988 -0
  391. data/docs/Tasker/TaskerRailsSchema/InvalidObjectTypeError.html +132 -0
  392. data/docs/Tasker/TaskerRailsSchema/TypeResolutionError.html +139 -0
  393. data/docs/Tasker/TaskerRailsSchema/UnknownInterfaceError.html +132 -0
  394. data/docs/Tasker/TaskerRailsSchema.html +384 -0
  395. data/docs/Tasker/TasksController.html +595 -0
  396. data/docs/Tasker/Telemetry/EventMapping.html +1307 -0
  397. data/docs/Tasker/Telemetry/EventRouter.html +2178 -0
  398. data/docs/Tasker/Telemetry/Events/ExportEvents.html +246 -0
  399. data/docs/Tasker/Telemetry/Events.html +115 -0
  400. data/docs/Tasker/Telemetry/ExportCoordinator/DistributedLockTimeoutError.html +135 -0
  401. data/docs/Tasker/Telemetry/ExportCoordinator.html +2137 -0
  402. data/docs/Tasker/Telemetry/IntelligentCacheManager.html +1083 -0
  403. data/docs/Tasker/Telemetry/LogBackend.html +1088 -0
  404. data/docs/Tasker/Telemetry/MetricTypes/Counter.html +1054 -0
  405. data/docs/Tasker/Telemetry/MetricTypes/Gauge.html +1270 -0
  406. data/docs/Tasker/Telemetry/MetricTypes/Histogram.html +1492 -0
  407. data/docs/Tasker/Telemetry/MetricTypes.html +153 -0
  408. data/docs/Tasker/Telemetry/MetricsBackend.html +2510 -0
  409. data/docs/Tasker/Telemetry/MetricsExportService.html +578 -0
  410. data/docs/Tasker/Telemetry/PluginRegistry.html +1774 -0
  411. data/docs/Tasker/Telemetry/Plugins/BaseExporter.html +1835 -0
  412. data/docs/Tasker/Telemetry/Plugins/CsvExporter.html +768 -0
  413. data/docs/Tasker/Telemetry/Plugins/JsonExporter.html +747 -0
  414. data/docs/Tasker/Telemetry/Plugins.html +117 -0
  415. data/docs/Tasker/Telemetry/PrometheusExporter.html +481 -0
  416. data/docs/Tasker/Telemetry/TraceBackend.html +891 -0
  417. data/docs/Tasker/Telemetry.html +130 -0
  418. data/docs/Tasker/Types/AuthConfig.html +886 -0
  419. data/docs/Tasker/Types/BackoffConfig.html +1063 -0
  420. data/docs/Tasker/Types/BaseConfig.html +227 -0
  421. data/docs/Tasker/Types/CacheConfig.html +1731 -0
  422. data/docs/Tasker/Types/DatabaseConfig.html +388 -0
  423. data/docs/Tasker/Types/DependencyGraph.html +526 -0
  424. data/docs/Tasker/Types/DependencyGraphConfig.html +753 -0
  425. data/docs/Tasker/Types/EngineConfig.html +1181 -0
  426. data/docs/Tasker/Types/ExecutionConfig.html +1963 -0
  427. data/docs/Tasker/Types/GraphEdge.html +517 -0
  428. data/docs/Tasker/Types/GraphMetadata.html +781 -0
  429. data/docs/Tasker/Types/GraphNode.html +694 -0
  430. data/docs/Tasker/Types/HealthConfig.html +784 -0
  431. data/docs/Tasker/Types/StepSequence.html +353 -0
  432. data/docs/Tasker/Types/StepTemplate.html +1193 -0
  433. data/docs/Tasker/Types/TaskRequest.html +1179 -0
  434. data/docs/Tasker/Types/TelemetryConfig.html +2746 -0
  435. data/docs/Tasker/Types.html +154 -0
  436. data/docs/Tasker/WorkflowStep/StepFinder.html +282 -0
  437. data/docs/Tasker/WorkflowStep.html +2724 -0
  438. data/docs/Tasker/WorkflowStepEdge.html +304 -0
  439. data/docs/Tasker/WorkflowStepSerializer.html +305 -0
  440. data/docs/Tasker/WorkflowStepTransition/TransitionDescriptionFormatter.html +282 -0
  441. data/docs/Tasker/WorkflowStepTransition.html +2201 -0
  442. data/docs/Tasker/WorkflowStepsController.html +462 -0
  443. data/docs/Tasker.html +452 -0
  444. data/docs/VISION.md +584 -0
  445. data/docs/WHY.md +21 -0
  446. data/docs/_index.html +2375 -0
  447. data/docs/class_list.html +54 -0
  448. data/docs/css/common.css +1 -0
  449. data/docs/css/full_list.css +58 -0
  450. data/docs/css/style.css +503 -0
  451. data/docs/events/migration_plan_outcomes.md +80 -0
  452. data/docs/file.README.html +541 -0
  453. data/docs/file_list.html +59 -0
  454. data/docs/frames.html +22 -0
  455. data/docs/index.html +541 -0
  456. data/docs/js/app.js +344 -0
  457. data/docs/js/full_list.js +242 -0
  458. data/docs/js/jquery.js +4 -0
  459. data/docs/method_list.html +9182 -0
  460. data/docs/top-level-namespace.html +110 -0
  461. data/lib/generators/tasker/authenticator_generator.rb +301 -0
  462. data/lib/generators/tasker/authorization_coordinator_generator.rb +139 -0
  463. data/lib/generators/tasker/events_generator.rb +91 -0
  464. data/lib/generators/tasker/subscriber_generator.rb +107 -0
  465. data/lib/generators/tasker/task_handler_generator.rb +138 -0
  466. data/lib/generators/tasker/templates/api_token_authenticator.rb.erb +113 -0
  467. data/lib/generators/tasker/templates/api_token_authenticator_spec.rb.erb +144 -0
  468. data/lib/generators/tasker/templates/authorization_coordinator.rb.erb +95 -0
  469. data/lib/generators/tasker/templates/authorization_coordinator_spec.rb.erb +142 -0
  470. data/lib/generators/tasker/templates/custom_authenticator.rb.erb +108 -0
  471. data/lib/generators/tasker/templates/custom_authenticator_spec.rb.erb +162 -0
  472. data/lib/generators/tasker/templates/custom_events.yml.erb +62 -0
  473. data/lib/generators/tasker/templates/custom_subscriber.rb.erb +72 -0
  474. data/lib/generators/tasker/templates/devise_authenticator.rb.erb +101 -0
  475. data/lib/generators/tasker/templates/devise_authenticator_spec.rb.erb +126 -0
  476. data/lib/generators/tasker/templates/initialize.rb.erb +202 -0
  477. data/lib/generators/tasker/templates/jwt_authenticator.rb.erb +144 -0
  478. data/lib/generators/tasker/templates/jwt_authenticator_spec.rb.erb +298 -0
  479. data/lib/generators/tasker/templates/metrics_subscriber.rb.erb +258 -0
  480. data/lib/generators/tasker/templates/metrics_subscriber_spec.rb.erb +308 -0
  481. data/lib/generators/tasker/templates/omniauth_authenticator.rb.erb +135 -0
  482. data/lib/generators/tasker/templates/omniauth_authenticator_spec.rb.erb +196 -0
  483. data/lib/generators/tasker/templates/opentelemetry_initializer.rb +52 -0
  484. data/lib/generators/tasker/templates/subscriber.rb.erb +64 -0
  485. data/lib/generators/tasker/templates/subscriber_spec.rb.erb +80 -0
  486. data/lib/generators/tasker/templates/task_config.yaml.erb +117 -0
  487. data/lib/generators/tasker/templates/task_handler.rb.erb +59 -0
  488. data/lib/generators/tasker/templates/task_handler_spec.rb.erb +159 -0
  489. data/lib/tasker/analysis/runtime_graph_analyzer.rb +1168 -0
  490. data/lib/tasker/analysis/template_graph_analyzer.rb +328 -0
  491. data/lib/tasker/authentication/coordinator.rb +78 -0
  492. data/lib/tasker/authentication/errors.rb +9 -0
  493. data/lib/tasker/authentication/interface.rb +36 -0
  494. data/lib/tasker/authentication/none_authenticator.rb +26 -0
  495. data/lib/tasker/authorization/base_coordinator.rb +112 -0
  496. data/lib/tasker/authorization/errors.rb +26 -0
  497. data/lib/tasker/authorization/resource_constants.rb +74 -0
  498. data/lib/tasker/authorization/resource_registry.rb +143 -0
  499. data/lib/tasker/authorization.rb +75 -0
  500. data/lib/tasker/cache_capabilities.rb +131 -0
  501. data/lib/tasker/cache_strategy.rb +469 -0
  502. data/lib/tasker/concerns/authenticatable.rb +41 -0
  503. data/lib/tasker/concerns/authorizable.rb +204 -0
  504. data/lib/tasker/concerns/controller_authorizable.rb +124 -0
  505. data/lib/tasker/concerns/event_publisher.rb +716 -0
  506. data/lib/tasker/concerns/idempotent_state_transitions.rb +128 -0
  507. data/lib/tasker/concerns/state_machine_base.rb +218 -0
  508. data/lib/tasker/concerns/structured_logging.rb +387 -0
  509. data/lib/tasker/configuration.rb +325 -0
  510. data/lib/tasker/constants/event_definitions.rb +147 -0
  511. data/lib/tasker/constants/registry_events.rb +54 -0
  512. data/lib/tasker/constants.rb +417 -0
  513. data/lib/tasker/engine.rb +90 -0
  514. data/lib/tasker/errors.rb +90 -0
  515. data/lib/tasker/events/catalog.rb +432 -0
  516. data/lib/tasker/events/custom_registry.rb +175 -0
  517. data/lib/tasker/events/definition_loader.rb +199 -0
  518. data/lib/tasker/events/event_payload_builder.rb +461 -0
  519. data/lib/tasker/events/publisher.rb +149 -0
  520. data/lib/tasker/events/subscribers/base_subscriber.rb +601 -0
  521. data/lib/tasker/events/subscribers/metrics_subscriber.rb +120 -0
  522. data/lib/tasker/events/subscribers/telemetry_subscriber.rb +462 -0
  523. data/lib/tasker/events/subscription_loader.rb +161 -0
  524. data/lib/tasker/events.rb +37 -0
  525. data/lib/tasker/functions/function_based_analytics_metrics.rb +103 -0
  526. data/lib/tasker/functions/function_based_dependency_levels.rb +54 -0
  527. data/lib/tasker/functions/function_based_slowest_steps.rb +84 -0
  528. data/lib/tasker/functions/function_based_slowest_tasks.rb +84 -0
  529. data/lib/tasker/functions/function_based_step_readiness_status.rb +183 -0
  530. data/lib/tasker/functions/function_based_system_health_counts.rb +94 -0
  531. data/lib/tasker/functions/function_based_task_execution_context.rb +148 -0
  532. data/lib/tasker/functions/function_wrapper.rb +42 -0
  533. data/lib/tasker/functions.rb +12 -0
  534. data/lib/tasker/handler_factory.rb +322 -0
  535. data/lib/tasker/health/readiness_checker.rb +186 -0
  536. data/lib/tasker/health/status_checker.rb +203 -0
  537. data/lib/tasker/identity_strategy.rb +38 -0
  538. data/lib/tasker/logging/correlation_id_generator.rb +120 -0
  539. data/lib/tasker/orchestration/backoff_calculator.rb +184 -0
  540. data/lib/tasker/orchestration/connection_builder.rb +122 -0
  541. data/lib/tasker/orchestration/connection_pool_intelligence.rb +177 -0
  542. data/lib/tasker/orchestration/coordinator.rb +119 -0
  543. data/lib/tasker/orchestration/future_state_analyzer.rb +137 -0
  544. data/lib/tasker/orchestration/plugin_integration.rb +124 -0
  545. data/lib/tasker/orchestration/response_processor.rb +168 -0
  546. data/lib/tasker/orchestration/retry_header_parser.rb +78 -0
  547. data/lib/tasker/orchestration/step_executor.rb +941 -0
  548. data/lib/tasker/orchestration/step_sequence_factory.rb +67 -0
  549. data/lib/tasker/orchestration/task_finalizer.rb +564 -0
  550. data/lib/tasker/orchestration/task_initializer.rb +140 -0
  551. data/lib/tasker/orchestration/task_reenqueuer.rb +71 -0
  552. data/lib/tasker/orchestration/viable_step_discovery.rb +65 -0
  553. data/lib/tasker/orchestration/workflow_coordinator.rb +294 -0
  554. data/lib/tasker/orchestration.rb +45 -0
  555. data/lib/tasker/railtie.rb +9 -0
  556. data/lib/tasker/registry/base_registry.rb +177 -0
  557. data/lib/tasker/registry/event_publisher.rb +91 -0
  558. data/lib/tasker/registry/interface_validator.rb +140 -0
  559. data/lib/tasker/registry/statistics_collector.rb +381 -0
  560. data/lib/tasker/registry/subscriber_registry.rb +285 -0
  561. data/lib/tasker/registry.rb +22 -0
  562. data/lib/tasker/state_machine/step_state_machine.rb +508 -0
  563. data/lib/tasker/state_machine/task_state_machine.rb +192 -0
  564. data/lib/tasker/state_machine.rb +83 -0
  565. data/lib/tasker/step_handler/api.rb +410 -0
  566. data/lib/tasker/step_handler/base.rb +206 -0
  567. data/lib/tasker/task_builder.rb +432 -0
  568. data/lib/tasker/task_handler/class_methods.rb +324 -0
  569. data/lib/tasker/task_handler/instance_methods.rb +293 -0
  570. data/lib/tasker/task_handler/step_group.rb +182 -0
  571. data/lib/tasker/task_handler.rb +43 -0
  572. data/lib/tasker/telemetry/event_mapping.rb +126 -0
  573. data/lib/tasker/telemetry/event_router.rb +318 -0
  574. data/lib/tasker/telemetry/events/export_events.rb +38 -0
  575. data/lib/tasker/telemetry/export_coordinator.rb +497 -0
  576. data/lib/tasker/telemetry/intelligent_cache_manager.rb +508 -0
  577. data/lib/tasker/telemetry/log_backend.rb +224 -0
  578. data/lib/tasker/telemetry/metric_types.rb +368 -0
  579. data/lib/tasker/telemetry/metrics_backend.rb +1227 -0
  580. data/lib/tasker/telemetry/metrics_export_service.rb +392 -0
  581. data/lib/tasker/telemetry/plugin_registry.rb +333 -0
  582. data/lib/tasker/telemetry/plugins/base_exporter.rb +246 -0
  583. data/lib/tasker/telemetry/plugins/csv_exporter.rb +198 -0
  584. data/lib/tasker/telemetry/plugins/json_exporter.rb +141 -0
  585. data/lib/tasker/telemetry/prometheus_exporter.rb +249 -0
  586. data/lib/tasker/telemetry/trace_backend.rb +186 -0
  587. data/lib/tasker/telemetry.rb +59 -0
  588. data/lib/tasker/types/auth_config.rb +81 -0
  589. data/lib/tasker/types/backoff_config.rb +142 -0
  590. data/lib/tasker/types/cache_config.rb +257 -0
  591. data/lib/tasker/types/database_config.rb +39 -0
  592. data/lib/tasker/types/dependency_graph.rb +225 -0
  593. data/lib/tasker/types/dependency_graph_config.rb +149 -0
  594. data/lib/tasker/types/engine_config.rb +131 -0
  595. data/lib/tasker/types/execution_config.rb +289 -0
  596. data/lib/tasker/types/health_config.rb +84 -0
  597. data/lib/tasker/types/step_sequence.rb +24 -0
  598. data/lib/tasker/types/step_template.rb +63 -0
  599. data/lib/tasker/types/task_request.rb +60 -0
  600. data/lib/tasker/types/telemetry_config.rb +273 -0
  601. data/lib/tasker/types.rb +64 -0
  602. data/lib/tasker/version.rb +7 -0
  603. data/lib/tasker.rb +82 -0
  604. data/lib/tasks/tasker_tasks.rake +302 -0
  605. metadata +958 -0
data/config/routes.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: false
4
+
5
+ Tasker::Engine.routes.draw do
6
+ # Health check endpoints
7
+ scope '/health', as: :health do
8
+ get :ready, to: 'health#ready'
9
+ get :live, to: 'health#live'
10
+ get :status, to: 'health#status'
11
+ end
12
+
13
+ # Metrics endpoint
14
+ get '/metrics', to: 'metrics#index'
15
+
16
+ # Analytics endpoints
17
+ scope '/analytics', as: :analytics do
18
+ get :performance, to: 'analytics#performance'
19
+ get :bottlenecks, to: 'analytics#bottlenecks'
20
+ end
21
+
22
+ # Handler discovery endpoints
23
+ get '/handlers', to: 'handlers#index' # List namespaces
24
+ get '/handlers/:namespace', to: 'handlers#show_namespace' # List handlers in namespace
25
+ get '/handlers/:namespace/:name', to: 'handlers#show' # Show specific handler with dependency graph
26
+
27
+ post '/graphql', to: 'graphql#execute'
28
+ # mount Rswag::Ui::Engine => '/api-docs'
29
+ # mount Rswag::Api::Engine => '/api-docs'
30
+ resources :tasks do
31
+ resources :workflow_steps
32
+ resources :task_diagrams, only: %i[index]
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ # Example Event Subscription Configuration
2
+ # This file demonstrates how to configure event subscriptions for various integrations
3
+ # Place your subscription files in config/tasker/subscriptions/
4
+
5
+ subscriptions:
6
+ # Sentry Integration - Error tracking for failed tasks and steps
7
+ sentry_integration:
8
+ class: 'SentrySubscriber'
9
+ enabled: true
10
+ events:
11
+ - 'task.failed'
12
+ - 'step.failed'
13
+ - 'workflow.error'
14
+ config:
15
+ dsn: 'https://your-sentry-dsn@sentry.io/project-id'
16
+ environment: 'production'
17
+ tags:
18
+ component: 'tasker'
19
+
20
+ # PagerDuty Integration - Critical alerts for system issues
21
+ pagerduty_alerts:
22
+ class: 'PagerDutySubscriber'
23
+ enabled: false # Disabled by default
24
+ events:
25
+ - 'task.failed'
26
+ - 'workflow.blocked'
27
+ - 'system.error'
28
+ config:
29
+ integration_key: 'your-pagerduty-integration-key'
30
+ severity: 'critical'
31
+
32
+ # Slack Integration - Team notifications for task completion
33
+ slack_notifications:
34
+ class: 'SlackSubscriber'
35
+ enabled: true
36
+ events:
37
+ - 'task.completed'
38
+ - 'task.failed'
39
+ - 'workflow.completed'
40
+ config:
41
+ webhook_url: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
42
+ channel: '#engineering'
43
+ username: 'Tasker Bot'
44
+
45
+ # Custom Analytics Integration - Track task metrics
46
+ analytics_tracker:
47
+ class: 'AnalyticsSubscriber'
48
+ enabled: true
49
+ events:
50
+ - 'task.started'
51
+ - 'task.completed'
52
+ - 'task.failed'
53
+ - 'step.completed'
54
+ - 'step.failed'
55
+ config:
56
+ api_key: 'your-analytics-api-key'
57
+ endpoint: 'https://api.analytics.com/events'
58
+
59
+ # Development Debug Subscriber - Detailed logging for development
60
+ debug_logger:
61
+ class: 'DebugSubscriber'
62
+ enabled: false # Only enable in development
63
+ events:
64
+ - '*' # Subscribe to all events
65
+ config:
66
+ log_level: 'debug'
67
+ include_payload: true
@@ -0,0 +1,305 @@
1
+ ---
2
+ # Tasker System Events Metadata & State Machine Configuration
3
+ #
4
+ # This file provides rich metadata about system events and state machine mappings.
5
+ # The actual event constants are defined in lib/tasker/constants.rb.
6
+ #
7
+ # This file serves two purposes:
8
+ # 1. Event metadata for runtime introspection (descriptions, schemas, etc.)
9
+ # 2. State machine transition mappings for declarative configuration
10
+
11
+ # Event metadata for runtime introspection and documentation
12
+ event_metadata:
13
+ # Task lifecycle events
14
+ task:
15
+ initialize_requested:
16
+ description: "Fired when a task is being created and initialized"
17
+ constant_ref: "Tasker::Constants::TaskEvents::INITIALIZE_REQUESTED"
18
+ payload_schema:
19
+ task_id: { type: "String", required: true }
20
+ task_name: { type: "String", required: true }
21
+ timestamp: { type: "Time", required: true }
22
+ fired_by: ["TaskBuilder", "TaskStateMachine"]
23
+
24
+ start_requested:
25
+ description: "Fired when a task processing begins"
26
+ constant_ref: "Tasker::Constants::TaskEvents::START_REQUESTED"
27
+ payload_schema:
28
+ task_id: { type: "String", required: true }
29
+ task_name: { type: "String", required: true }
30
+ timestamp: { type: "Time", required: true }
31
+ fired_by: ["TaskHandler", "TaskStateMachine"]
32
+
33
+ completed:
34
+ description: "Fired when a task completes successfully"
35
+ constant_ref: "Tasker::Constants::TaskEvents::COMPLETED"
36
+ payload_schema:
37
+ task_id: { type: "String", required: true }
38
+ task_name: { type: "String", required: true }
39
+ total_steps: { type: "Integer", required: true }
40
+ completed_steps: { type: "Integer", required: true }
41
+ total_duration: { type: "Float", required: false }
42
+ timestamp: { type: "Time", required: true }
43
+ fired_by: ["TaskHandler", "TaskStateMachine"]
44
+
45
+ failed:
46
+ description: "Fired when a task fails due to errors"
47
+ constant_ref: "Tasker::Constants::TaskEvents::FAILED"
48
+ payload_schema:
49
+ task_id: { type: "String", required: true }
50
+ task_name: { type: "String", required: true }
51
+ error_message: { type: "String", required: true }
52
+ failed_steps: { type: "Array", required: false }
53
+ timestamp: { type: "Time", required: true }
54
+ fired_by: ["TaskHandler", "TaskStateMachine"]
55
+
56
+ retry_requested:
57
+ description: "Fired when a task is queued for retry"
58
+ constant_ref: "Tasker::Constants::TaskEvents::RETRY_REQUESTED"
59
+ payload_schema:
60
+ task_id: { type: "String", required: true }
61
+ task_name: { type: "String", required: true }
62
+ retry_reason: { type: "String", required: true }
63
+ timestamp: { type: "Time", required: true }
64
+ fired_by: ["TaskHandler", "TaskStateMachine"]
65
+
66
+ # Step lifecycle events
67
+ step:
68
+ execution_requested:
69
+ description: "Fired when a step is queued for execution"
70
+ constant_ref: "Tasker::Constants::StepEvents::EXECUTION_REQUESTED"
71
+ payload_schema:
72
+ task_id: { type: "String", required: true }
73
+ step_id: { type: "String", required: true }
74
+ step_name: { type: "String", required: true }
75
+ timestamp: { type: "Time", required: true }
76
+ fired_by: ["StepExecutor", "StepStateMachine"]
77
+
78
+ before_handle:
79
+ description: "Fired just before a step handler is called"
80
+ constant_ref: "Tasker::Constants::StepEvents::BEFORE_HANDLE"
81
+ payload_schema:
82
+ task_id: { type: "String", required: true }
83
+ step_id: { type: "String", required: true }
84
+ step_name: { type: "String", required: true }
85
+ timestamp: { type: "Time", required: true }
86
+ fired_by: ["StepHandler::Base", "StepHandler::Api"]
87
+
88
+ completed:
89
+ description: "Fired when a step completes successfully"
90
+ constant_ref: "Tasker::Constants::StepEvents::COMPLETED"
91
+ payload_schema:
92
+ task_id: { type: "String", required: true }
93
+ step_id: { type: "String", required: true }
94
+ step_name: { type: "String", required: true }
95
+ execution_duration: { type: "Float", required: true }
96
+ attempt_number: { type: "Integer", required: true }
97
+ timestamp: { type: "Time", required: true }
98
+ fired_by: ["StepHandler::Base", "StepHandler::Api", "StepStateMachine"]
99
+
100
+ failed:
101
+ description: "Fired when a step fails during execution"
102
+ constant_ref: "Tasker::Constants::StepEvents::FAILED"
103
+ payload_schema:
104
+ task_id: { type: "String", required: true }
105
+ step_id: { type: "String", required: true }
106
+ step_name: { type: "String", required: true }
107
+ error_message: { type: "String", required: true }
108
+ error_class: { type: "String", required: true }
109
+ backtrace: { type: "Array", required: false }
110
+ attempt_number: { type: "Integer", required: true }
111
+ timestamp: { type: "Time", required: true }
112
+ fired_by: ["StepHandler::Base", "StepHandler::Api", "StepStateMachine"]
113
+
114
+ # Workflow orchestration events
115
+ workflow:
116
+ viable_steps_discovered:
117
+ description: "Fired when steps are identified as ready for execution"
118
+ constant_ref: "Tasker::Constants::WorkflowEvents::VIABLE_STEPS_DISCOVERED"
119
+ payload_schema:
120
+ task_id: { type: "String", required: true }
121
+ step_ids: { type: "Array", required: true }
122
+ step_count: { type: "Integer", required: true }
123
+ processing_mode: { type: "String", required: true }
124
+ timestamp: { type: "Time", required: true }
125
+ fired_by: ["ViableStepDiscovery", "WorkflowOrchestrator"]
126
+
127
+ # Registry system events
128
+ handler:
129
+ registered:
130
+ description: "Fired when a handler is successfully registered"
131
+ constant_ref: "Tasker::Constants::RegistryEvents::HANDLER_REGISTERED"
132
+ payload_schema:
133
+ handler_class: { type: "String", required: true }
134
+ namespace_name: { type: "String", required: true }
135
+ version: { type: "String", required: true }
136
+ timestamp: { type: "Time", required: true }
137
+ fired_by: ["HandlerFactory", "Registry::BaseRegistry"]
138
+
139
+ unregistered:
140
+ description: "Fired when a handler is unregistered"
141
+ constant_ref: "Tasker::Constants::RegistryEvents::HANDLER_UNREGISTERED"
142
+ payload_schema:
143
+ handler_class: { type: "String", required: true }
144
+ namespace_name: { type: "String", required: true }
145
+ version: { type: "String", required: true }
146
+ timestamp: { type: "Time", required: true }
147
+ fired_by: ["HandlerFactory", "Registry::BaseRegistry"]
148
+
149
+ validation_failed:
150
+ description: "Fired when handler validation fails during registration"
151
+ constant_ref: "Tasker::Constants::RegistryEvents::HANDLER_VALIDATION_FAILED"
152
+ payload_schema:
153
+ handler_class: { type: "String", required: true }
154
+ validation_error: { type: "String", required: true }
155
+ timestamp: { type: "Time", required: true }
156
+ fired_by: ["HandlerFactory", "Registry::InterfaceValidator"]
157
+
158
+ plugin:
159
+ registered:
160
+ description: "Fired when a plugin is successfully registered"
161
+ constant_ref: "Tasker::Constants::RegistryEvents::PLUGIN_REGISTERED"
162
+ payload_schema:
163
+ plugin_class: { type: "String", required: true }
164
+ plugin_format: { type: "String", required: true }
165
+ timestamp: { type: "Time", required: true }
166
+ fired_by: ["PluginRegistry", "ExportCoordinator"]
167
+
168
+ unregistered:
169
+ description: "Fired when a plugin is unregistered"
170
+ constant_ref: "Tasker::Constants::RegistryEvents::PLUGIN_UNREGISTERED"
171
+ payload_schema:
172
+ plugin_class: { type: "String", required: true }
173
+ plugin_format: { type: "String", required: true }
174
+ timestamp: { type: "Time", required: true }
175
+ fired_by: ["PluginRegistry", "ExportCoordinator"]
176
+
177
+ validation_failed:
178
+ description: "Fired when plugin validation fails during registration"
179
+ constant_ref: "Tasker::Constants::RegistryEvents::PLUGIN_VALIDATION_FAILED"
180
+ payload_schema:
181
+ plugin_class: { type: "String", required: true }
182
+ validation_error: { type: "String", required: true }
183
+ timestamp: { type: "Time", required: true }
184
+ fired_by: ["PluginRegistry", "Registry::InterfaceValidator"]
185
+
186
+ subscriber:
187
+ registered:
188
+ description: "Fired when a subscriber is successfully registered"
189
+ constant_ref: "Tasker::Constants::RegistryEvents::SUBSCRIBER_REGISTERED"
190
+ payload_schema:
191
+ subscriber_class: { type: "String", required: true }
192
+ events: { type: "Array", required: true }
193
+ timestamp: { type: "Time", required: true }
194
+ fired_by: ["SubscriberRegistry", "Events::CustomRegistry"]
195
+
196
+ unregistered:
197
+ description: "Fired when a subscriber is unregistered"
198
+ constant_ref: "Tasker::Constants::RegistryEvents::SUBSCRIBER_UNREGISTERED"
199
+ payload_schema:
200
+ subscriber_class: { type: "String", required: true }
201
+ events: { type: "Array", required: true }
202
+ timestamp: { type: "Time", required: true }
203
+ fired_by: ["SubscriberRegistry", "Events::CustomRegistry"]
204
+
205
+ validation_failed:
206
+ description: "Fired when subscriber validation fails during registration"
207
+ constant_ref: "Tasker::Constants::RegistryEvents::SUBSCRIBER_VALIDATION_FAILED"
208
+ payload_schema:
209
+ subscriber_class: { type: "String", required: true }
210
+ validation_error: { type: "String", required: true }
211
+ timestamp: { type: "Time", required: true }
212
+ fired_by: ["SubscriberRegistry", "Registry::InterfaceValidator"]
213
+
214
+ # State machine transition mappings (declarative configuration)
215
+ state_machine_mappings:
216
+ task_transitions:
217
+ # Initial state transitions (from nil/initial)
218
+ - from_state: null
219
+ to_state: "pending"
220
+ event_constant: "task.initialize_requested"
221
+ description: "Task initialization"
222
+
223
+ - from_state: null
224
+ to_state: "in_progress"
225
+ event_constant: "task.start_requested"
226
+ description: "Direct task start"
227
+
228
+ - from_state: null
229
+ to_state: "complete"
230
+ event_constant: "task.completed"
231
+ description: "Direct task completion"
232
+
233
+ - from_state: null
234
+ to_state: "error"
235
+ event_constant: "task.failed"
236
+ description: "Direct task failure"
237
+
238
+ - from_state: null
239
+ to_state: "cancelled"
240
+ event_constant: "task.cancelled"
241
+ description: "Direct task cancellation"
242
+
243
+ - from_state: null
244
+ to_state: "resolved_manually"
245
+ event_constant: "task.resolved_manually"
246
+ description: "Direct manual resolution"
247
+
248
+ # Normal state transitions
249
+ - from_state: "pending"
250
+ to_state: "in_progress"
251
+ event_constant: "task.start_requested"
252
+ description: "Task starts processing"
253
+
254
+ - from_state: "pending"
255
+ to_state: "cancelled"
256
+ event_constant: "task.cancelled"
257
+ description: "Pending task cancelled"
258
+
259
+ - from_state: "pending"
260
+ to_state: "error"
261
+ event_constant: "task.failed"
262
+ description: "Pending task failed"
263
+
264
+ - from_state: "in_progress"
265
+ to_state: "pending"
266
+ event_constant: "task.initialize_requested"
267
+ description: "Reset task to pending"
268
+
269
+ - from_state: "in_progress"
270
+ to_state: "complete"
271
+ event_constant: "task.completed"
272
+ description: "Task completed successfully"
273
+
274
+ - from_state: "in_progress"
275
+ to_state: "error"
276
+ event_constant: "task.failed"
277
+ description: "Task failed during processing"
278
+
279
+ - from_state: "in_progress"
280
+ to_state: "cancelled"
281
+ event_constant: "task.cancelled"
282
+ description: "Running task cancelled"
283
+
284
+ - from_state: "error"
285
+ to_state: "pending"
286
+ event_constant: "task.retry_requested"
287
+ description: "Failed task retry"
288
+
289
+ - from_state: "error"
290
+ to_state: "resolved_manually"
291
+ event_constant: "task.resolved_manually"
292
+ description: "Failed task manually resolved"
293
+
294
+ # Admin override scenarios
295
+ - from_state: "complete"
296
+ to_state: "cancelled"
297
+ event_constant: "task.cancelled"
298
+ description: "Admin cancellation override"
299
+
300
+ - from_state: "resolved_manually"
301
+ to_state: "cancelled"
302
+ event_constant: "task.cancelled"
303
+ description: "Manual resolution cancelled"
304
+
305
+
@@ -0,0 +1,45 @@
1
+ -- Calculate Dependency Levels Function
2
+ -- Calculates the dependency level (depth) of each workflow step in a task
3
+ -- Uses recursive CTE to traverse the dependency graph and assign levels
4
+ -- Input: task_id
5
+ -- Output: workflow_step_id and its dependency level (0 = root, 1+ = depth from root)
6
+
7
+ CREATE OR REPLACE FUNCTION calculate_dependency_levels(input_task_id BIGINT)
8
+ RETURNS TABLE(
9
+ workflow_step_id BIGINT,
10
+ dependency_level INTEGER
11
+ ) LANGUAGE plpgsql STABLE AS $$
12
+ BEGIN
13
+ RETURN QUERY
14
+ WITH RECURSIVE dependency_levels AS (
15
+ -- Base case: Find root nodes (steps with no dependencies)
16
+ SELECT
17
+ ws.workflow_step_id,
18
+ 0 as level
19
+ FROM tasker_workflow_steps ws
20
+ WHERE ws.task_id = input_task_id
21
+ AND NOT EXISTS (
22
+ SELECT 1
23
+ FROM tasker_workflow_step_edges wse
24
+ WHERE wse.to_step_id = ws.workflow_step_id
25
+ )
26
+
27
+ UNION ALL
28
+
29
+ -- Recursive case: Find children of current level nodes
30
+ SELECT
31
+ wse.to_step_id as workflow_step_id,
32
+ dl.level + 1 as level
33
+ FROM dependency_levels dl
34
+ JOIN tasker_workflow_step_edges wse ON wse.from_step_id = dl.workflow_step_id
35
+ JOIN tasker_workflow_steps ws ON ws.workflow_step_id = wse.to_step_id
36
+ WHERE ws.task_id = input_task_id
37
+ )
38
+ SELECT
39
+ dl.workflow_step_id,
40
+ MAX(dl.level) as dependency_level -- Use MAX to handle multiple paths to same node
41
+ FROM dependency_levels dl
42
+ GROUP BY dl.workflow_step_id
43
+ ORDER BY dependency_level, workflow_step_id;
44
+ END;
45
+ $$;
@@ -0,0 +1,137 @@
1
+ -- Analytics Metrics Function
2
+ -- Returns comprehensive analytics metrics for performance monitoring
3
+ -- Input: since_timestamp for time-based filtering
4
+ -- Output: Single row with all analytics metrics
5
+
6
+ CREATE OR REPLACE FUNCTION get_analytics_metrics_v01(since_timestamp TIMESTAMPTZ DEFAULT NULL)
7
+ RETURNS TABLE (
8
+ -- System overview metrics
9
+ active_tasks_count BIGINT,
10
+ total_namespaces_count BIGINT,
11
+ unique_task_types_count BIGINT,
12
+ system_health_score NUMERIC(5,3),
13
+
14
+ -- Performance metrics since timestamp
15
+ task_throughput BIGINT,
16
+ completion_count BIGINT,
17
+ error_count BIGINT,
18
+ completion_rate NUMERIC(5,2),
19
+ error_rate NUMERIC(5,2),
20
+
21
+ -- Duration metrics (in seconds)
22
+ avg_task_duration NUMERIC(10,3),
23
+ avg_step_duration NUMERIC(10,3),
24
+ step_throughput BIGINT,
25
+
26
+ -- Metadata
27
+ analysis_period_start TIMESTAMPTZ,
28
+ calculated_at TIMESTAMPTZ
29
+ ) LANGUAGE plpgsql STABLE AS $$
30
+ DECLARE
31
+ analysis_start TIMESTAMPTZ;
32
+ BEGIN
33
+ -- Set analysis start time (default to 1 hour ago if not provided)
34
+ analysis_start := COALESCE(since_timestamp, NOW() - INTERVAL '1 hour');
35
+
36
+ RETURN QUERY
37
+ WITH active_tasks AS (
38
+ SELECT COUNT(DISTINCT t.task_id) as active_count
39
+ FROM tasker_tasks t
40
+ INNER JOIN tasker_workflow_steps ws ON ws.task_id = t.task_id
41
+ INNER JOIN tasker_workflow_step_transitions wst ON wst.workflow_step_id = ws.workflow_step_id
42
+ WHERE wst.most_recent = true
43
+ AND wst.to_state NOT IN ('complete', 'error', 'skipped', 'resolved_manually')
44
+ ),
45
+ namespace_summary AS (
46
+ SELECT COUNT(DISTINCT tn.name) as namespace_count
47
+ FROM tasker_task_namespaces tn
48
+ INNER JOIN tasker_named_tasks nt ON nt.task_namespace_id = tn.task_namespace_id
49
+ INNER JOIN tasker_tasks t ON t.named_task_id = nt.named_task_id
50
+ ),
51
+ task_type_summary AS (
52
+ SELECT COUNT(DISTINCT nt.name) as task_type_count
53
+ FROM tasker_named_tasks nt
54
+ INNER JOIN tasker_tasks t ON t.named_task_id = nt.named_task_id
55
+ ),
56
+ recent_task_health AS (
57
+ SELECT
58
+ COUNT(DISTINCT t.task_id) as total_recent_tasks,
59
+ COUNT(DISTINCT t.task_id) FILTER (
60
+ WHERE wst.to_state = 'complete' AND wst.most_recent = true
61
+ ) as completed_tasks,
62
+ COUNT(DISTINCT t.task_id) FILTER (
63
+ WHERE wst.to_state = 'error' AND wst.most_recent = true
64
+ ) as error_tasks
65
+ FROM tasker_tasks t
66
+ INNER JOIN tasker_workflow_steps ws ON ws.task_id = t.task_id
67
+ INNER JOIN tasker_workflow_step_transitions wst ON wst.workflow_step_id = ws.workflow_step_id
68
+ WHERE t.created_at > NOW() - INTERVAL '1 hour'
69
+ ),
70
+ period_metrics AS (
71
+ SELECT
72
+ COUNT(DISTINCT t.task_id) as throughput,
73
+ COUNT(DISTINCT t.task_id) FILTER (
74
+ WHERE completed_wst.to_state = 'complete' AND completed_wst.most_recent = true
75
+ ) as completions,
76
+ COUNT(DISTINCT t.task_id) FILTER (
77
+ WHERE error_wst.to_state = 'error' AND error_wst.most_recent = true
78
+ ) as errors,
79
+ COUNT(DISTINCT ws.workflow_step_id) as step_count,
80
+ AVG(
81
+ CASE
82
+ WHEN completed_wst.to_state = 'complete' AND completed_wst.most_recent = true
83
+ THEN EXTRACT(EPOCH FROM (completed_wst.created_at - t.created_at))
84
+ ELSE NULL
85
+ END
86
+ ) as avg_task_seconds,
87
+ AVG(
88
+ CASE
89
+ WHEN step_completed.to_state = 'complete' AND step_completed.most_recent = true
90
+ THEN EXTRACT(EPOCH FROM (step_completed.created_at - ws.created_at))
91
+ ELSE NULL
92
+ END
93
+ ) as avg_step_seconds
94
+ FROM tasker_tasks t
95
+ LEFT JOIN tasker_workflow_steps ws ON ws.task_id = t.task_id
96
+ LEFT JOIN tasker_workflow_step_transitions completed_wst ON completed_wst.workflow_step_id = ws.workflow_step_id
97
+ AND completed_wst.to_state = 'complete' AND completed_wst.most_recent = true
98
+ LEFT JOIN tasker_workflow_step_transitions error_wst ON error_wst.workflow_step_id = ws.workflow_step_id
99
+ AND error_wst.to_state = 'error' AND error_wst.most_recent = true
100
+ LEFT JOIN tasker_workflow_step_transitions step_completed ON step_completed.workflow_step_id = ws.workflow_step_id
101
+ AND step_completed.to_state = 'complete' AND step_completed.most_recent = true
102
+ WHERE t.created_at > analysis_start
103
+ )
104
+ SELECT
105
+ at.active_count,
106
+ ns.namespace_count,
107
+ tts.task_type_count,
108
+ CASE
109
+ WHEN (rth.completed_tasks + rth.error_tasks) > 0
110
+ THEN ROUND((rth.completed_tasks::NUMERIC / (rth.completed_tasks + rth.error_tasks)), 3)
111
+ ELSE 1.0
112
+ END as health_score,
113
+ pm.throughput,
114
+ pm.completions,
115
+ pm.errors,
116
+ CASE
117
+ WHEN pm.throughput > 0
118
+ THEN ROUND((pm.completions::NUMERIC / pm.throughput * 100), 2)
119
+ ELSE 0.0
120
+ END as completion_rate_pct,
121
+ CASE
122
+ WHEN pm.throughput > 0
123
+ THEN ROUND((pm.errors::NUMERIC / pm.throughput * 100), 2)
124
+ ELSE 0.0
125
+ END as error_rate_pct,
126
+ ROUND(COALESCE(pm.avg_task_seconds, 0), 3),
127
+ ROUND(COALESCE(pm.avg_step_seconds, 0), 3),
128
+ pm.step_count,
129
+ analysis_start,
130
+ NOW()
131
+ FROM active_tasks at
132
+ CROSS JOIN namespace_summary ns
133
+ CROSS JOIN task_type_summary tts
134
+ CROSS JOIN recent_task_health rth
135
+ CROSS JOIN period_metrics pm;
136
+ END;
137
+ $$;
@@ -0,0 +1,82 @@
1
+ -- Slowest Steps Analysis Function
2
+ -- Returns the slowest workflow steps within a specified time period
3
+ -- Input: since_timestamp, limit_count, and optional filters
4
+ -- Output: Ranked list of slowest steps with duration and context
5
+
6
+ CREATE OR REPLACE FUNCTION get_slowest_steps_v01(
7
+ since_timestamp TIMESTAMPTZ DEFAULT NULL,
8
+ limit_count INTEGER DEFAULT 10,
9
+ namespace_filter TEXT DEFAULT NULL,
10
+ task_name_filter TEXT DEFAULT NULL,
11
+ version_filter TEXT DEFAULT NULL
12
+ )
13
+ RETURNS TABLE (
14
+ workflow_step_id BIGINT,
15
+ task_id BIGINT,
16
+ step_name VARCHAR(128),
17
+ task_name VARCHAR(64),
18
+ namespace_name VARCHAR(64),
19
+ version VARCHAR(64),
20
+ duration_seconds NUMERIC(10,3),
21
+ attempts INTEGER,
22
+ created_at TIMESTAMPTZ,
23
+ completed_at TIMESTAMPTZ,
24
+ retryable BOOLEAN,
25
+ step_status VARCHAR(64)
26
+ ) LANGUAGE plpgsql STABLE AS $$
27
+ DECLARE
28
+ analysis_start TIMESTAMPTZ;
29
+ BEGIN
30
+ -- Set analysis start time (default to 24 hours ago if not provided)
31
+ analysis_start := COALESCE(since_timestamp, NOW() - INTERVAL '24 hours');
32
+
33
+ RETURN QUERY
34
+ WITH step_durations AS (
35
+ SELECT
36
+ ws.workflow_step_id,
37
+ ws.task_id,
38
+ ns.name as step_name,
39
+ nt.name as task_name,
40
+ tn.name as namespace_name,
41
+ nt.version,
42
+ ws.created_at,
43
+ ws.attempts,
44
+ ws.retryable,
45
+ -- Find the completion time
46
+ wst.created_at as completion_time,
47
+ wst.to_state as final_state,
48
+ -- Calculate duration from step creation to completion
49
+ EXTRACT(EPOCH FROM (wst.created_at - ws.created_at)) as duration_seconds
50
+ FROM tasker_workflow_steps ws
51
+ INNER JOIN tasker_named_steps ns ON ns.named_step_id = ws.named_step_id
52
+ INNER JOIN tasker_tasks t ON t.task_id = ws.task_id
53
+ INNER JOIN tasker_named_tasks nt ON nt.named_task_id = t.named_task_id
54
+ INNER JOIN tasker_task_namespaces tn ON tn.task_namespace_id = nt.task_namespace_id
55
+ INNER JOIN tasker_workflow_step_transitions wst ON wst.workflow_step_id = ws.workflow_step_id
56
+ WHERE ws.created_at > analysis_start
57
+ AND wst.most_recent = true
58
+ AND wst.to_state = 'complete' -- Only include completed steps for accurate duration
59
+ AND (namespace_filter IS NULL OR tn.name = namespace_filter)
60
+ AND (task_name_filter IS NULL OR nt.name = task_name_filter)
61
+ AND (version_filter IS NULL OR nt.version = version_filter)
62
+ )
63
+ SELECT
64
+ sd.workflow_step_id,
65
+ sd.task_id,
66
+ sd.step_name,
67
+ sd.task_name,
68
+ sd.namespace_name,
69
+ sd.version,
70
+ ROUND(sd.duration_seconds, 3),
71
+ sd.attempts,
72
+ sd.created_at,
73
+ sd.completion_time,
74
+ sd.retryable,
75
+ sd.final_state
76
+ FROM step_durations sd
77
+ WHERE sd.duration_seconds IS NOT NULL
78
+ AND sd.duration_seconds > 0 -- Filter out negative durations (data integrity check)
79
+ ORDER BY sd.duration_seconds DESC
80
+ LIMIT limit_count;
81
+ END;
82
+ $$;