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,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+ require 'pathname'
5
+
6
+ module Tasker
7
+ class TaskDiagram
8
+ # Colors for different step statuses
9
+ STATUS_COLORS = {
10
+ Tasker::Constants::WorkflowStepStatuses::PENDING => 'lightblue',
11
+ Tasker::Constants::WorkflowStepStatuses::IN_PROGRESS => 'lightgreen',
12
+ Tasker::Constants::WorkflowStepStatuses::COMPLETE => 'green',
13
+ Tasker::Constants::WorkflowStepStatuses::ERROR => 'red',
14
+ Tasker::Constants::WorkflowStepStatuses::CANCELLED => 'gray'
15
+ }.freeze
16
+
17
+ # Create a new task diagram
18
+ #
19
+ # @param task [Tasker::Task] The task to create a diagram for
20
+ # @param base_url [String, nil] Optional base URL for REST endpoints
21
+ # @return [TaskDiagram] A new task diagram instance
22
+ def initialize(task, base_url = nil)
23
+ @task = task
24
+ @base_url = base_url
25
+ end
26
+
27
+ # Generate a Mermaid diagram string for the task
28
+ #
29
+ # @return [String] Mermaid flowchart diagram string
30
+ delegate :to_mermaid, to: :flowchart
31
+
32
+ # Generate a complete HTML document with embedded Mermaid diagram
33
+ #
34
+ # @return [String] HTML document with Mermaid diagram
35
+ def to_html
36
+ # Generate the mermaid diagram
37
+ @diagram = flowchart.to_mermaid
38
+
39
+ # Create binding with relevant variables
40
+ task = @task # Make task available to the template
41
+ diagram = @diagram # Make diagram available to the template
42
+
43
+ # Create a binding with the variables
44
+ b = binding
45
+
46
+ # Get the template path relative to this file
47
+ template_path = views_path.join('_diagram.html.erb')
48
+
49
+ # Load and render the template with ERB
50
+ begin
51
+ template = File.read(template_path)
52
+ ERB.new(template).result(b)
53
+ rescue Errno::ENOENT
54
+ raise TaskDiagramError, "Template file not found: #{template_path}"
55
+ rescue Errno::EACCES
56
+ raise TaskDiagramError, "Permission denied while accessing template file: #{template_path}"
57
+ end
58
+ end
59
+
60
+ def to_json(pretty: false)
61
+ flowchart.to_json(pretty: pretty)
62
+ end
63
+
64
+ private
65
+
66
+ def flowchart
67
+ return @flowchart if @flowchart
68
+
69
+ # Preload workflow steps with scenic view relationships for efficiency
70
+ workflow_steps = @task.workflow_steps.includes(:named_step, :step_dag_relationship)
71
+
72
+ # Create a new flowchart
73
+ @flowchart = Tasker::Diagram::Flowchart.new(
74
+ direction: 'TD',
75
+ title: "Task #{@task.task_id}: #{@task.name}"
76
+ )
77
+
78
+ # Add task info node
79
+ @flowchart.add_node(build_task_node)
80
+
81
+ # Build nodes for all workflow steps
82
+ workflow_steps.each do |step|
83
+ @flowchart.add_node(build_step_node(step))
84
+ end
85
+
86
+ # Build all edges efficiently using scenic view data
87
+ build_all_step_edges(workflow_steps).each do |edge|
88
+ @flowchart.add_edge(edge)
89
+ end
90
+
91
+ @flowchart
92
+ end
93
+
94
+ # Get the path to the view templates directory
95
+ #
96
+ # @return [Pathname] Path to view templates
97
+ def views_path
98
+ # Get the absolute path of the current file
99
+ current_file = Pathname.new(__FILE__)
100
+
101
+ # Navigate to the views directory relative to this file
102
+ # This file is in app/models/tasker/task_diagram.rb
103
+ # Views are in app/views/tasker/task/
104
+ current_file.dirname.parent.parent.parent.join('app', 'views', 'tasker', 'task')
105
+ end
106
+
107
+ # Build the task information node
108
+ #
109
+ # @return [Tasker::Diagram::Node] The task node
110
+ def build_task_node
111
+ Tasker::Diagram::Node.new(
112
+ id: "task_#{@task.task_id}",
113
+ label: "Task: #{@task.name}\nID: #{@task.task_id}\nStatus: #{@task.status}"
114
+ )
115
+ end
116
+
117
+ # Build a node for a workflow step
118
+ #
119
+ # @param step [Tasker::WorkflowStep] The workflow step
120
+ # @return [Tasker::Diagram::Node] The step node
121
+ def build_step_node(step)
122
+ node_id = "step_#{step.workflow_step_id}"
123
+ color = STATUS_COLORS[step.status] || 'lightgray'
124
+
125
+ # Create label with step details
126
+ label = build_step_label(step)
127
+
128
+ # Create clickable URL if base_url is provided
129
+ url = @base_url ? "#{@base_url}/tasks/#{@task.task_id}/workflow_steps/#{step.workflow_step_id}" : nil
130
+
131
+ # Create node with styling
132
+ Tasker::Diagram::Node.new(
133
+ id: node_id,
134
+ label: label.join("\n"),
135
+ shape: 'box',
136
+ style: "fill:#{color};",
137
+ url: url
138
+ )
139
+ end
140
+
141
+ # Build the label lines for a step node
142
+ #
143
+ # @param step [Tasker::WorkflowStep] The workflow step
144
+ # @return [Array<String>] Array of label lines
145
+ def build_step_label(step)
146
+ label = [
147
+ "Step: #{step.name}",
148
+ "Status: #{step.status}",
149
+ "Attempts: #{step.attempts || 0}"
150
+ ]
151
+
152
+ # Add error info if applicable
153
+ if step.status == Tasker::Constants::WorkflowStepStatuses::ERROR && step.results&.key?('error')
154
+ error_msg = step.results['error'].to_s
155
+ # Truncate long error messages
156
+ error_msg = "#{error_msg[0..27]}..." if error_msg.length > 30
157
+ label << "Error: #{error_msg}"
158
+ end
159
+
160
+ label
161
+ end
162
+
163
+ # Build an edge between two nodes
164
+ #
165
+ # @param source_id [String] The source node ID
166
+ # @param target_id [String] The target node ID
167
+ # @param label [String] The edge label
168
+ # @return [Tasker::Diagram::Edge] The edge
169
+ def build_edge(source_id, target_id, label = '')
170
+ Tasker::Diagram::Edge.new(
171
+ source_id: source_id,
172
+ target_id: target_id,
173
+ label: label
174
+ )
175
+ end
176
+
177
+ # Build all edges efficiently using scenic view data - eliminates N+1 queries
178
+ #
179
+ # @param workflow_steps [Array<Tasker::WorkflowStep>] All workflow steps for the task
180
+ # @return [Array<Tasker::Diagram::Edge>] All edges for the diagram
181
+ def build_all_step_edges(workflow_steps)
182
+ edges = []
183
+
184
+ # Add edges from task to root steps using dedicated builder
185
+ edges.concat(TaskToRootStepEdgeBuilder.build(@task, workflow_steps))
186
+
187
+ # Add edges between steps using dedicated builder
188
+ edges.concat(StepToStepEdgeBuilder.build(workflow_steps))
189
+
190
+ edges
191
+ end
192
+
193
+ # Service class to build edges from task to root steps
194
+ # Reduces complexity by organizing edge building logic
195
+ class TaskToRootStepEdgeBuilder
196
+ class << self
197
+ # Build edges from task node to root steps
198
+ #
199
+ # @param task [Tasker::Task] The task
200
+ # @param workflow_steps [Array<Tasker::WorkflowStep>] All workflow steps
201
+ # @return [Array<Tasker::Diagram::Edge>] Task to root step edges
202
+ def build(task, workflow_steps)
203
+ edges = []
204
+
205
+ workflow_steps.each do |step|
206
+ next unless step.step_dag_relationship&.is_root_step
207
+
208
+ edges << build_edge(
209
+ "task_#{task.task_id}",
210
+ "step_#{step.workflow_step_id}"
211
+ )
212
+ end
213
+
214
+ edges
215
+ end
216
+
217
+ private
218
+
219
+ # Build an edge between two nodes
220
+ #
221
+ # @param source_id [String] The source node ID
222
+ # @param target_id [String] The target node ID
223
+ # @param label [String] The edge label
224
+ # @return [Tasker::Diagram::Edge] The edge
225
+ def build_edge(source_id, target_id, label = '')
226
+ Tasker::Diagram::Edge.new(
227
+ source_id: source_id,
228
+ target_id: target_id,
229
+ label: label
230
+ )
231
+ end
232
+ end
233
+ end
234
+
235
+ # Service class to build edges between workflow steps
236
+ # Reduces complexity by organizing edge building logic
237
+ class StepToStepEdgeBuilder
238
+ class << self
239
+ # Build edges between workflow steps
240
+ #
241
+ # @param workflow_steps [Array<Tasker::WorkflowStep>] All workflow steps
242
+ # @return [Array<Tasker::Diagram::Edge>] Step to step edges
243
+ def build(workflow_steps)
244
+ edge_data = collect_edge_data(workflow_steps)
245
+ return [] if edge_data.empty?
246
+
247
+ edge_records = batch_load_edge_records(edge_data)
248
+ build_edges_from_data(edge_data, edge_records)
249
+ end
250
+
251
+ private
252
+
253
+ # Collect all edge relationships for efficient batch lookup
254
+ #
255
+ # @param workflow_steps [Array<Tasker::WorkflowStep>] All workflow steps
256
+ # @return [Array<Hash>] Edge data with from_step_id and to_step_id
257
+ def collect_edge_data(workflow_steps)
258
+ edge_data = []
259
+
260
+ workflow_steps.each do |step|
261
+ next unless step.step_dag_relationship
262
+
263
+ child_ids = step.step_dag_relationship.child_step_ids_array
264
+ child_ids.each do |child_id|
265
+ edge_data << {
266
+ from_step_id: step.workflow_step_id,
267
+ to_step_id: child_id
268
+ }
269
+ end
270
+ end
271
+
272
+ edge_data
273
+ end
274
+
275
+ # Batch load all WorkflowStepEdge records for edge labels
276
+ #
277
+ # @param edge_data [Array<Hash>] Edge data to load records for
278
+ # @return [Hash] Hash mapping edge keys to edge records
279
+ def batch_load_edge_records(edge_data)
280
+ edge_records = {}
281
+
282
+ conditions = edge_data.map do |data|
283
+ "(from_step_id = #{data[:from_step_id]} AND to_step_id = #{data[:to_step_id]})"
284
+ end
285
+
286
+ Tasker::WorkflowStepEdge.where(conditions.join(' OR ')).find_each do |edge_record|
287
+ key = "#{edge_record.from_step_id}_#{edge_record.to_step_id}"
288
+ edge_records[key] = edge_record
289
+ end
290
+
291
+ edge_records
292
+ end
293
+
294
+ # Build edges using pre-calculated data and records
295
+ #
296
+ # @param edge_data [Array<Hash>] Edge data with IDs
297
+ # @param edge_records [Hash] Loaded edge records for labels
298
+ # @return [Array<Tasker::Diagram::Edge>] Built edges
299
+ def build_edges_from_data(edge_data, edge_records)
300
+ edges = []
301
+
302
+ edge_data.each do |data|
303
+ source_id = "step_#{data[:from_step_id]}"
304
+ target_id = "step_#{data[:to_step_id]}"
305
+
306
+ # Find edge label from batch-loaded records
307
+ key = "#{data[:from_step_id]}_#{data[:to_step_id]}"
308
+ edge_label = edge_records[key]&.name || ''
309
+
310
+ edges << build_edge(source_id, target_id, edge_label)
311
+ end
312
+
313
+ edges
314
+ end
315
+
316
+ # Build an edge between two nodes
317
+ #
318
+ # @param source_id [String] The source node ID
319
+ # @param target_id [String] The target node ID
320
+ # @param label [String] The edge label
321
+ # @return [Tasker::Diagram::Edge] The edge
322
+ def build_edge(source_id, target_id, label = '')
323
+ Tasker::Diagram::Edge.new(
324
+ source_id: source_id,
325
+ target_id: target_id,
326
+ label: label
327
+ )
328
+ end
329
+ end
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ # TaskExecutionContext now uses SQL functions for high-performance queries
5
+ # This class explicitly delegates to the function-based implementation for better maintainability
6
+ class TaskExecutionContext
7
+ # Explicit delegation of class methods to function-based implementation
8
+ def self.find(task_id)
9
+ Tasker::Functions::FunctionBasedTaskExecutionContext.find(task_id)
10
+ end
11
+
12
+ def self.for_tasks(task_ids)
13
+ Tasker::Functions::FunctionBasedTaskExecutionContext.for_tasks(task_ids)
14
+ end
15
+
16
+ # For backward compatibility, maintain the active method but point to function-based implementation
17
+ def self.active
18
+ Tasker::Functions::FunctionBasedTaskExecutionContext
19
+ end
20
+
21
+ def initialize(task_id)
22
+ @task_id = task_id
23
+ end
24
+
25
+ def workflow_summary
26
+ @workflow_summary ||= Tasker::Functions::FunctionBasedTaskExecutionContext.find(@task_id).workflow_summary
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: tasker_task_namespaces
7
+ #
8
+ # name :string(64) not null
9
+ # description :string(255)
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ # task_namespace_id :integer not null, primary key
13
+ #
14
+ # Indexes
15
+ #
16
+ # task_namespaces_name_index (name)
17
+ # task_namespaces_name_unique (name) UNIQUE
18
+ #
19
+ module Tasker
20
+ class TaskNamespace < ApplicationRecord
21
+ self.primary_key = :task_namespace_id
22
+
23
+ has_many :named_tasks, dependent: :nullify
24
+
25
+ validates :name, presence: true, uniqueness: true, length: { maximum: 64 }
26
+ validates :description, length: { maximum: 255 }
27
+
28
+ # Find or create default namespace - always works even if not seeded
29
+ def self.default
30
+ find_or_create_by!(name: 'default')
31
+ end
32
+
33
+ # Scope for non-default namespaces
34
+ scope :custom, -> { where.not(name: 'default') }
35
+
36
+ # Check if this is the default namespace
37
+ def default?
38
+ name == 'default'
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ # TaskTransition represents state transitions for Task entities using Statesman
5
+ #
6
+ # This model stores the audit trail of all task state changes, providing
7
+ # a complete history of task lifecycle events with metadata and timestamps.
8
+ class TaskTransition < ApplicationRecord
9
+ # NOTE: We don't include Statesman::Adapters::ActiveRecordTransition
10
+ # because we're using PostgreSQL JSONB column for metadata
11
+
12
+ # Associations
13
+ belongs_to :task, inverse_of: :task_transitions
14
+
15
+ # Validations
16
+ validates :to_state, inclusion: {
17
+ in: %w[pending in_progress complete error cancelled resolved_manually],
18
+ message: 'is not a valid task state'
19
+ }
20
+
21
+ # Validate that the task exists before creating transition
22
+ validate :task_must_exist
23
+
24
+ validates :sort_key, presence: true, uniqueness: { scope: :task_id }
25
+ # Custom validation for metadata that allows empty hash but not nil
26
+ validate :metadata_must_be_hash
27
+
28
+ # Ensure metadata is always a hash
29
+ after_initialize :ensure_metadata_hash
30
+ # Ensure metadata defaults to empty hash if not provided
31
+ before_validation :ensure_metadata_presence
32
+
33
+ # Scopes
34
+ scope :recent, -> { order(sort_key: :desc) }
35
+ scope :to_state, ->(state) { where(to_state: state) }
36
+ scope :with_metadata_key, ->(key) { where('metadata ? :key', key: key.to_s) }
37
+
38
+ # Class methods for querying transitions
39
+ class << self
40
+ # Find the most recent transition to a specific state
41
+ #
42
+ # @param state [String, Symbol] The state to find the most recent transition to
43
+ # @return [TaskTransition, nil] The most recent transition to the given state
44
+ def most_recent_to_state(state)
45
+ to_state(state.to_s).order(sort_key: :desc).first
46
+ end
47
+
48
+ # Find all transitions that occurred within a time range
49
+ #
50
+ # @param start_time [Time] The start of the time range
51
+ # @param end_time [Time] The end of the time range
52
+ # @return [ActiveRecord::Relation] Transitions within the time range
53
+ def in_time_range(start_time, end_time)
54
+ where(created_at: start_time..end_time)
55
+ end
56
+
57
+ # Find transitions with specific metadata values
58
+ #
59
+ # @param key [String, Symbol] The metadata key to search for
60
+ # @param value [Object] The value to match
61
+ # @return [ActiveRecord::Relation] Transitions with matching metadata
62
+ def with_metadata_value(key, value)
63
+ where('metadata->:key = :value', key: key.to_s, value: value.to_json.delete('"'))
64
+ end
65
+
66
+ # Get transition statistics for analytics
67
+ #
68
+ # @return [Hash] Statistics about transitions
69
+ def statistics
70
+ {
71
+ total_transitions: count,
72
+ states: group(:to_state).count,
73
+ recent_activity: where(created_at: 24.hours.ago..Time.current).count,
74
+ average_time_between_transitions: average_time_between_transitions
75
+ }
76
+ end
77
+
78
+ private
79
+
80
+ # Calculate average time between transitions
81
+ #
82
+ # @return [Float, nil] Average seconds between transitions
83
+ def average_time_between_transitions
84
+ transitions = order(:created_at).pluck(:created_at)
85
+ return nil if transitions.size < 2
86
+
87
+ total_time = 0
88
+ (1...transitions.size).each do |i|
89
+ total_time += (transitions[i] - transitions[i - 1])
90
+ end
91
+
92
+ total_time / (transitions.size - 1)
93
+ end
94
+ end
95
+
96
+ # Instance methods
97
+
98
+ # Get the duration since the previous transition
99
+ #
100
+ # @return [Float, nil] Duration in seconds since previous transition
101
+ def duration_since_previous
102
+ previous_transition = self.class.where(task_id: task_id)
103
+ .where(sort_key: ...sort_key)
104
+ .order(sort_key: :desc)
105
+ .first
106
+
107
+ return nil unless previous_transition
108
+
109
+ created_at - previous_transition.created_at
110
+ end
111
+
112
+ # Check if this transition represents an error state
113
+ #
114
+ # @return [Boolean] True if transitioning to an error state
115
+ def error_transition?
116
+ to_state == 'error'
117
+ end
118
+
119
+ # Check if this transition represents completion
120
+ #
121
+ # @return [Boolean] True if transitioning to a completion state
122
+ def completion_transition?
123
+ %w[complete resolved_manually].include?(to_state)
124
+ end
125
+
126
+ # Check if this transition represents cancellation
127
+ #
128
+ # @return [Boolean] True if transitioning to cancelled state
129
+ def cancellation_transition?
130
+ to_state == 'cancelled'
131
+ end
132
+
133
+ # Get human-readable description of the transition
134
+ #
135
+ # @return [String] Description of what this transition represents
136
+ def description
137
+ case to_state
138
+ when 'pending'
139
+ 'Task initialized and ready for processing'
140
+ when 'in_progress'
141
+ 'Task execution started'
142
+ when 'complete'
143
+ 'Task completed successfully'
144
+ when 'error'
145
+ 'Task encountered an error'
146
+ when 'cancelled'
147
+ 'Task was cancelled'
148
+ when 'resolved_manually'
149
+ 'Task was manually resolved'
150
+ else
151
+ "Task transitioned to #{to_state}"
152
+ end
153
+ end
154
+
155
+ # Get formatted metadata for display
156
+ #
157
+ # @return [Hash] Formatted metadata with additional computed fields
158
+ def formatted_metadata
159
+ base_metadata = metadata.dup
160
+
161
+ # Add computed fields
162
+ base_metadata['duration_since_previous'] = duration_since_previous
163
+ base_metadata['transition_description'] = description
164
+ base_metadata['transition_timestamp'] = created_at.iso8601
165
+
166
+ base_metadata
167
+ end
168
+
169
+ # Check if transition has specific metadata
170
+ #
171
+ # @param key [String, Symbol] The metadata key to check for
172
+ # @return [Boolean] True if the metadata contains the key
173
+ def has_metadata?(key)
174
+ metadata.key?(key.to_s)
175
+ end
176
+
177
+ # Get metadata value with default
178
+ #
179
+ # @param key [String, Symbol] The metadata key
180
+ # @param default [Object] Default value if key not found
181
+ # @return [Object] The metadata value or default
182
+ def get_metadata(key, default = nil)
183
+ metadata.fetch(key.to_s, default)
184
+ end
185
+
186
+ # Set metadata value
187
+ #
188
+ # @param key [String, Symbol] The metadata key
189
+ # @param value [Object] The value to set
190
+ # @return [Object] The set value
191
+ def set_metadata(key, value)
192
+ self.metadata = metadata.merge(key.to_s => value)
193
+ value
194
+ end
195
+
196
+ private
197
+
198
+ # Ensure metadata is always initialized as a hash
199
+ #
200
+ # @return [void]
201
+ def ensure_metadata_hash
202
+ self.metadata ||= {}
203
+ end
204
+
205
+ # Ensure metadata is present for validation
206
+ #
207
+ # @return [void]
208
+ def ensure_metadata_presence
209
+ self.metadata = {} if metadata.blank?
210
+ end
211
+
212
+ # Custom validation for metadata
213
+ #
214
+ # @return [void]
215
+ def metadata_must_be_hash
216
+ if metadata.nil?
217
+ self.metadata = {}
218
+ elsif !metadata.is_a?(Hash)
219
+ errors.add(:metadata, 'must be a hash')
220
+ end
221
+ end
222
+
223
+ # Validate that the task exists
224
+ #
225
+ # @return [void]
226
+ def task_must_exist
227
+ return if task_id.blank?
228
+
229
+ errors.add(:task, 'must exist before creating transition') unless Tasker::Task.exists?(task_id: task_id)
230
+ rescue ActiveRecord::StatementInvalid => e
231
+ # Handle cases where the table might not exist (e.g., during migrations)
232
+ Rails.logger.warn { "Could not validate task existence: #{e.message}" }
233
+ end
234
+ end
235
+ end