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,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module Tasker
6
+ module Generators
7
+ class SubscriberGenerator < Rails::Generators::NamedBase
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ desc 'Generate a new Tasker event subscriber'
11
+
12
+ class_option :events, type: :array, default: [],
13
+ desc: 'Events to subscribe to (e.g., task.completed step.failed)'
14
+
15
+ class_option :directory, type: :string, default: 'app/subscribers',
16
+ desc: 'Directory to place the subscriber'
17
+
18
+ class_option :metrics, type: :boolean, default: false,
19
+ desc: 'Generate a specialized metrics collection subscriber'
20
+
21
+ def create_subscriber_file
22
+ if options[:metrics]
23
+ template 'metrics_subscriber.rb.erb', File.join(options[:directory], "#{file_name}_subscriber.rb")
24
+ else
25
+ template 'subscriber.rb.erb', File.join(options[:directory], "#{file_name}_subscriber.rb")
26
+ end
27
+ end
28
+
29
+ def create_spec_file
30
+ return unless defined?(RSpec)
31
+
32
+ if options[:metrics]
33
+ template 'metrics_subscriber_spec.rb.erb', File.join('spec', 'subscribers', "#{file_name}_subscriber_spec.rb")
34
+ else
35
+ template 'subscriber_spec.rb.erb', File.join('spec', 'subscribers', "#{file_name}_subscriber_spec.rb")
36
+ end
37
+ end
38
+
39
+ def show_usage_instructions
40
+ say "\n#{set_color('Subscriber created successfully!', :green)}"
41
+
42
+ if options[:metrics]
43
+ say "\n#{set_color('Metrics subscriber features:', :cyan)}"
44
+ say ' - Built-in helper methods for extracting timing, error, and performance metrics'
45
+ say ' - Automatic tag generation for categorization'
46
+ say ' - Examples for StatsD, DataDog, Prometheus, and other metrics systems'
47
+ say ' - Safe numeric value extraction with defaults'
48
+ end
49
+
50
+ say "\nTo register your subscriber, add this to an initializer:"
51
+ say set_color(" #{class_name}Subscriber.subscribe(Tasker::Events::Publisher.instance)", :cyan)
52
+
53
+ if options[:events].any?
54
+ say "\nYour subscriber will handle these events:"
55
+ options[:events].each do |event|
56
+ method_name = "handle_#{event.tr('.', '_')}"
57
+ say set_color(" #{event} -> #{method_name}", :yellow)
58
+ end
59
+ end
60
+
61
+ say "\nAvailable events can be viewed with:"
62
+ say set_color(' Tasker::Events.catalog.keys', :cyan)
63
+
64
+ return unless options[:metrics]
65
+
66
+ say "\n#{set_color('Metrics collection examples:', :green)}"
67
+ say ' - Task completion rates and durations'
68
+ say ' - Error categorization and retry patterns'
69
+ say ' - Performance monitoring and resource usage'
70
+ say ' - Business metrics with proper tagging'
71
+ end
72
+
73
+ private
74
+
75
+ def file_name
76
+ @file_name ||= name.underscore
77
+ end
78
+
79
+ def class_name
80
+ @class_name ||= name.camelize
81
+ end
82
+
83
+ def subscribed_events
84
+ if options[:metrics] && options[:events].empty?
85
+ # Default to common metrics events if none specified
86
+ %w[task.completed task.failed step.completed step.failed]
87
+ else
88
+ options[:events]
89
+ end
90
+ end
91
+
92
+ def handler_methods
93
+ subscribed_events.map do |event|
94
+ {
95
+ event: event,
96
+ method_name: "handle_#{event.tr('.', '_')}",
97
+ method_signature: "handle_#{event.tr('.', '_')}(event)"
98
+ }
99
+ end
100
+ end
101
+
102
+ def metrics_type?
103
+ options[:metrics]
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module Tasker
6
+ module Generators
7
+ class TaskHandlerGenerator < Rails::Generators::NamedBase
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ desc 'Generate a new Tasker task handler with TaskNamespace + versioning support, YAML configuration and tests'
11
+
12
+ class_option :module_namespace, type: :string, default: nil,
13
+ desc: 'The module namespace for the task handler ' \
14
+ '(defaults to Tasker.configuration.engine.default_module_namespace)'
15
+ class_option :namespace_name, type: :string, default: 'default',
16
+ desc: 'The TaskNamespace for organizing the task (e.g., payments, inventory, notifications)'
17
+ class_option :version, type: :string, default: '0.1.0',
18
+ desc: 'Semantic version for the task handler (e.g., 1.0.0, 2.1.0)'
19
+ class_option :description, type: :string, default: nil,
20
+ desc: 'Description of what this task handler does'
21
+ class_option :steps, type: :array, default: [],
22
+ desc: 'Step names to include in the task (e.g., --steps=validate,process,complete)'
23
+
24
+ def create_task_handler_files
25
+ # Set variables first
26
+ @module_namespace = options[:module_namespace] || Tasker.configuration.engine.default_module_namespace
27
+ @module_path = @module_namespace&.underscore
28
+ @task_handler_class = name.camelize
29
+ @task_name = name.underscore
30
+ @namespace_name = options[:namespace_name]
31
+ @version = options[:version]
32
+ @description = options[:description]
33
+ @steps = options[:steps]
34
+
35
+ # Load configuration
36
+ ensure_configuration_loaded
37
+
38
+ # Get directory paths from configuration
39
+ @task_handler_directory = Tasker.configuration.engine.task_handler_directory
40
+ @task_config_directory = Tasker.configuration.engine.task_config_directory
41
+
42
+ # Ensure directories exist
43
+ ensure_directories_exist(
44
+ [
45
+ task_handler_directory_with_module_path,
46
+ spec_directory_with_module_path,
47
+ task_config_directory_with_module_path
48
+ ]
49
+ )
50
+
51
+ # Create the YAML config file
52
+ template 'task_config.yaml.erb', "#{task_config_directory_with_module_path}/#{@task_name}.yaml"
53
+
54
+ # Create the task handler class
55
+ template 'task_handler.rb.erb', "#{task_handler_directory_with_module_path}/#{@task_name}.rb"
56
+
57
+ # Create the task handler spec
58
+ template 'task_handler_spec.rb.erb', "#{spec_directory_with_module_path}/#{@task_name}_spec.rb"
59
+
60
+ display_success_message
61
+ end
62
+
63
+ private
64
+
65
+ def usable_module_path
66
+ @module_path ? "#{@module_path}/" : ''
67
+ end
68
+
69
+ def task_handler_directory_with_module_path
70
+ Rails.root.join("app/#{@task_handler_directory}/#{usable_module_path}")
71
+ end
72
+
73
+ def task_config_directory_with_module_path
74
+ Rails.root.join("config/#{@task_config_directory}/#{usable_module_path}")
75
+ end
76
+
77
+ def spec_directory_with_module_path
78
+ Rails.root.join("spec/#{@task_handler_directory}/#{usable_module_path}")
79
+ end
80
+
81
+ def ensure_configuration_loaded
82
+ # Check if Tasker is already loaded
83
+ return if defined?(Tasker) && Tasker.respond_to?(:configuration)
84
+
85
+ initializer_path = Rails.root.join('config/initializers/tasker.rb')
86
+
87
+ # Copy initializer if it doesn't exist
88
+ unless File.exist?(initializer_path)
89
+ template_path = File.expand_path('templates/initialize.rb.erb', __dir__)
90
+ FileUtils.cp(template_path, initializer_path)
91
+ Rails.logger.debug { "Created Tasker configuration at #{initializer_path}" }
92
+ end
93
+
94
+ # Load the initializer
95
+ require initializer_path
96
+ end
97
+
98
+ def ensure_directories_exist(dirs)
99
+ dirs.each do |dir|
100
+ unless File.directory?(dir)
101
+ FileUtils.mkdir_p(dir)
102
+ Rails.logger.debug { "Created directory: #{dir}" }
103
+ end
104
+ end
105
+ end
106
+
107
+ def display_success_message
108
+ say "\nTask handler created successfully!"
109
+ say ''
110
+ say 'Files created:'
111
+ say " - #{task_handler_directory_with_module_path}/#{@task_name}.rb"
112
+ say " - #{task_config_directory_with_module_path}/#{@task_name}.yaml"
113
+ say " - #{spec_directory_with_module_path}/#{@task_name}_spec.rb"
114
+ say ''
115
+ say 'Next steps:'
116
+ say ' 1. Define your step handlers in the YAML configuration'
117
+ say ' 2. Implement step handlers as needed'
118
+ test_path = "spec/#{@task_handler_directory}/#{usable_module_path}#{@task_name}_spec.rb"
119
+ say " 3. Run your tests: bundle exec rspec #{test_path}"
120
+ say ''
121
+ say 'Usage example:'
122
+ say ' task_request = Tasker::Types::TaskRequest.new('
123
+ say " name: '#{@task_name}',"
124
+ say " namespace: '#{@namespace_name}',"
125
+ say " version: '#{@version}',"
126
+ say ' context: { /* your task context */ }'
127
+ say ' )'
128
+ say ''
129
+ say ' handler = Tasker::HandlerFactory.instance.get('
130
+ say " '#{@task_name}',"
131
+ say " namespace_name: '#{@namespace_name}',"
132
+ say " version: '#{@version}'"
133
+ say ' )'
134
+ say ' task = handler.initialize_task!(task_request)'
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ # API Token authenticator for <%= class_name %>
4
+ # Generated by: rails generate tasker:authenticator <%= file_name %> --type=api_token
5
+ #
6
+ # This authenticator implements API token-based authentication.
7
+ # Expects tokens to be passed in request headers and looks up users by token.
8
+ #
9
+ # Configuration example:
10
+ # Tasker.configuration do |config|
11
+ # config.auth do |auth|
12
+ # auth.strategy = :custom
13
+ # auth.options = {
14
+ # authenticator_class: '<%= class_name %>Authenticator',
15
+ # header_name: 'X-API-Token',
16
+ # user_class: '<%= user_model_class %>',
17
+ # token_field: 'api_token'
18
+ # }
19
+ # end
20
+ # end
21
+
22
+ class <%= class_name %>Authenticator
23
+ include Tasker::Authentication::Interface
24
+
25
+ def initialize(options = {})
26
+ @header_name = options[:header_name] || 'X-API-Token'
27
+ @user_class = options[:user_class] || '<%= user_model_class %>'
28
+ @token_field = options[:token_field] || 'api_token'
29
+ @options = options
30
+ end
31
+
32
+ # Required: Authenticate the request, raise exception if fails
33
+ def authenticate!(controller)
34
+ user = current_user(controller)
35
+ unless user
36
+ raise Tasker::Authentication::AuthenticationError,
37
+ 'Invalid or missing API token'
38
+ end
39
+ true
40
+ end
41
+
42
+ # Required: Get the current authenticated user
43
+ def current_user(controller)
44
+ return @current_user if defined?(@current_user)
45
+
46
+ @current_user = begin
47
+ token = extract_token(controller.request)
48
+ return nil unless token
49
+
50
+ find_user_by_token(token)
51
+ rescue StandardError => e
52
+ Rails.logger.debug "API token authentication failed: #{e.message}"
53
+ nil
54
+ end
55
+ end
56
+
57
+ # Optional: Configuration validation
58
+ def validate_configuration(options = {})
59
+ errors = []
60
+
61
+ # Validate user class
62
+ user_class = options[:user_class] || '<%= user_model_class %>'
63
+ begin
64
+ model = user_class.constantize
65
+
66
+ # Check if the token field exists
67
+ token_field = options[:token_field] || 'api_token'
68
+ unless model.column_names.include?(token_field.to_s)
69
+ errors << "User model '#{user_class}' does not have '#{token_field}' column"
70
+ end
71
+ rescue NameError
72
+ errors << "User class '#{user_class}' not found"
73
+ end
74
+
75
+ # Validate header name
76
+ header_name = options[:header_name]
77
+ if header_name.present? && !header_name.is_a?(String)
78
+ errors << 'Header name must be a string'
79
+ end
80
+
81
+ errors
82
+ end
83
+
84
+ private
85
+
86
+ attr_reader :header_name, :user_class, :token_field, :options
87
+
88
+ def extract_token(request)
89
+ # Try configured header first
90
+ token = request.headers[@header_name]
91
+ return token if token.present?
92
+
93
+ # Fallback to Authorization header with Bearer format
94
+ auth_header = request.headers['Authorization']
95
+ return nil unless auth_header.present?
96
+
97
+ # Support "Bearer <token>" format
98
+ auth_header.start_with?('Bearer ') ? auth_header.sub(/^Bearer /, '') : auth_header
99
+ end
100
+
101
+ def find_user_by_token(token)
102
+ return nil if token.blank?
103
+
104
+ user_model = @user_class.constantize
105
+ user_model.find_by(@token_field => token)
106
+ rescue ActiveRecord::RecordNotFound, NoMethodError
107
+ nil
108
+ end
109
+
110
+ def user_model
111
+ @user_model ||= @user_class.constantize
112
+ end
113
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe <%= class_name %>Authenticator, type: :model do
6
+ let(:options) do
7
+ {
8
+ header_name: 'X-API-Token',
9
+ user_class: '<%= user_model_class %>',
10
+ token_field: 'api_token'
11
+ }
12
+ end
13
+
14
+ let(:authenticator) { described_class.new(options) }
15
+ let(:controller) { instance_double('ActionController::Base') }
16
+ let(:request) { instance_double('ActionDispatch::Request') }
17
+ let(:headers) { {} }
18
+
19
+ before do
20
+ allow(controller).to receive(:request).and_return(request)
21
+ allow(request).to receive(:headers).and_return(headers)
22
+ end
23
+
24
+ describe '#initialize' do
25
+ it 'sets configuration options' do
26
+ expect(authenticator.send(:header_name)).to eq('X-API-Token')
27
+ expect(authenticator.send(:user_class)).to eq('<%= user_model_class %>')
28
+ expect(authenticator.send(:token_field)).to eq('api_token')
29
+ end
30
+
31
+ it 'uses default values when options are not provided' do
32
+ authenticator = described_class.new
33
+ expect(authenticator.send(:header_name)).to eq('X-API-Token')
34
+ expect(authenticator.send(:user_class)).to eq('<%= user_model_class %>')
35
+ expect(authenticator.send(:token_field)).to eq('api_token')
36
+ end
37
+ end
38
+
39
+ describe '#current_user' do
40
+ let(:token) { 'abc123token' }
41
+ let(:user) { double('User', id: 1) }
42
+
43
+ before do
44
+ # Mock the user model
45
+ user_model = double('UserModel')
46
+ allow('<%= user_model_class %>').to receive(:constantize).and_return(user_model)
47
+ allow(user_model).to receive(:find_by).with('api_token' => token).and_return(user)
48
+ end
49
+
50
+ context 'with valid token in configured header' do
51
+ before do
52
+ headers['X-API-Token'] = token
53
+ end
54
+
55
+ it 'returns the authenticated user' do
56
+ expect(authenticator.current_user(controller)).to eq(user)
57
+ end
58
+ end
59
+
60
+ context 'with valid token in Authorization header (Bearer format)' do
61
+ before do
62
+ headers['Authorization'] = "Bearer #{token}"
63
+ end
64
+
65
+ it 'returns the authenticated user' do
66
+ expect(authenticator.current_user(controller)).to eq(user)
67
+ end
68
+ end
69
+
70
+ context 'with valid token in Authorization header (raw format)' do
71
+ before do
72
+ headers['Authorization'] = token
73
+ end
74
+
75
+ it 'returns the authenticated user' do
76
+ expect(authenticator.current_user(controller)).to eq(user)
77
+ end
78
+ end
79
+
80
+ context 'with missing token' do
81
+ it 'returns nil' do
82
+ expect(authenticator.current_user(controller)).to be_nil
83
+ end
84
+ end
85
+
86
+ context 'with invalid token' do
87
+ before do
88
+ headers['X-API-Token'] = 'invalid_token'
89
+ user_model = double('UserModel')
90
+ allow('<%= user_model_class %>').to receive(:constantize).and_return(user_model)
91
+ allow(user_model).to receive(:find_by).with('api_token' => 'invalid_token').and_return(nil)
92
+ end
93
+
94
+ it 'returns nil' do
95
+ expect(authenticator.current_user(controller)).to be_nil
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#validate_configuration' do
101
+ context 'with valid configuration' do
102
+ before do
103
+ # Mock valid user model with token field
104
+ user_model = double('UserModel', column_names: ['id', 'name', 'api_token'])
105
+ allow('<%= user_model_class %>').to receive(:constantize).and_return(user_model)
106
+ end
107
+
108
+ it 'returns no errors' do
109
+ errors = authenticator.validate_configuration(options)
110
+ expect(errors).to be_empty
111
+ end
112
+ end
113
+
114
+ context 'with invalid user class' do
115
+ let(:invalid_options) { options.merge(user_class: 'NonExistentUser') }
116
+
117
+ it 'returns validation error' do
118
+ errors = authenticator.validate_configuration(invalid_options)
119
+ expect(errors).to include(/not found/)
120
+ end
121
+ end
122
+
123
+ context 'when user model is missing token field' do
124
+ before do
125
+ user_model = double('UserModel', column_names: ['id', 'name'])
126
+ allow('<%= user_model_class %>').to receive(:constantize).and_return(user_model)
127
+ end
128
+
129
+ it 'returns validation error' do
130
+ errors = authenticator.validate_configuration(options)
131
+ expect(errors).to include(/does not have 'api_token' column/)
132
+ end
133
+ end
134
+
135
+ context 'with invalid header name type' do
136
+ let(:invalid_options) { options.merge(header_name: 123) }
137
+
138
+ it 'returns validation error' do
139
+ errors = authenticator.validate_configuration(invalid_options)
140
+ expect(errors).to include('Header name must be a string')
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Authorization coordinator for <%= @coordinator_class_name %>
4
+ #
5
+ # This coordinator provides authorization logic for Tasker resources.
6
+ # Customize the authorization methods below to implement your business logic.
7
+ #
8
+ # For more advanced examples, see:
9
+ # - docs/AUTH.md (Authorization System section)
10
+ # - spec/examples/custom_authorization_coordinator.rb
11
+ # - spec/lib/tasker/authorization/ (test examples)
12
+ #
13
+ class <%= @coordinator_class_name %> < Tasker::Authorization::BaseCoordinator
14
+ protected
15
+
16
+ # Implement your authorization logic here
17
+ #
18
+ # @param resource [String] The resource being accessed (e.g., 'tasker.task')
19
+ # @param action [Symbol] The action being performed (e.g., :show, :create)
20
+ # @param context [Hash] Additional context (controller, params, user, etc.)
21
+ # @return [Boolean] true if authorized, false otherwise
22
+ def authorized?(resource, action, context = {})
23
+ # Return false if no user or user doesn't have permission methods
24
+ return false unless user&.respond_to?(:has_tasker_permission?)
25
+
26
+ case resource
27
+ when Tasker::Authorization::ResourceConstants::RESOURCES::TASK
28
+ authorize_task(action, context)
29
+ when Tasker::Authorization::ResourceConstants::RESOURCES::WORKFLOW_STEP
30
+ authorize_workflow_step(action, context)
31
+ when Tasker::Authorization::ResourceConstants::RESOURCES::TASK_DIAGRAM
32
+ authorize_task_diagram(action, context)
33
+ when Tasker::Authorization::ResourceConstants::RESOURCES::HEALTH_STATUS
34
+ authorize_system_status(action, context)
35
+ else
36
+ # Deny access to unknown resources
37
+ false
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ # Authorize task operations
44
+ def authorize_task(action, context)
45
+ case action
46
+ when :index, :show
47
+ # TODO: Implement your read permission logic
48
+ user.has_tasker_permission?("tasker.task:#{action}")
49
+ when :create, :update, :destroy, :retry, :cancel
50
+ # TODO: Implement your write permission logic
51
+ # Example: Admin users or users with specific permissions
52
+ user.tasker_admin? || user.has_tasker_permission?("tasker.task:#{action}")
53
+ else
54
+ false
55
+ end
56
+ end
57
+
58
+ # Authorize workflow step operations
59
+ def authorize_workflow_step(action, context)
60
+ case action
61
+ when :index, :show
62
+ # TODO: Implement your step read logic
63
+ user.has_tasker_permission?("tasker.workflow_step:#{action}")
64
+ when :update, :destroy, :retry, :cancel
65
+ # TODO: Implement your step write logic
66
+ # Example: Only admins can modify steps
67
+ user.tasker_admin?
68
+ else
69
+ false
70
+ end
71
+ end
72
+
73
+ # Authorize task diagram operations
74
+ def authorize_task_diagram(action, context)
75
+ case action
76
+ when :index, :show
77
+ # TODO: Implement your diagram access logic
78
+ user.has_tasker_permission?("tasker.task_diagram:#{action}")
79
+ else
80
+ false
81
+ end
82
+ end
83
+
84
+ # Authorize system status operations
85
+ def authorize_system_status(action, context)
86
+ case action
87
+ when :read
88
+ # TODO: Implement your system status access logic
89
+ # Example: Admin users or users with explicit permission
90
+ user.tasker_admin? || user.has_tasker_permission?("tasker.system_status:#{action}")
91
+ else
92
+ false
93
+ end
94
+ end
95
+ end