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,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: false
4
+
5
+ module Tasker
6
+ # Abstract base class for all Tasker models that provides optional secondary database support.
7
+ #
8
+ # This class follows Rails multi-database conventions using the `connects_to` API.
9
+ # When secondary database is enabled, it connects to a database named 'tasker' in database.yml.
10
+ #
11
+ # @example Basic usage with shared database (default)
12
+ # Tasker.configuration do |config|
13
+ # config.database.enable_secondary_database = false
14
+ # end
15
+ #
16
+ # @example Using a dedicated Tasker database
17
+ # Tasker.configuration do |config|
18
+ # config.database.enable_secondary_database = true
19
+ # config.database.name = :tasker
20
+ # end
21
+ #
22
+ # # In database.yml:
23
+ # production:
24
+ # primary:
25
+ # database: my_primary_database
26
+ # adapter: postgresql
27
+ # tasker:
28
+ # database: my_tasker_database
29
+ # adapter: postgresql
30
+ #
31
+ class ApplicationRecord < ActiveRecord::Base
32
+ self.abstract_class = true
33
+
34
+ # Configure database connections based on Tasker configuration
35
+ # This follows Rails multi-database conventions but only when database is actually available
36
+ def self.configure_database_connections
37
+ # Ensure Tasker configuration is available - fail fast if not
38
+ unless defined?(Tasker.configuration)
39
+ error_message = 'Tasker.configuration is not available. This indicates a Rails initialization order issue. ' \
40
+ 'Ensure Tasker is properly initialized before models are loaded.'
41
+ raise StandardError, error_message
42
+ end
43
+
44
+ config = Tasker.configuration.database
45
+ if config.enable_secondary_database && config.name.present?
46
+ # Check if the database configuration actually exists before calling connects_to
47
+ if database_configuration_exists?(config.name)
48
+ # Use connects_to for proper Rails multi-database support
49
+ connects_to database: { writing: config.name.to_sym, reading: config.name.to_sym }
50
+ else
51
+ warning_message = "Tasker secondary database '#{config.name}' is enabled but not found in database.yml. " \
52
+ 'Using default database.'
53
+ Rails.logger.warn warning_message
54
+ end
55
+ end
56
+ rescue ActiveRecord::DatabaseConfigurations::InvalidConfigurationError => e
57
+ # Log database configuration errors but don't fail startup - this allows for
58
+ # environments where the secondary database might not be available
59
+ Rails.logger.warn "Tasker database configuration error: #{e.message}"
60
+ end
61
+
62
+ # Check if a database configuration exists in the current environment
63
+ def self.database_configuration_exists?(db_name)
64
+ Rails.application.config.database_configuration.key?(db_name.to_s)
65
+ end
66
+
67
+ # Call the connection configuration method
68
+ configure_database_connections
69
+ end
70
+ end
@@ -0,0 +1,26 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: dependent_systems
7
+ #
8
+ # description :string(255)
9
+ # name :string(64) not null
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ # dependent_system_id :integer not null, primary key
13
+ #
14
+ # Indexes
15
+ #
16
+ # dependent_systems_name_index (name)
17
+ # dependent_systems_name_unique (name) UNIQUE
18
+ #
19
+ module Tasker
20
+ class DependentSystem < ApplicationRecord
21
+ self.primary_key = :dependent_system_id
22
+ has_many :dependent_system_object_maps, dependent: :destroy
23
+ has_many :named_steps, dependent: :destroy
24
+ validates :name, presence: true, uniqueness: true
25
+ end
26
+ end
@@ -0,0 +1,64 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: dependent_system_object_maps
7
+ #
8
+ # remote_id_one :string(128) not null
9
+ # remote_id_two :string(128) not null
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ # dependent_system_object_map_id :bigint not null, primary key
13
+ # dependent_system_one_id :integer not null
14
+ # dependent_system_two_id :integer not null
15
+ #
16
+ # Indexes
17
+ #
18
+ # dependent_system_object_maps_dependent_system_one_id_dependent_ (dependent_system_one_id,dependent_system_two_id,remote_id_one,remote_id_two) UNIQUE
19
+ # dependent_system_object_maps_dependent_system_one_id_index (dependent_system_one_id)
20
+ # dependent_system_object_maps_dependent_system_two_id_index (dependent_system_two_id)
21
+ # dependent_system_object_maps_remote_id_one_index (remote_id_one)
22
+ # dependent_system_object_maps_remote_id_two_index (remote_id_two)
23
+ #
24
+ # Foreign Keys
25
+ #
26
+ # dependent_system_object_maps_dependent_system_one_id_foreign (dependent_system_one_id => dependent_systems.dependent_system_id)
27
+ # dependent_system_object_maps_dependent_system_two_id_foreign (dependent_system_two_id => dependent_systems.dependent_system_id)
28
+ #
29
+
30
+ module Tasker
31
+ class DependentSystemObjectMap < ApplicationRecord
32
+ self.primary_key = :dependent_system_object_map_id
33
+ belongs_to :dependent_system_one, class_name: 'Tasker::DependentSystem'
34
+ belongs_to :dependent_system_two, class_name: 'Tasker::DependentSystem'
35
+ validates :remote_id_one, presence: true
36
+ validates :remote_id_two, presence: true
37
+
38
+ def self.find_or_create(system_one_name, system_one_id, system_two_name, system_two_id)
39
+ system_one = Tasker::DependentSystem.find_or_create_by!(name: system_one_name)
40
+ system_two = Tasker::DependentSystem.find_or_create_by!(name: system_two_name)
41
+ # these could be in either order
42
+ inst = where(
43
+ remote_id_one: system_one_id,
44
+ remote_id_two: system_two_id,
45
+ dependent_system_one_id: system_one.dependent_system_id,
46
+ dependent_system_two_id: system_two.dependent_system_id
47
+ ).or(
48
+ where(
49
+ remote_id_one: system_two_id,
50
+ remote_id_two: system_one_id,
51
+ dependent_system_one_id: system_two.dependent_system_id,
52
+ dependent_system_two_id: system_one.dependent_system_id
53
+ )
54
+ ).first
55
+ inst ||= create(
56
+ remote_id_one: system_one_id,
57
+ remote_id_two: system_two_id,
58
+ dependent_system_one: system_one,
59
+ dependent_system_two: system_two
60
+ )
61
+ inst
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ module Diagram
5
+ # Represents an edge (connection) between nodes in a flowchart diagram
6
+ class Edge
7
+ # @return [String] The ID of the source node
8
+ attr_accessor :source_id
9
+
10
+ # @return [String] The ID of the target node
11
+ attr_accessor :target_id
12
+
13
+ # @return [String] The label to display on the edge
14
+ attr_accessor :label
15
+
16
+ # @return [String] The type of edge (e.g., 'solid', 'dashed')
17
+ attr_accessor :type
18
+
19
+ # @return [String] Direction of the arrow (e.g., 'forward', 'back', 'both', 'none')
20
+ attr_accessor :direction
21
+
22
+ # @return [Hash] Additional attributes for the edge
23
+ attr_accessor :attributes
24
+
25
+ # Define constants for style mappings
26
+ EDGE_STYLES = {
27
+ 'dashed' => '--',
28
+ 'thick' => '==',
29
+ 'dotted' => '-.-',
30
+ 'solid' => '--' # Default
31
+ }.freeze
32
+
33
+ ARROW_STYLES = {
34
+ 'back' => '<',
35
+ 'both' => '<>',
36
+ 'none' => '',
37
+ 'forward' => '>' # Default
38
+ }.freeze
39
+
40
+ # Creates a new diagram edge
41
+ #
42
+ # @param source_id [String] The ID of the source node
43
+ # @param target_id [String] The ID of the target node
44
+ # @param label [String] The label to display on the edge
45
+ # @param type [String] The type of edge (default: 'solid')
46
+ # @param direction [String] Direction of the arrow (default: 'forward')
47
+ # @param attributes [Hash] Additional attributes for the edge
48
+ # @return [Edge] A new diagram edge
49
+ def initialize(source_id:, target_id:, label: '', type: 'solid', direction: 'forward', attributes: {})
50
+ @source_id = source_id
51
+ @target_id = target_id
52
+ @label = label
53
+ @type = type
54
+ @direction = direction
55
+ @attributes = attributes
56
+ end
57
+
58
+ # Convert the edge to a hash representation
59
+ #
60
+ # @return [Hash] Hash representation of the edge
61
+ def to_h
62
+ {
63
+ source_id: source_id,
64
+ target_id: target_id,
65
+ label: label,
66
+ type: type,
67
+ direction: direction,
68
+ attributes: attributes
69
+ }.compact
70
+ end
71
+
72
+ # Convert the edge to a JSON string
73
+ #
74
+ # @return [String] JSON representation of the edge
75
+ def to_json(*)
76
+ to_h.to_json(*)
77
+ end
78
+
79
+ # Generate Mermaid diagram syntax for this edge
80
+ #
81
+ # @return [String] Mermaid syntax for the edge
82
+ def to_mermaid
83
+ # For labeled edges, use the |label| syntax instead of adding a separate text label
84
+ if label&.present? # rubocop:disable Lint/RedundantSafeNavigation
85
+ "#{source_id} -->|\"#{escape_mermaid_text(label)}\"| #{target_id}"
86
+ else
87
+ "#{source_id} --> #{target_id}"
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ # Escape special characters in Mermaid text
94
+ #
95
+ # @param text [String] The text to escape
96
+ # @return [String] Escaped text safe for Mermaid diagrams
97
+ def escape_mermaid_text(text)
98
+ # Handle nil values
99
+ return '' if text.nil?
100
+
101
+ # Replace instances of " with ' to avoid breaking the Mermaid syntax
102
+ text.to_s.tr('"', "'")
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ module Diagram
5
+ # Represents a flowchart diagram with nodes and edges
6
+ class Flowchart
7
+ # @return [Array<Tasker::Diagram::Node>] The nodes in the flowchart
8
+ attr_accessor :nodes
9
+
10
+ # @return [Array<Tasker::Diagram::Edge>] The edges in the flowchart
11
+ attr_accessor :edges
12
+
13
+ # @return [String] The direction of the flowchart (TD: top-down, LR: left-right, etc.)
14
+ attr_accessor :direction
15
+
16
+ # @return [String] The title of the flowchart
17
+ attr_accessor :title
18
+
19
+ # @return [Hash] Additional attributes for the flowchart
20
+ attr_accessor :attributes
21
+
22
+ # Creates a new flowchart diagram
23
+ #
24
+ # @param nodes [Array<Tasker::Diagram::Node>] The nodes in the flowchart
25
+ # @param edges [Array<Tasker::Diagram::Edge>] The edges in the flowchart
26
+ # @param direction [String] The direction of the flowchart (default: 'TD')
27
+ # @param title [String, nil] The title of the flowchart
28
+ # @param attributes [Hash] Additional attributes for the flowchart
29
+ # @return [Flowchart] A new flowchart diagram
30
+ def initialize(nodes: [], edges: [], direction: 'TD', title: nil, attributes: {})
31
+ @nodes = nodes
32
+ @edges = edges
33
+ @direction = direction
34
+ @title = title
35
+ @attributes = attributes
36
+ end
37
+
38
+ # Add a node to the flowchart
39
+ #
40
+ # @param node [Tasker::Diagram::Node] The node to add
41
+ # @return [Tasker::Diagram::Node] The added node
42
+ def add_node(node)
43
+ @nodes << node
44
+ node
45
+ end
46
+
47
+ # Add an edge to the flowchart
48
+ #
49
+ # @param edge [Tasker::Diagram::Edge] The edge to add
50
+ # @return [Tasker::Diagram::Edge] The added edge
51
+ def add_edge(edge)
52
+ @edges << edge
53
+ edge
54
+ end
55
+
56
+ # Find a node by its ID
57
+ #
58
+ # @param id [String] The ID of the node to find
59
+ # @return [Tasker::Diagram::Node, nil] The node with the given ID, or nil if not found
60
+ def find_node(id)
61
+ @nodes.find { |node| node.id == id }
62
+ end
63
+
64
+ # Find all edges connected to a node
65
+ #
66
+ # @param node_id [String] The ID of the node
67
+ # @param direction [Symbol] :outgoing, :incoming, or :both (default: :both)
68
+ # @return [Array<Tasker::Diagram::Edge>] The edges connected to the node
69
+ def find_edges_for_node(node_id, direction = :both)
70
+ case direction
71
+ when :outgoing
72
+ @edges.select { |edge| edge.source_id == node_id }
73
+ when :incoming
74
+ @edges.select { |edge| edge.target_id == node_id }
75
+ else
76
+ @edges.select { |edge| edge.source_id == node_id || edge.target_id == node_id }
77
+ end
78
+ end
79
+
80
+ # Convert the flowchart to a hash representation
81
+ #
82
+ # @return [Hash] Hash representation of the flowchart
83
+ def to_h
84
+ {
85
+ nodes: nodes.map(&:to_h),
86
+ edges: edges.map(&:to_h),
87
+ direction: direction,
88
+ title: title,
89
+ attributes: attributes
90
+ }.compact
91
+ end
92
+
93
+ # Convert the flowchart to a JSON string
94
+ #
95
+ # @return [String] JSON representation of the flowchart
96
+ def to_json(*)
97
+ to_h.to_json(*)
98
+ end
99
+
100
+ # Generate Mermaid diagram syntax for this flowchart
101
+ #
102
+ # @return [String] Mermaid syntax for the flowchart
103
+ def to_mermaid
104
+ lines = []
105
+
106
+ # Add the flowchart definition
107
+ lines << "graph #{direction}"
108
+
109
+ # Use a subgraph with title if title is present
110
+ if title
111
+ lines << "subgraph \"#{title}\""
112
+ indent = ' '
113
+ else
114
+ indent = ''
115
+ end
116
+
117
+ # Add all nodes
118
+ nodes.each do |node|
119
+ node.to_mermaid.each do |line|
120
+ lines << "#{indent}#{line}"
121
+ end
122
+ end
123
+
124
+ # Add all edges
125
+ edges.each do |edge|
126
+ lines << "#{indent}#{edge.to_mermaid}"
127
+ end
128
+
129
+ # Close the subgraph if we have a title
130
+ lines << 'end' if title
131
+
132
+ # Join all lines with newlines
133
+ lines.join("\n")
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ module Diagram
5
+ # Represents a node in a flowchart diagram
6
+ class Node
7
+ # @return [String] The unique identifier for this node
8
+ attr_accessor :id
9
+
10
+ # @return [String] The display label for this node
11
+ attr_accessor :label
12
+
13
+ # @return [String] The shape of the node (e.g., 'box', 'circle', 'diamond')
14
+ attr_accessor :shape
15
+
16
+ # @return [String] CSS styling for the node
17
+ attr_accessor :style
18
+
19
+ # @return [String, nil] URL to link to when clicking the node
20
+ attr_accessor :url
21
+
22
+ # @return [Hash] Additional attributes for the node
23
+ attr_accessor :attributes
24
+
25
+ # Creates a new diagram node
26
+ #
27
+ # @param id [String] The unique identifier for this node
28
+ # @param label [String] The display label for this node
29
+ # @param shape [String] The shape of the node (default: 'box')
30
+ # @param style [String, nil] CSS styling for the node
31
+ # @param url [String, nil] URL to link to when clicking the node
32
+ # @param attributes [Hash] Additional attributes for the node
33
+ # @return [Node] A new diagram node
34
+ def initialize(id:, label:, shape: 'box', style: nil, url: nil, attributes: {})
35
+ @id = id
36
+ @label = label
37
+ @shape = shape
38
+ @style = style
39
+ @url = url
40
+ @attributes = attributes
41
+ end
42
+
43
+ # Convert the node to a hash representation
44
+ #
45
+ # @return [Hash] Hash representation of the node
46
+ def to_h
47
+ {
48
+ id: id,
49
+ label: label,
50
+ shape: shape,
51
+ style: style,
52
+ url: url,
53
+ attributes: attributes
54
+ }.compact
55
+ end
56
+
57
+ # Convert the node to a JSON string
58
+ #
59
+ # @return [String] JSON representation of the node
60
+ def to_json(*)
61
+ to_h.to_json(*)
62
+ end
63
+
64
+ # Generate Mermaid diagram syntax for this node
65
+ #
66
+ # @return [Array<String>] Array of Mermaid syntax lines for the node
67
+ def to_mermaid
68
+ # Use HTML line breaks in the label
69
+ formatted_label = escape_mermaid_text(label).gsub("\n", '<br/>')
70
+
71
+ # Basic node definition
72
+ node_def = "#{id}[\"#{formatted_label}\"]"
73
+
74
+ # Add URL link if present
75
+ click_def = url ? "click #{id} \"#{escape_mermaid_text(url)}\"" : nil
76
+
77
+ # Add style definition if present
78
+ style_def = style ? "style #{id} #{style}" : nil
79
+
80
+ # Return node definition and optional click and style definitions
81
+ [node_def, click_def, style_def].compact
82
+ end
83
+
84
+ private
85
+
86
+ # Escape special characters in Mermaid text
87
+ #
88
+ # @param text [String] The text to escape
89
+ # @return [String] Escaped text safe for Mermaid diagrams
90
+ def escape_mermaid_text(text)
91
+ # Handle nil values
92
+ return '' if text.nil?
93
+
94
+ # Replace instances of " with ' to avoid breaking the Mermaid syntax
95
+ text.to_s.tr('"', "'")
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,41 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: named_steps
7
+ #
8
+ # description :string(255)
9
+ # name :string(128) not null
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ # dependent_system_id :integer not null
13
+ # named_step_id :integer not null, primary key
14
+ #
15
+ # Indexes
16
+ #
17
+ # named_step_by_system_uniq (dependent_system_id,name) UNIQUE
18
+ # named_steps_dependent_system_id_index (dependent_system_id)
19
+ # named_steps_name_index (name)
20
+ #
21
+ # Foreign Keys
22
+ #
23
+ # named_steps_dependent_system_id_foreign (dependent_system_id => dependent_systems.dependent_system_id)
24
+ #
25
+ module Tasker
26
+ class NamedStep < ApplicationRecord
27
+ self.primary_key = :named_step_id
28
+ belongs_to :dependent_system
29
+ has_many :workflow_steps, dependent: :nullify
30
+ validates :name, presence: true, uniqueness: { scope: :dependent_system_id }
31
+
32
+ def self.create_named_steps_from_templates(templates)
33
+ templates.map do |template|
34
+ dependent_system = Tasker::DependentSystem.find_or_create_by!(name: template.dependent_system)
35
+ named_step = NamedStep.find_or_create_by!(name: template.name,
36
+ dependent_system_id: dependent_system.dependent_system_id)
37
+ named_step
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,121 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: tasker_named_tasks
7
+ #
8
+ # description :string(255)
9
+ # name :string(64) not null
10
+ # version :string(16) not null
11
+ # configuration :jsonb
12
+ # created_at :datetime not null
13
+ # updated_at :datetime not null
14
+ # named_task_id :integer not null, primary key
15
+ # task_namespace_id :integer not null
16
+ #
17
+ # Indexes
18
+ #
19
+ # named_tasks_name_index (name)
20
+ # named_tasks_namespace_name_version_unique (task_namespace_id,name,version) UNIQUE
21
+ # named_tasks_task_namespace_id_index (task_namespace_id)
22
+ # named_tasks_version_index (version)
23
+ # named_tasks_configuration_gin_index (configuration) USING gin
24
+ #
25
+ # Foreign Keys
26
+ #
27
+ # fk_rails_... (task_namespace_id => tasker_task_namespaces.task_namespace_id)
28
+ #
29
+ module Tasker
30
+ class NamedTask < ApplicationRecord
31
+ self.primary_key = :named_task_id
32
+
33
+ belongs_to :task_namespace
34
+ has_many :tasks, dependent: :nullify
35
+
36
+ validates :name, presence: true, length: { maximum: 64 }
37
+ validates :version, presence: true, format: {
38
+ with: /\A\d+\.\d+\.\d+\z/,
39
+ message: 'must be in semver format (e.g., 1.0.0)'
40
+ }, length: { maximum: 16 }
41
+ validates :task_namespace_id, uniqueness: { scope: %i[name version] }
42
+
43
+ # Default version for new tasks
44
+ DEFAULT_VERSION = '0.1.0'
45
+
46
+ # Default namespace name
47
+ DEFAULT_NAMESPACE = 'default'
48
+
49
+ # Find or create with namespace and version support
50
+ def self.find_or_create_by_full_name!(name:, namespace_name: DEFAULT_NAMESPACE, version: DEFAULT_VERSION)
51
+ namespace = TaskNamespace.find_or_create_by!(name: namespace_name)
52
+ find_or_create_by!(
53
+ task_namespace: namespace,
54
+ name: name,
55
+ version: version
56
+ )
57
+ end
58
+
59
+ # Full qualified name: namespace.name@version
60
+ def full_name
61
+ "#{task_namespace.name}.#{name}@#{version}"
62
+ end
63
+
64
+ # Short name without version: namespace.name
65
+ def qualified_name
66
+ "#{task_namespace.name}.#{name}"
67
+ end
68
+
69
+ # Configuration accessor with defaults
70
+ def config
71
+ @config ||= (configuration || {}).with_indifferent_access
72
+ end
73
+
74
+ # Get concurrency setting from configuration
75
+ def concurrent?
76
+ config.fetch('concurrent', true)
77
+ end
78
+
79
+ # Update configuration
80
+ def update_config!(new_config)
81
+ self.configuration = (config || {}).deep_merge(new_config)
82
+ save!
83
+ @config = nil # Clear memoized config
84
+ end
85
+
86
+ # Check if this uses the default namespace
87
+ def default_namespace?
88
+ task_namespace.default?
89
+ end
90
+
91
+ def namespace_name
92
+ task_namespace.name
93
+ end
94
+
95
+ # Scope methods for common queries
96
+ scope :in_namespace, lambda { |namespace|
97
+ joins(:task_namespace).where(task_namespace: { name: namespace })
98
+ }
99
+
100
+ scope :with_version, ->(version) { where(version: version) }
101
+
102
+ scope :latest_versions, lambda {
103
+ select('DISTINCT ON (task_namespace_id, name) *')
104
+ .order(:task_namespace_id, :name, version: :desc)
105
+ }
106
+
107
+ # Find latest version of a named task in a namespace
108
+ def self.find_latest_version(namespace_name, task_name)
109
+ in_namespace(namespace_name)
110
+ .where(name: task_name)
111
+ .order(version: :desc)
112
+ .first
113
+ end
114
+
115
+ # Check if a specific version exists
116
+ def self.version_exists?(namespace_name, task_name, version)
117
+ in_namespace(namespace_name)
118
+ .exists?(name: task_name, version: version)
119
+ end
120
+ end
121
+ end