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
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Tasker
6
+ module Events
7
+ # DefinitionLoader handles loading event metadata and state machine mappings from YAML files
8
+ #
9
+ # This class provides a clean loader for event metadata (descriptions, schemas, etc.)
10
+ # and state machine transition mappings. The actual event constants are defined
11
+ # in constants.rb as the single source of truth.
12
+ #
13
+ # Features:
14
+ # - Event metadata loading for runtime introspection
15
+ # - State machine transition mappings for declarative configuration
16
+ # - Support for custom application events and mappings
17
+ # - Hot reloading in development environments
18
+ class DefinitionLoader
19
+ include Singleton
20
+
21
+ class << self
22
+ # Load all event metadata for introspection
23
+ #
24
+ # @return [Hash] Event metadata keyed by constant reference
25
+ def load_event_metadata
26
+ metadata = {}
27
+
28
+ # Load system event metadata first
29
+ system_metadata = load_system_event_metadata
30
+ metadata.merge!(system_metadata)
31
+
32
+ # Load custom event metadata from applications
33
+ custom_metadata = load_custom_event_metadata
34
+ metadata.merge!(custom_metadata)
35
+
36
+ metadata
37
+ end
38
+
39
+ # Load state machine mappings from YAML
40
+ #
41
+ # @return [Hash] State machine mappings with task and step transitions
42
+ def load_state_machine_mappings
43
+ yaml_file = File.join(tasker_config_path, 'system_events.yml')
44
+
45
+ if File.exist?(yaml_file)
46
+ yaml_data = YAML.load_file(yaml_file)
47
+ yaml_data['state_machine_mappings'] || {}
48
+ else
49
+ Rails.logger.warn('Tasker: system_events.yml not found')
50
+ {}
51
+ end
52
+ end
53
+
54
+ # Get event metadata for a specific constant
55
+ #
56
+ # @param constant_ref [String] The constant reference or actual constant value
57
+ # @return [Hash, nil] Event metadata or nil if not found
58
+ def find_event_metadata(constant_ref)
59
+ metadata = load_event_metadata
60
+
61
+ # Try direct lookup first
62
+ return metadata[constant_ref] if metadata[constant_ref]
63
+
64
+ # Try reverse lookup by constant value
65
+ metadata.find { |_key, data| data['constant_ref'] == constant_ref }&.last
66
+ end
67
+
68
+ # Get all events grouped by category for introspection
69
+ #
70
+ # @return [Hash] Events grouped by category (task, step, workflow, etc.)
71
+ def events_by_category
72
+ metadata = load_event_metadata
73
+ grouped = Hash.new { |h, k| h[k] = {} }
74
+
75
+ metadata.each do |event_key, event_data|
76
+ category = extract_category_from_key(event_key)
77
+ grouped[category][event_key] = event_data
78
+ end
79
+
80
+ grouped
81
+ end
82
+
83
+ private
84
+
85
+ # Load system event metadata from Tasker gem
86
+ #
87
+ # @return [Hash] System event metadata
88
+ def load_system_event_metadata
89
+ system_file = File.join(tasker_config_path, 'system_events.yml')
90
+
91
+ if File.exist?(system_file)
92
+ load_metadata_from_file(system_file)
93
+ else
94
+ Rails.logger.warn("Tasker: System events file not found at #{system_file}")
95
+ {}
96
+ end
97
+ end
98
+
99
+ # Load custom event metadata from application configuration
100
+ #
101
+ # @return [Hash] Custom event metadata
102
+ def load_custom_event_metadata
103
+ metadata = {}
104
+
105
+ # Load custom events from configured directories if they exist
106
+ Tasker.configuration.engine.custom_events_directories.each do |directory_path|
107
+ absolute_path = File.expand_path(directory_path, Rails.root)
108
+
109
+ if File.directory?(absolute_path)
110
+ load_metadata_from_directory(absolute_path, metadata)
111
+ elsif File.exist?(absolute_path) && absolute_path.end_with?('.yml', '.yaml')
112
+ file_metadata = load_metadata_from_file(absolute_path)
113
+ metadata.merge!(file_metadata)
114
+ end
115
+ end
116
+
117
+ metadata
118
+ end
119
+
120
+ # Load metadata from a single YAML file
121
+ #
122
+ # @param file_path [String] Path to the YAML file
123
+ # @return [Hash] Event metadata from the file
124
+ def load_metadata_from_file(file_path)
125
+ Rails.logger.debug { "Tasker: Loading event metadata from #{file_path}" }
126
+
127
+ begin
128
+ yaml_data = YAML.load_file(file_path)
129
+ return {} if yaml_data.blank?
130
+
131
+ # Extract event metadata section
132
+ event_metadata = yaml_data['event_metadata'] || {}
133
+ transform_metadata_structure(event_metadata, file_path)
134
+ rescue StandardError => e
135
+ Rails.logger.error("Tasker: Failed to load event metadata from #{file_path}: #{e.message}")
136
+ {}
137
+ end
138
+ end
139
+
140
+ # Transform nested YAML metadata structure to flat lookup
141
+ #
142
+ # @param metadata [Hash] Nested metadata structure from YAML
143
+ # @param source_file [String] Source file for metadata attribution
144
+ # @return [Hash] Flattened metadata hash
145
+ def transform_metadata_structure(metadata, source_file)
146
+ flattened = {}
147
+
148
+ metadata.each do |category, events|
149
+ events.each do |event_name, event_data|
150
+ # Create a composite key for easy lookup
151
+ lookup_key = "#{category}.#{event_name}"
152
+
153
+ # Enhance event data with source information
154
+ enhanced_data = event_data.merge(
155
+ 'category' => category.to_s,
156
+ 'event_name' => event_name.to_s,
157
+ 'source_file' => source_file,
158
+ 'lookup_key' => lookup_key
159
+ )
160
+
161
+ flattened[lookup_key] = enhanced_data
162
+ end
163
+ end
164
+
165
+ flattened
166
+ end
167
+
168
+ # Extract category from composite event key
169
+ #
170
+ # @param event_key [String] The composite event key (e.g., "task.completed")
171
+ # @return [String] The category portion
172
+ def extract_category_from_key(event_key)
173
+ event_key.split('.').first || 'unknown'
174
+ end
175
+
176
+ # Load metadata from a directory
177
+ #
178
+ # @param directory_path [String] Absolute path to the directory
179
+ # @param metadata [Hash] Hash to merge metadata into
180
+ # @return [void]
181
+ def load_metadata_from_directory(directory_path, metadata)
182
+ Rails.logger.debug { "Tasker: Scanning directory for metadata files: #{directory_path}" }
183
+
184
+ Dir.glob(File.join(directory_path, '*.{yml,yaml}')).each do |metadata_file|
185
+ file_metadata = load_metadata_from_file(metadata_file)
186
+ metadata.merge!(file_metadata)
187
+ end
188
+ end
189
+
190
+ # Get path to Tasker gem configuration
191
+ #
192
+ # @return [String] Path to Tasker config directory
193
+ def tasker_config_path
194
+ @tasker_config_path ||= File.join(Tasker::Engine.root, 'config', 'tasker')
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,461 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ module Events
5
+ # EventPayloadBuilder creates standardized event payloads for consistent telemetry
6
+ #
7
+ # This class solves the payload standardization issues identified during factory migration:
8
+ # - Missing :execution_duration keys in step completion events
9
+ # - Missing :error_message keys in step failure events
10
+ # - Missing :attempt_number keys for retry tracking
11
+ # - Inconsistent payload structure across different event publishers
12
+ #
13
+ # Usage:
14
+ # payload = EventPayloadBuilder.build_step_payload(step, task, event_type: :completed)
15
+ # Tasker::Events::Publisher.instance.publish('step.completed', payload)
16
+ class EventPayloadBuilder
17
+ class << self
18
+ # Build standardized payload for step events
19
+ #
20
+ # @param step [WorkflowStep] The step object
21
+ # @param task [Task] The associated task
22
+ # @param event_type [Symbol] The type of event (:started, :completed, :failed, :retry, etc.)
23
+ # @param additional_context [Hash] Additional context to merge in
24
+ # @return [Hash] Standardized event payload
25
+ def build_step_payload(step, task = nil, event_type: :completed, additional_context: {})
26
+ StepPayloadBuilder.build(step, task, event_type, additional_context)
27
+ end
28
+
29
+ # Build standardized payload for task events
30
+ #
31
+ # @param task [Task] The task object
32
+ # @param event_type [Symbol] The type of event (:started, :completed, :failed, etc.)
33
+ # @param additional_context [Hash] Additional context to merge in
34
+ # @return [Hash] Standardized event payload
35
+ def build_task_payload(task, event_type: :completed, additional_context: {})
36
+ # Get all completion stats in a single optimized query
37
+ stats = Tasker::WorkflowStep.task_completion_stats(task)
38
+
39
+ base_payload = {
40
+ # Core identifiers
41
+ task_id: task.task_id,
42
+ task_name: get_task_name(task),
43
+
44
+ # Timing information - only set completed_at for fully completed tasks
45
+ started_at: task.created_at&.iso8601,
46
+ completed_at: stats[:all_complete] ? stats[:latest_completion_time]&.iso8601 : nil,
47
+
48
+ # Task metadata
49
+ task_type: task.class.name,
50
+ event_type: event_type.to_s,
51
+ timestamp: Time.current.iso8601
52
+ }
53
+
54
+ # Add duration and step statistics to all task events
55
+ base_payload.merge!(build_task_timing_and_statistics(task, stats))
56
+
57
+ # Add event-specific fields
58
+ case event_type
59
+ when :completed
60
+ base_payload.merge!(build_task_completion_specific_payload(task))
61
+ when :failed
62
+ base_payload.merge!(build_task_failure_payload(task, additional_context))
63
+ when :started
64
+ base_payload.merge!(build_task_start_payload(task))
65
+ end
66
+
67
+ # Merge additional context, allowing overrides
68
+ base_payload.merge!(additional_context)
69
+
70
+ base_payload
71
+ end
72
+
73
+ # Build standardized payload for workflow orchestration events
74
+ #
75
+ # @param event_type [Symbol] The orchestration event type
76
+ # @param context [Hash] The orchestration context
77
+ # @return [Hash] Standardized orchestration payload
78
+ def build_orchestration_payload(event_type:, context: {})
79
+ {
80
+ # Event metadata
81
+ event_type: event_type.to_s,
82
+ orchestration_event: true,
83
+ timestamp: Time.current.iso8601,
84
+
85
+ # Merge provided context
86
+ **context
87
+ }
88
+ end
89
+
90
+ private
91
+
92
+ # Get task name safely handling the named_task association
93
+ #
94
+ # @param task [Task] The task object
95
+ # @return [String] The task name
96
+ def get_task_name(task)
97
+ if task.respond_to?(:named_task) && task.named_task
98
+ task.named_task.name
99
+ elsif task.respond_to?(:name)
100
+ task.name
101
+ else
102
+ 'unknown_task'
103
+ end
104
+ end
105
+
106
+ # Build completion-specific payload fields
107
+ #
108
+ # @param step [WorkflowStep] The completed step
109
+ # @return [Hash] Completion payload fields
110
+ def build_completion_payload(step)
111
+ payload = {}
112
+
113
+ # Calculate execution duration using last_attempted_at and processed_at
114
+ payload[:execution_duration] = if step.last_attempted_at && step.processed_at
115
+ (step.processed_at - step.last_attempted_at).round(3)
116
+ else
117
+ 0.0
118
+ end
119
+
120
+ # Include step results if available
121
+ payload[:step_results] = step.results if step.results.present?
122
+
123
+ payload
124
+ end
125
+
126
+ # Build failure-specific payload fields
127
+ #
128
+ # @param step [WorkflowStep] The failed step
129
+ # @param additional_context [Hash] Additional context (may include error details)
130
+ # @return [Hash] Failure payload fields
131
+ def build_failure_payload(step, additional_context = {})
132
+ payload = {}
133
+
134
+ # Extract error information using the refactored service
135
+ error_info = ErrorInfoExtractor.extract(step, additional_context)
136
+ payload.merge!(error_info)
137
+
138
+ # Include step results
139
+ payload[:step_results] = step.results if step.results.present?
140
+
141
+ payload
142
+ end
143
+
144
+ # Build start-specific payload fields
145
+ #
146
+ # @param step [WorkflowStep] The starting step
147
+ # @return [Hash] Start payload fields
148
+ def build_start_payload(step)
149
+ {
150
+ step_inputs: step.inputs,
151
+ step_dependencies: step.respond_to?(:parents) ? step.parents.map(&:name) : []
152
+ }
153
+ end
154
+
155
+ # Build retry-specific payload fields
156
+ #
157
+ # @param step [WorkflowStep] The step being retried
158
+ # @return [Hash] Retry payload fields
159
+ def build_retry_payload(step)
160
+ {
161
+ previous_attempts: step.attempts - 1,
162
+ retry_reason: 'Step execution failed',
163
+ backoff_strategy: 'exponential' # Could be made configurable
164
+ }
165
+ end
166
+
167
+ # Build task timing and statistics (shared across all task event types)
168
+ #
169
+ # @param task [Task] The task
170
+ # @param stats [Hash] Pre-calculated task completion statistics from WorkflowStep.task_completion_stats
171
+ # @return [Hash] Timing and statistics payload fields
172
+ def build_task_timing_and_statistics(task, stats)
173
+ payload = {}
174
+
175
+ # Distinguish between total duration (all steps complete) and current duration (in progress)
176
+ if stats[:all_complete] && task.created_at && stats[:latest_completion_time]
177
+ # True total execution duration - complete workflow
178
+ payload[:total_execution_duration] = (stats[:latest_completion_time] - task.created_at).round(3)
179
+ payload[:current_execution_duration] = nil # Not applicable for completed tasks
180
+ elsif task.created_at
181
+ # Current execution duration - task still in progress
182
+ payload[:total_execution_duration] = nil # Not available until completion
183
+ payload[:current_execution_duration] = (Time.current - task.created_at).round(3)
184
+ else
185
+ # No timing information available
186
+ payload[:total_execution_duration] = nil
187
+ payload[:current_execution_duration] = nil
188
+ end
189
+
190
+ # Use pre-calculated step statistics (no additional queries needed)
191
+ payload[:total_steps] = stats[:total_steps]
192
+ payload[:completed_steps] = stats[:completed_steps]
193
+ payload[:failed_steps] = stats[:failed_steps]
194
+ payload[:pending_steps] = stats[:pending_steps]
195
+
196
+ payload
197
+ end
198
+
199
+ # Build task completion-specific payload fields (only for completed events)
200
+ #
201
+ # @param task [Task] The completed task
202
+ # @return [Hash] Completion-specific payload fields
203
+ def build_task_completion_specific_payload(_task)
204
+ {
205
+ # Could add completion-specific metadata here if needed
206
+ # For now, all the important data is in the timing/statistics method
207
+ }
208
+ end
209
+
210
+ # Build task failure payload fields
211
+ #
212
+ # @param task [Task] The failed task
213
+ # @param additional_context [Hash] Additional context
214
+ # @return [Hash] Task failure payload fields
215
+ def build_task_failure_payload(_task, additional_context = {})
216
+ payload = {}
217
+
218
+ # Extract error information
219
+ if additional_context[:error_steps].present?
220
+ payload[:error_steps] = additional_context[:error_steps]
221
+ payload[:error_step_results] = additional_context[:error_step_results]
222
+ end
223
+
224
+ # Default error message if not provided
225
+ payload[:error_message] = additional_context[:error_message] ||
226
+ additional_context[:error] ||
227
+ 'Task execution failed'
228
+
229
+ payload
230
+ end
231
+
232
+ # Build task start payload fields
233
+ #
234
+ # @param task [Task] The starting task
235
+ # @return [Hash] Task start payload fields
236
+ def build_task_start_payload(task)
237
+ {
238
+ task_context: task.context,
239
+ total_steps: task.workflow_steps.count
240
+ }
241
+ end
242
+
243
+ # Check if a step is complete (reused from various helpers)
244
+ #
245
+ # @param step [WorkflowStep] The step to check
246
+ # @return [Boolean] True if step is complete
247
+ def step_complete?(step)
248
+ [
249
+ Tasker::Constants::WorkflowStepStatuses::COMPLETE,
250
+ Tasker::Constants::WorkflowStepStatuses::RESOLVED_MANUALLY
251
+ ].include?(step.status)
252
+ end
253
+
254
+ # Check if a step is in error state
255
+ #
256
+ # @param step [WorkflowStep] The step to check
257
+ # @return [Boolean] True if step is in error
258
+ def step_in_error?(step)
259
+ step.status == Tasker::Constants::WorkflowStepStatuses::ERROR
260
+ end
261
+
262
+ # Service class to build step payloads for different event types
263
+ # Reduces complexity by organizing payload building logic
264
+ class StepPayloadBuilder
265
+ class << self
266
+ # Build complete step payload for specified event type
267
+ #
268
+ # @param step [WorkflowStep] The workflow step
269
+ # @param task [Task] The task (optional, will be retrieved from step if nil)
270
+ # @param event_type [Symbol] The event type
271
+ # @param additional_context [Hash] Additional context to merge
272
+ # @return [Hash] Complete event payload
273
+ def build(step, task, event_type, additional_context)
274
+ task ||= step.task
275
+
276
+ base_payload = build_base_payload(step, task, event_type)
277
+ event_specific_payload = build_event_specific_payload(step, event_type, additional_context)
278
+
279
+ # Merge additional context, allowing overrides
280
+ base_payload.merge(event_specific_payload).merge(additional_context)
281
+ end
282
+
283
+ private
284
+
285
+ # Build base payload common to all step events
286
+ #
287
+ # @param step [WorkflowStep] The workflow step
288
+ # @param task [Task] The task
289
+ # @param event_type [Symbol] The event type
290
+ # @return [Hash] Base payload
291
+ def build_base_payload(step, task, event_type)
292
+ {
293
+ # Core identifiers (always present)
294
+ task_id: task.task_id,
295
+ step_id: step.workflow_step_id,
296
+ step_name: step.name,
297
+
298
+ # Timing information - steps use last_attempted_at and processed_at
299
+ started_at: step.last_attempted_at&.iso8601,
300
+ completed_at: step.processed_at&.iso8601,
301
+
302
+ # Retry and attempt tracking
303
+ attempt_number: step.attempts || 1,
304
+ retry_limit: step.retry_limit,
305
+
306
+ # Event metadata
307
+ event_type: event_type.to_s,
308
+ timestamp: Time.current.iso8601
309
+ }
310
+ end
311
+
312
+ # Build event-specific payload fields
313
+ #
314
+ # @param step [WorkflowStep] The workflow step
315
+ # @param event_type [Symbol] The event type
316
+ # @param additional_context [Hash] Additional context
317
+ # @return [Hash] Event-specific payload
318
+ def build_event_specific_payload(step, event_type, additional_context)
319
+ case event_type
320
+ when :completed
321
+ build_completion_payload(step)
322
+ when :failed
323
+ build_failure_payload(step, additional_context)
324
+ when :started
325
+ build_start_payload(step)
326
+ when :retry
327
+ build_retry_payload(step)
328
+ else
329
+ {}
330
+ end
331
+ end
332
+
333
+ # Build completion-specific payload fields
334
+ #
335
+ # @param step [WorkflowStep] The completed step
336
+ # @return [Hash] Completion payload fields
337
+ def build_completion_payload(step)
338
+ payload = {}
339
+
340
+ # Calculate execution duration using last_attempted_at and processed_at
341
+ payload[:execution_duration] = if step.last_attempted_at && step.processed_at
342
+ (step.processed_at - step.last_attempted_at).round(3)
343
+ else
344
+ 0.0
345
+ end
346
+
347
+ # Include step results if available
348
+ payload[:step_results] = step.results if step.results.present?
349
+
350
+ payload
351
+ end
352
+
353
+ # Build failure-specific payload fields
354
+ #
355
+ # @param step [WorkflowStep] The failed step
356
+ # @param additional_context [Hash] Additional context (may include error details)
357
+ # @return [Hash] Failure payload fields
358
+ def build_failure_payload(step, additional_context = {})
359
+ payload = {}
360
+
361
+ # Extract error information using the refactored service
362
+ error_info = ErrorInfoExtractor.extract(step, additional_context)
363
+ payload.merge!(error_info)
364
+
365
+ # Include step results
366
+ payload[:step_results] = step.results if step.results.present?
367
+
368
+ payload
369
+ end
370
+
371
+ # Build start-specific payload fields
372
+ #
373
+ # @param step [WorkflowStep] The starting step
374
+ # @return [Hash] Start payload fields
375
+ def build_start_payload(step)
376
+ {
377
+ step_inputs: step.inputs,
378
+ step_dependencies: step.respond_to?(:parents) ? step.parents.map(&:name) : []
379
+ }
380
+ end
381
+
382
+ # Build retry-specific payload fields
383
+ #
384
+ # @param step [WorkflowStep] The step being retried
385
+ # @return [Hash] Retry payload fields
386
+ def build_retry_payload(step)
387
+ {
388
+ previous_attempts: step.attempts - 1,
389
+ retry_reason: 'Step execution failed',
390
+ backoff_strategy: 'exponential' # Could be made configurable
391
+ }
392
+ end
393
+ end
394
+ end
395
+ end
396
+
397
+ # Service class to extract error information from step and context
398
+ # Reduces complexity by organizing error extraction logic
399
+ class ErrorInfoExtractor
400
+ class << self
401
+ # Extract error information from step and context
402
+ #
403
+ # @param step [WorkflowStep] The step with error
404
+ # @param additional_context [Hash] Additional context
405
+ # @return [Hash] Error information payload
406
+ def extract(step, additional_context = {})
407
+ error_payload = {}
408
+
409
+ error_payload[:error_message] = extract_error_message(step, additional_context)
410
+ error_payload[:exception_class] = extract_exception_class(additional_context)
411
+
412
+ backtrace = extract_backtrace(step, additional_context)
413
+ error_payload[:backtrace] = backtrace if backtrace
414
+
415
+ error_payload
416
+ end
417
+
418
+ private
419
+
420
+ # Extract the primary error message from various sources
421
+ #
422
+ # @param step [WorkflowStep] The step with error
423
+ # @param additional_context [Hash] Additional context
424
+ # @return [String] The error message
425
+ def extract_error_message(step, additional_context)
426
+ additional_context[:error_message] ||
427
+ additional_context[:error] ||
428
+ step.results&.dig('error') ||
429
+ step.results&.dig(:error) ||
430
+ 'Unknown error'
431
+ end
432
+
433
+ # Extract the exception class name
434
+ #
435
+ # @param additional_context [Hash] Additional context
436
+ # @return [String] The exception class name
437
+ def extract_exception_class(additional_context)
438
+ if additional_context[:exception_object]
439
+ additional_context[:exception_object].class.name
440
+ elsif additional_context[:exception_class]
441
+ additional_context[:exception_class]
442
+ else
443
+ 'StandardError'
444
+ end
445
+ end
446
+
447
+ # Extract backtrace information from various sources
448
+ #
449
+ # @param step [WorkflowStep] The step with error
450
+ # @param additional_context [Hash] Additional context
451
+ # @return [String, nil] The backtrace or nil if not available
452
+ def extract_backtrace(step, additional_context)
453
+ additional_context[:backtrace] ||
454
+ step.results&.dig('backtrace') ||
455
+ step.results&.dig(:backtrace)
456
+ end
457
+ end
458
+ end
459
+ end
460
+ end
461
+ end