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,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe <%= @coordinator_class_name %>, type: :model do
6
+ let(:user_class) { Struct.new(:id, :permissions, :roles, :admin, keyword_init: true) }
7
+
8
+ let(:admin_user) do
9
+ user_class.new(
10
+ id: 1,
11
+ permissions: [],
12
+ roles: ['admin'],
13
+ admin: true
14
+ )
15
+ end
16
+
17
+ let(:regular_user) do
18
+ user_class.new(
19
+ id: 2,
20
+ permissions: [
21
+ 'tasker.task:index',
22
+ 'tasker.task:show',
23
+ 'tasker.workflow_step:index',
24
+ 'tasker.task_diagram:index'
25
+ ],
26
+ roles: ['user'],
27
+ admin: false
28
+ )
29
+ end
30
+
31
+ let(:coordinator) { described_class.new(user) }
32
+
33
+ # Add required methods to test users
34
+ before do
35
+ user_class.class_eval do
36
+ def has_tasker_permission?(permission)
37
+ permissions.include?(permission)
38
+ end
39
+
40
+ def tasker_admin?
41
+ admin == true
42
+ end
43
+
44
+ def tasker_roles
45
+ roles
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '#authorize!' do
51
+ context 'with admin user' do
52
+ let(:user) { admin_user }
53
+
54
+ it 'allows admin access to all resources' do
55
+ expect { coordinator.authorize!('tasker.task', :index) }.not_to raise_error
56
+ expect { coordinator.authorize!('tasker.task', :create) }.not_to raise_error
57
+ expect { coordinator.authorize!('tasker.workflow_step', :update) }.not_to raise_error
58
+ expect { coordinator.authorize!('tasker.task_diagram', :show) }.not_to raise_error
59
+ end
60
+ end
61
+
62
+ context 'with regular user' do
63
+ let(:user) { regular_user }
64
+
65
+ it 'allows access to permitted resources' do
66
+ expect { coordinator.authorize!('tasker.task', :index) }.not_to raise_error
67
+ expect { coordinator.authorize!('tasker.task', :show) }.not_to raise_error
68
+ expect { coordinator.authorize!('tasker.workflow_step', :index) }.not_to raise_error
69
+ expect { coordinator.authorize!('tasker.task_diagram', :index) }.not_to raise_error
70
+ end
71
+
72
+ it 'denies access to forbidden resources' do
73
+ expect { coordinator.authorize!('tasker.task', :create) }.to raise_error(Tasker::Authorization::UnauthorizedError)
74
+ expect { coordinator.authorize!('tasker.task', :destroy) }.to raise_error(Tasker::Authorization::UnauthorizedError)
75
+ expect { coordinator.authorize!('tasker.workflow_step', :update) }.to raise_error(Tasker::Authorization::UnauthorizedError)
76
+ end
77
+ end
78
+
79
+ context 'with no user' do
80
+ let(:user) { nil }
81
+
82
+ it 'denies all operations' do
83
+ expect { coordinator.authorize!('tasker.task', :index) }.to raise_error(Tasker::Authorization::UnauthorizedError)
84
+ expect { coordinator.authorize!('tasker.workflow_step', :show) }.to raise_error(Tasker::Authorization::UnauthorizedError)
85
+ expect { coordinator.authorize!('tasker.task_diagram', :show) }.to raise_error(Tasker::Authorization::UnauthorizedError)
86
+ end
87
+ end
88
+ end
89
+
90
+ describe '#can?' do
91
+ context 'with admin user' do
92
+ let(:user) { admin_user }
93
+
94
+ it 'returns true for valid operations' do
95
+ expect(coordinator.can?('tasker.task', :index)).to be true
96
+ expect(coordinator.can?('tasker.task', :create)).to be true
97
+ expect(coordinator.can?('tasker.workflow_step', :update)).to be true
98
+ expect(coordinator.can?('tasker.task_diagram', :show)).to be true
99
+ end
100
+ end
101
+
102
+ context 'with regular user' do
103
+ let(:user) { regular_user }
104
+
105
+ it 'returns true for permitted operations' do
106
+ expect(coordinator.can?('tasker.task', :index)).to be true
107
+ expect(coordinator.can?('tasker.task', :show)).to be true
108
+ expect(coordinator.can?('tasker.workflow_step', :index)).to be true
109
+ expect(coordinator.can?('tasker.task_diagram', :index)).to be true
110
+ end
111
+
112
+ it 'returns false for forbidden operations' do
113
+ expect(coordinator.can?('tasker.task', :create)).to be false
114
+ expect(coordinator.can?('tasker.task', :destroy)).to be false
115
+ expect(coordinator.can?('tasker.workflow_step', :update)).to be false
116
+ end
117
+ end
118
+
119
+ it 'returns false for unknown resources' do
120
+ expect(coordinator.can?('unknown.resource', :index)).to be false
121
+ end
122
+
123
+ it 'returns false for unknown actions' do
124
+ expect(coordinator.can?('tasker.task', :unknown_action)).to be false
125
+ end
126
+ end
127
+
128
+ describe 'interface compliance' do
129
+ it 'inherits from BaseCoordinator' do
130
+ expect(described_class.superclass).to eq(Tasker::Authorization::BaseCoordinator)
131
+ end
132
+
133
+ it 'implements the required authorized? method' do
134
+ expect(coordinator).to respond_to(:authorized?, true)
135
+ end
136
+
137
+ it 'provides access to the user' do
138
+ coordinator = described_class.new(regular_user)
139
+ expect(coordinator.send(:user)).to eq(regular_user)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Custom authenticator for <%= class_name %>
4
+ # Generated by: rails generate tasker:authenticator <%= file_name %> --type=custom
5
+ #
6
+ # This authenticator template provides a starting point for implementing
7
+ # custom authentication logic in your Tasker application.
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
+ # user_class: '<%= user_model_class %>'
16
+ # # Add your custom options here
17
+ # }
18
+ # end
19
+ # end
20
+
21
+ class <%= class_name %>Authenticator
22
+ include Tasker::Authentication::Interface
23
+
24
+ def initialize(options = {})
25
+ @user_class = options[:user_class] || '<%= user_model_class %>'
26
+ @options = options
27
+ end
28
+
29
+ # Required: Authenticate the request, raise exception if fails
30
+ def authenticate!(controller)
31
+ user = current_user(controller)
32
+ unless user
33
+ raise Tasker::Authentication::AuthenticationError,
34
+ 'Authentication failed. Please provide valid credentials.'
35
+ end
36
+ true
37
+ end
38
+
39
+ # Required: Get the current authenticated user
40
+ def current_user(controller)
41
+ return @current_user if defined?(@current_user)
42
+
43
+ @current_user = begin
44
+ # TODO: Implement your user lookup logic here
45
+ # Examples:
46
+ # - Check session for user ID
47
+ # - Extract token from headers
48
+ # - Use existing Rails authentication
49
+ # - Custom authentication scheme
50
+
51
+ # Example session-based lookup:
52
+ # user_id = controller.session[:user_id]
53
+ # return nil unless user_id
54
+ # user_model.find_by(id: user_id)
55
+
56
+ # Example header-based lookup:
57
+ # token = controller.request.headers['Authorization']
58
+ # return nil unless token
59
+ # find_user_by_token(token)
60
+
61
+ # Placeholder - replace with your logic
62
+ nil
63
+ rescue StandardError => e
64
+ Rails.logger.error "Authentication error in <%= class_name %>Authenticator: #{e.message}"
65
+ nil
66
+ end
67
+ end
68
+
69
+ # Optional: Check if user is authenticated (uses current_user by default)
70
+ def authenticated?(controller)
71
+ current_user(controller).present?
72
+ end
73
+
74
+ # Optional: Configuration validation
75
+ def validate_configuration(options = {})
76
+ errors = []
77
+
78
+ # Validate user class
79
+ user_class = options[:user_class] || '<%= user_model_class %>'
80
+ begin
81
+ user_class.constantize
82
+ rescue NameError
83
+ errors << "User class '#{user_class}' not found"
84
+ end
85
+
86
+ # TODO: Add your custom validation logic here
87
+ # Examples:
88
+ # - Required configuration options
89
+ # - External service dependencies
90
+ # - Security settings validation
91
+
92
+ errors
93
+ end
94
+
95
+ private
96
+
97
+ attr_reader :options, :user_class
98
+
99
+ def user_model
100
+ @user_model ||= @user_class.constantize
101
+ end
102
+
103
+ # TODO: Add your private helper methods here
104
+ # Examples:
105
+ # def extract_token(request)
106
+ # def find_user_by_token(token)
107
+ # def validate_credentials(credentials)
108
+ end
@@ -0,0 +1,162 @@
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
+ user_class: '<%= user_model_class %>'
9
+ # Add your custom options here
10
+ }
11
+ end
12
+
13
+ let(:authenticator) { described_class.new(options) }
14
+ let(:controller) { instance_double('ActionController::Base') }
15
+ let(:request) { instance_double('ActionDispatch::Request') }
16
+ let(:headers) { {} }
17
+
18
+ before do
19
+ allow(controller).to receive(:request).and_return(request)
20
+ allow(request).to receive(:headers).and_return(headers)
21
+ end
22
+
23
+ describe '#initialize' do
24
+ it 'sets default options' do
25
+ authenticator = described_class.new
26
+ expect(authenticator.send(:user_class)).to eq('<%= user_model_class %>')
27
+ end
28
+
29
+ it 'accepts custom options' do
30
+ custom_options = { user_class: 'CustomUser' }
31
+ authenticator = described_class.new(custom_options)
32
+ expect(authenticator.send(:user_class)).to eq('CustomUser')
33
+ end
34
+ end
35
+
36
+ describe '#authenticate!' do
37
+ context 'when user is authenticated' do
38
+ before do
39
+ allow(authenticator).to receive(:current_user).with(controller).and_return(double('User'))
40
+ end
41
+
42
+ it 'returns true' do
43
+ expect(authenticator.authenticate!(controller)).to be_truthy
44
+ end
45
+ end
46
+
47
+ context 'when user is not authenticated' do
48
+ before do
49
+ allow(authenticator).to receive(:current_user).with(controller).and_return(nil)
50
+ end
51
+
52
+ it 'raises AuthenticationError' do
53
+ expect do
54
+ authenticator.authenticate!(controller)
55
+ end.to raise_error(Tasker::Authentication::AuthenticationError)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#current_user' do
61
+ context 'when user authentication succeeds' do
62
+ # TODO: Implement test cases based on your authentication logic
63
+ # Example:
64
+ # let(:user) { create(:user) }
65
+ #
66
+ # before do
67
+ # # Set up your authentication scenario
68
+ # # e.g., session, headers, tokens, etc.
69
+ # end
70
+ #
71
+ # it 'returns the authenticated user' do
72
+ # expect(authenticator.current_user(controller)).to eq(user)
73
+ # end
74
+
75
+ it 'needs implementation based on your authentication logic' do
76
+ pending 'Implement based on your specific authentication method'
77
+ end
78
+ end
79
+
80
+ context 'when user authentication fails' do
81
+ it 'returns nil' do
82
+ expect(authenticator.current_user(controller)).to be_nil
83
+ end
84
+ end
85
+
86
+ context 'when authentication raises an error' do
87
+ before do
88
+ # Simulate an error in your authentication logic
89
+ allow(controller).to receive(:session).and_raise(StandardError, 'Session error')
90
+ end
91
+
92
+ it 'returns nil and logs the error' do
93
+ expect(Rails.logger).to receive(:error).with(/Authentication error/)
94
+ expect(authenticator.current_user(controller)).to be_nil
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#authenticated?' do
100
+ context 'when current_user returns a user' do
101
+ before do
102
+ allow(authenticator).to receive(:current_user).with(controller).and_return(double('User'))
103
+ end
104
+
105
+ it 'returns true' do
106
+ expect(authenticator.authenticated?(controller)).to be true
107
+ end
108
+ end
109
+
110
+ context 'when current_user returns nil' do
111
+ before do
112
+ allow(authenticator).to receive(:current_user).with(controller).and_return(nil)
113
+ end
114
+
115
+ it 'returns false' do
116
+ expect(authenticator.authenticated?(controller)).to be false
117
+ end
118
+ end
119
+ end
120
+
121
+ describe '#validate_configuration' do
122
+ context 'with valid configuration' do
123
+ it 'returns no errors' do
124
+ errors = authenticator.validate_configuration(options)
125
+ expect(errors).to be_empty
126
+ end
127
+ end
128
+
129
+ context 'with invalid user class' do
130
+ let(:invalid_options) { { user_class: 'NonExistentUser' } }
131
+
132
+ it 'returns validation errors' do
133
+ errors = authenticator.validate_configuration(invalid_options)
134
+ expect(errors).to include(/not found/)
135
+ end
136
+ end
137
+
138
+ # TODO: Add more validation test cases based on your specific requirements
139
+ # Examples:
140
+ # context 'when required option is missing' do
141
+ # let(:invalid_options) { options.except(:required_option) }
142
+ #
143
+ # it 'returns validation error' do
144
+ # errors = authenticator.validate_configuration(invalid_options)
145
+ # expect(errors).to include(/required/)
146
+ # end
147
+ # end
148
+ end
149
+
150
+ describe 'interface compliance' do
151
+ it 'includes the authentication interface' do
152
+ expect(described_class.included_modules).to include(Tasker::Authentication::Interface)
153
+ end
154
+
155
+ it 'responds to required interface methods' do
156
+ expect(authenticator).to respond_to(:authenticate!)
157
+ expect(authenticator).to respond_to(:current_user)
158
+ expect(authenticator).to respond_to(:authenticated?)
159
+ expect(authenticator).to respond_to(:validate_configuration)
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,62 @@
1
+ ---
2
+ # <%= application_name.humanize %> Custom Events Configuration
3
+ # Define your application-specific events here
4
+ # The system automatically protects against namespace collisions
5
+
6
+ events:
7
+ # Example order processing events
8
+ custom:
9
+ order_processed:
10
+ constant: "order.processed"
11
+ description: "Fired when an order is fully processed and ready for fulfillment"
12
+ payload_schema:
13
+ order_id: { type: "String", required: true }
14
+ customer_id: { type: "String", required: true }
15
+ total_amount: { type: "Float", required: true }
16
+ timestamp: { type: "Time", required: true }
17
+ fired_by: ["OrderService"]
18
+
19
+ payment_completed:
20
+ constant: "payment.completed"
21
+ description: "Fired when a payment is successfully processed"
22
+ payload_schema:
23
+ payment_id: { type: "String", required: true }
24
+ order_id: { type: "String", required: true }
25
+ amount: { type: "Float", required: true }
26
+ payment_method: { type: "String", required: true }
27
+ timestamp: { type: "Time", required: true }
28
+ fired_by: ["PaymentService"]
29
+
30
+ notification_sent:
31
+ constant: "notification.sent"
32
+ description: "Fired when a notification is successfully sent"
33
+ payload_schema:
34
+ notification_id: { type: "String", required: true }
35
+ recipient: { type: "String", required: true }
36
+ channel: { type: "String", required: true }
37
+ success: { type: "Boolean", required: true }
38
+ timestamp: { type: "Time", required: true }
39
+ fired_by: ["NotificationService"]
40
+
41
+ # Uncomment and customize these examples for your application:
42
+ #
43
+ # user_registered:
44
+ # constant: "user.registered"
45
+ # description: "Fired when a new user completes registration"
46
+ # payload_schema:
47
+ # user_id: { type: "String", required: true }
48
+ # email: { type: "String", required: true }
49
+ # registration_source: { type: "String", required: true }
50
+ # timestamp: { type: "Time", required: true }
51
+ # fired_by: ["UserService", "RegistrationController"]
52
+ #
53
+ # data_exported:
54
+ # constant: "data.exported"
55
+ # description: "Fired when data export is completed"
56
+ # payload_schema:
57
+ # export_id: { type: "String", required: true }
58
+ # format: { type: "String", required: true }
59
+ # record_count: { type: "Integer", required: true }
60
+ # file_size: { type: "Integer", required: false }
61
+ # timestamp: { type: "Time", required: true }
62
+ # fired_by: ["ExportService"]
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example Custom Events Subscriber for <%= application_name.humanize %>
4
+ #
5
+ # This subscriber demonstrates how to create custom event handlers
6
+ # for your application-specific events.
7
+ class CustomEventsSubscriber < Tasker::Events::Subscribers::BaseSubscriber
8
+ # Subscribe to custom events defined in config/tasker/events.yml
9
+ # Note: Use clean event names - the system handles namespace protection internally
10
+ subscribe_to 'order.processed',
11
+ 'payment.completed',
12
+ 'notification.sent'
13
+
14
+ # Handle order processed events
15
+ def handle_order_processed(event)
16
+ order_id = safe_get(event, :order_id)
17
+ customer_id = safe_get(event, :customer_id)
18
+ total_amount = safe_get(event, :total_amount)
19
+
20
+ Rails.logger.info("Order #{order_id} processed for customer #{customer_id}, total: $#{total_amount}")
21
+
22
+ # Example: Send completion notification
23
+ # OrderCompletionMailer.order_processed(order_id).deliver_later
24
+
25
+ # Example: Update analytics
26
+ # Analytics.track_order_completion(order_id: order_id, amount: total_amount)
27
+ end
28
+
29
+ # Handle payment completion events
30
+ def handle_payment_completed(event)
31
+ payment_id = safe_get(event, :payment_id)
32
+ order_id = safe_get(event, :order_id)
33
+ payment_method = safe_get(event, :payment_method)
34
+
35
+ Rails.logger.info("Payment #{payment_id} completed for order #{order_id} via #{payment_method}")
36
+
37
+ # Example: Record payment metrics
38
+ # PaymentMetrics.record_completion(payment_id: payment_id, method: payment_method)
39
+
40
+ # Example: Trigger fulfillment
41
+ # FulfillmentService.process_order(order_id)
42
+ end
43
+
44
+ # Handle notification sent events
45
+ def handle_notification_sent(event)
46
+ notification_id = safe_get(event, :notification_id)
47
+ recipient = safe_get(event, :recipient)
48
+ channel = safe_get(event, :channel)
49
+ success = safe_get(event, :success)
50
+
51
+ if success
52
+ Rails.logger.info("Notification #{notification_id} sent to #{recipient} via #{channel}")
53
+
54
+ # Example: Update delivery metrics
55
+ # NotificationMetrics.record_delivery(notification_id: notification_id, channel: channel)
56
+ else
57
+ Rails.logger.warn("Failed to send notification #{notification_id} to #{recipient}")
58
+
59
+ # Example: Retry or escalate
60
+ # NotificationRetryService.schedule_retry(notification_id)
61
+ end
62
+ end
63
+
64
+ # Optional: Override to add subscriber-specific filtering
65
+ # def should_process_event?(event_constant)
66
+ # # Only process events during business hours
67
+ # Time.current.hour.between?(9, 17)
68
+ # end
69
+ end
70
+
71
+ # Register the subscriber (add this to an initializer)
72
+ # CustomEventsSubscriber.subscribe(Tasker::Events::Publisher.instance)
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Devise authenticator for <%= class_name %>
4
+ # Generated by: rails generate tasker:authenticator <%= file_name %> --type=devise
5
+ #
6
+ # This authenticator integrates with Devise authentication system.
7
+ # Uses Devise's built-in authentication methods and scopes.
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
+ # scope: :user
16
+ # }
17
+ # end
18
+ # end
19
+
20
+ class <%= class_name %>Authenticator
21
+ include Tasker::Authentication::Interface
22
+
23
+ def initialize(options = {})
24
+ @scope = options[:scope] || :user
25
+ @failure_app = options[:failure_app]
26
+ @options = options
27
+ end
28
+
29
+ # Required: Authenticate the request, raise exception if fails
30
+ def authenticate!(controller)
31
+ # Use Devise's built-in authentication
32
+ result = controller.send("authenticate_#{@scope}!")
33
+
34
+ # Devise authenticate_*! methods return true on success or redirect/halt on failure
35
+ # If we reach here, authentication was successful
36
+ result
37
+ rescue StandardError => e
38
+ # Devise authentication failed
39
+ raise Tasker::Authentication::AuthenticationError,
40
+ "Devise authentication failed: #{e.message}"
41
+ end
42
+
43
+ # Required: Get the current authenticated user
44
+ def current_user(controller)
45
+ # Use Devise's current_user helper
46
+ controller.send("current_#{@scope}")
47
+ rescue StandardError => e
48
+ Rails.logger.error "Error getting current #{@scope}: #{e.message}"
49
+ nil
50
+ end
51
+
52
+ # Optional: Check if user is authenticated
53
+ def authenticated?(controller)
54
+ # Use Devise's user_signed_in? helper if available
55
+ signed_in_method = "#{@scope}_signed_in?"
56
+
57
+ if controller.respond_to?(signed_in_method)
58
+ controller.send(signed_in_method)
59
+ else
60
+ # Fallback to checking current_user presence
61
+ current_user(controller).present?
62
+ end
63
+ end
64
+
65
+ # Optional: Configuration validation
66
+ def validate_configuration(options = {})
67
+ errors = []
68
+
69
+ # Check if Devise is available
70
+ unless defined?(Devise)
71
+ errors << 'Devise gem is required for DeviseAuthenticator'
72
+ end
73
+
74
+ # Validate scope
75
+ scope = options[:scope] || :user
76
+ unless scope.is_a?(Symbol)
77
+ errors << 'Devise scope must be a symbol'
78
+ end
79
+
80
+ # Check if scope is configured in Devise
81
+ if defined?(Devise) && Devise.mappings[scope].nil?
82
+ errors << "Devise scope '#{scope}' is not configured. Available scopes: #{Devise.mappings.keys.join(', ')}"
83
+ end
84
+
85
+ errors
86
+ end
87
+
88
+ private
89
+
90
+ attr_reader :scope, :failure_app, :options
91
+
92
+ # Helper method to get the user model class for the scope
93
+ def user_model_class
94
+ return nil unless defined?(Devise)
95
+
96
+ mapping = Devise.mappings[@scope]
97
+ mapping&.class_name&.constantize
98
+ rescue StandardError
99
+ nil
100
+ end
101
+ end