tasker-engine 0.1.0 → 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.
Potentially problematic release.
This version of tasker-engine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +12 -9
- data/app/controllers/tasker/analytics_controller.rb +2 -2
- data/app/controllers/tasker/graphql_controller.rb +3 -3
- data/app/controllers/tasker/health_controller.rb +1 -1
- data/app/controllers/tasker/metrics_controller.rb +3 -3
- data/app/controllers/tasker/task_diagrams_controller.rb +30 -0
- data/app/jobs/tasker/metrics_export_job.rb +1 -1
- data/app/models/tasker/application_record.rb +5 -5
- data/app/models/tasker/diagram/edge.rb +106 -0
- data/app/models/tasker/diagram/flowchart.rb +137 -0
- data/app/models/tasker/diagram/node.rb +99 -0
- data/app/models/tasker/task.rb +11 -1
- data/app/models/tasker/task_diagram.rb +332 -0
- data/app/models/tasker/workflow_step_edge.rb +4 -5
- data/app/views/tasker/task/_diagram.html.erb +32 -0
- data/config/routes.rb +3 -3
- data/db/init/schema.sql +23 -0
- data/docs/APPLICATION_GENERATOR.md +1 -1
- data/docs/AUTH.md +51 -12
- data/docs/DEVELOPER_GUIDE.md +9 -8
- data/docs/EXECUTION_CONFIGURATION.md +1 -1
- data/docs/HEALTH.md +3 -3
- data/docs/METRICS.md +4 -4
- data/docs/OPTIMIZATION_PLAN.md +3 -3
- data/docs/OVERVIEW.md +4 -0
- data/docs/QUICK_START.md +1 -1
- data/docs/REST_API.md +1 -1
- data/docs/TASK_DIAGRAM.md +252 -0
- data/docs/TELEMETRY.md +5 -5
- data/docs/TROUBLESHOOTING.md +3 -3
- data/docs/TaskHandlerGenerator.html +55 -55
- data/docs/Tasker/Analysis/RuntimeGraphAnalyzer.html +1 -1
- data/docs/Tasker/Analysis/TemplateGraphAnalyzer.html +1 -1
- data/docs/Tasker/Analysis.html +1 -1
- data/docs/Tasker/AnalyticsController.html +1 -1
- data/docs/Tasker/AnalyticsService/BottleneckAnalytics.html +1 -1
- data/docs/Tasker/AnalyticsService/PerformanceAnalytics.html +1 -1
- data/docs/Tasker/AnalyticsService.html +1 -1
- data/docs/Tasker/AnnotationType.html +1 -1
- data/docs/Tasker/AnnotationTypeSerializer.html +1 -1
- data/docs/Tasker/ApplicationController.html +2 -2
- data/docs/Tasker/ApplicationJob.html +1 -1
- data/docs/Tasker/ApplicationRecord.html +6 -6
- data/docs/Tasker/Authentication/AuthenticationError.html +1 -1
- data/docs/Tasker/Authentication/ConfigurationError.html +1 -1
- data/docs/Tasker/Authentication/Coordinator.html +1 -1
- data/docs/Tasker/Authentication/Interface.html +1 -1
- data/docs/Tasker/Authentication/InterfaceError.html +1 -1
- data/docs/Tasker/Authentication/NoneAuthenticator.html +1 -1
- data/docs/Tasker/Authentication.html +1 -1
- data/docs/Tasker/Authorization/AuthorizationError.html +1 -1
- data/docs/Tasker/Authorization/BaseCoordinator.html +2 -2
- data/docs/Tasker/Authorization/ConfigurationError.html +1 -1
- data/docs/Tasker/Authorization/ResourceConstants/ACTIONS.html +10 -10
- data/docs/Tasker/Authorization/ResourceConstants/RESOURCES.html +13 -8
- data/docs/Tasker/Authorization/ResourceConstants.html +1 -1
- data/docs/Tasker/Authorization/ResourceRegistry.html +40 -33
- data/docs/Tasker/Authorization/UnauthorizedError.html +1 -1
- data/docs/Tasker/Authorization.html +2 -2
- data/docs/Tasker/CacheCapabilities.html +1 -1
- data/docs/Tasker/CacheStrategy.html +1 -1
- data/docs/Tasker/Concerns/Authenticatable.html +1 -1
- data/docs/Tasker/Concerns/Authorizable/AdminStatusChecker.html +1 -1
- data/docs/Tasker/Concerns/Authorizable.html +1 -1
- data/docs/Tasker/Concerns/ControllerAuthorizable.html +1 -1
- data/docs/Tasker/Concerns/EventPublisher.html +1 -1
- data/docs/Tasker/Concerns/IdempotentStateTransitions.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/ClassMethods.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase/ClassMethods.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase.html +1 -1
- data/docs/Tasker/Concerns/StructuredLogging.html +1 -1
- data/docs/Tasker/Concerns.html +1 -1
- data/docs/Tasker/Configuration/ConfigurationProxy.html +1 -1
- data/docs/Tasker/Configuration/TelemetryConfigurationProxy.html +1 -1
- data/docs/Tasker/Configuration.html +1 -1
- data/docs/Tasker/ConfigurationError.html +1 -1
- data/docs/Tasker/ConfiguredTask.html +2 -2
- data/docs/Tasker/Constants/EventDefinitions.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents/Step.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents/Task.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents.html +1 -1
- data/docs/Tasker/Constants/RegistryEvents.html +1 -1
- data/docs/Tasker/Constants/StepEvents.html +1 -1
- data/docs/Tasker/Constants/TaskEvents.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/ExecutionStatus.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/HealthStatus.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/RecommendedAction.html +1 -1
- data/docs/Tasker/Constants/TaskExecution.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/ErrorMessages.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/PendingReasons.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/ReenqueueReasons.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization.html +1 -1
- data/docs/Tasker/Constants/TaskStatuses.html +1 -1
- data/docs/Tasker/Constants/TestEvents.html +1 -1
- data/docs/Tasker/Constants/WorkflowEvents.html +1 -1
- data/docs/Tasker/Constants/WorkflowStepStatuses.html +1 -1
- data/docs/Tasker/Constants.html +1 -1
- data/docs/Tasker/DependentSystem.html +1 -1
- data/docs/Tasker/DependentSystemObjectMap.html +1 -1
- data/docs/Tasker/DetectorRegistry.html +1 -1
- data/docs/Tasker/Diagram/Edge.html +1 -1
- data/docs/Tasker/Diagram/Flowchart.html +1 -1
- data/docs/Tasker/Diagram/Node.html +1 -1
- data/docs/Tasker/Diagram.html +1 -1
- data/docs/Tasker/Engine.html +1 -1
- data/docs/Tasker/Error.html +1 -1
- data/docs/Tasker/Events/Catalog/CatalogPrinter.html +1 -1
- data/docs/Tasker/Events/Catalog/CustomEventRegistrar.html +1 -1
- data/docs/Tasker/Events/Catalog/ExamplePayloadGenerator.html +1 -1
- data/docs/Tasker/Events/Catalog.html +1 -1
- data/docs/Tasker/Events/CustomRegistry.html +1 -1
- data/docs/Tasker/Events/DefinitionLoader.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder/ErrorInfoExtractor.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder/StepPayloadBuilder.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder.html +1 -1
- data/docs/Tasker/Events/Publisher.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer/ErrorTypeClassifier.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/MetricTagsExtractor.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber.html +1 -1
- data/docs/Tasker/Events/Subscribers/MetricsSubscriber.html +2 -2
- data/docs/Tasker/Events/Subscribers/TelemetrySubscriber.html +5 -5
- data/docs/Tasker/Events/Subscribers.html +1 -1
- data/docs/Tasker/Events/SubscriptionLoader.html +1 -1
- data/docs/Tasker/Events.html +1 -1
- data/docs/Tasker/EventsGenerator.html +2 -2
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics/AnalyticsMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedDependencyLevels.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps/SlowestStep.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks/SlowestTask.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedStepReadinessStatus.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts/HealthMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedTaskExecutionContext.html +1 -1
- data/docs/Tasker/Functions/FunctionWrapper.html +1 -1
- data/docs/Tasker/Functions.html +1 -1
- data/docs/Tasker/Generators/AuthenticatorGenerator/UsageInstructionsFormatter.html +1 -1
- data/docs/Tasker/Generators/AuthenticatorGenerator.html +1 -1
- data/docs/Tasker/Generators/AuthorizationCoordinatorGenerator.html +1 -1
- data/docs/Tasker/Generators/SubscriberGenerator.html +1 -1
- data/docs/Tasker/Generators/TaskHandlerGenerator.html +4 -4
- data/docs/Tasker/Generators.html +1 -1
- data/docs/Tasker/GraphQLTypes/AnnotationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseArgument.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseConnection.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseEdge.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseEnum.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseField.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseInputObject.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseInterface.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseObject.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseScalar.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseUnion.html +1 -1
- data/docs/Tasker/GraphQLTypes/DependentSystemObjectMapType.html +1 -1
- data/docs/Tasker/GraphQLTypes/DependentSystemType.html +1 -1
- data/docs/Tasker/GraphQLTypes/MutationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedTaskType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedTasksNamedStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NodeType.html +1 -1
- data/docs/Tasker/GraphQLTypes/QueryType.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskAnnotationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskInterface.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskType.html +1 -1
- data/docs/Tasker/GraphQLTypes/WorkflowStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes.html +1 -1
- data/docs/Tasker/GraphqlController.html +1 -1
- data/docs/Tasker/HandlerFactory.html +44 -54
- data/docs/Tasker/HandlerSerializer.html +1 -1
- data/docs/Tasker/HandlersController.html +1 -1
- data/docs/Tasker/HashIdentityStrategy.html +1 -1
- data/docs/Tasker/Health/ReadinessChecker.html +2 -2
- data/docs/Tasker/Health/StatusChecker.html +2 -2
- data/docs/Tasker/Health.html +1 -1
- data/docs/Tasker/HealthController.html +1 -1
- data/docs/Tasker/IdentityStrategy.html +1 -1
- data/docs/Tasker/InvalidTaskHandlerConfig.html +1 -1
- data/docs/Tasker/Logging/CorrelationIdGenerator.html +2 -2
- data/docs/Tasker/Logging.html +1 -1
- data/docs/Tasker/MetricsController.html +1 -1
- data/docs/Tasker/MetricsExportJob.html +1 -1
- data/docs/Tasker/Mutations/BaseMutation.html +1 -1
- data/docs/Tasker/Mutations/CancelStep.html +1 -1
- data/docs/Tasker/Mutations/CancelTask.html +1 -1
- data/docs/Tasker/Mutations/CreateTask.html +1 -1
- data/docs/Tasker/Mutations/UpdateStep.html +1 -1
- data/docs/Tasker/Mutations/UpdateTask.html +1 -1
- data/docs/Tasker/Mutations.html +1 -1
- data/docs/Tasker/NamedStep.html +1 -1
- data/docs/Tasker/NamedTask.html +1 -1
- data/docs/Tasker/NamedTasksNamedStep.html +1 -1
- data/docs/Tasker/Orchestration/BackoffCalculator.html +1 -1
- data/docs/Tasker/Orchestration/ConnectionBuilder/ConfigValidator.html +1 -1
- data/docs/Tasker/Orchestration/ConnectionBuilder.html +2 -2
- data/docs/Tasker/Orchestration/ConnectionPoolIntelligence.html +3 -3
- data/docs/Tasker/Orchestration/Coordinator.html +1 -1
- data/docs/Tasker/Orchestration/FutureStateAnalyzer.html +1 -1
- data/docs/Tasker/Orchestration/PluginIntegration.html +1 -1
- data/docs/Tasker/Orchestration/ResponseProcessor.html +1 -1
- data/docs/Tasker/Orchestration/RetryHeaderParser.html +1 -1
- data/docs/Tasker/Orchestration/StepExecutor.html +4 -4
- data/docs/Tasker/Orchestration/StepSequenceFactory.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/BlockageChecker.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ContextManager.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/DelayCalculator.html +2 -2
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationDecisionMaker.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationProcessor.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ReasonDeterminer.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ReenqueueManager.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/UnclearStateHandler.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer.html +1 -1
- data/docs/Tasker/Orchestration/TaskInitializer.html +1 -1
- data/docs/Tasker/Orchestration/TaskReenqueuer.html +1 -1
- data/docs/Tasker/Orchestration/ViableStepDiscovery.html +1 -1
- data/docs/Tasker/Orchestration/WorkflowCoordinator.html +1 -1
- data/docs/Tasker/Orchestration.html +1 -1
- data/docs/Tasker/PageSort/PageSortParamsBuilder.html +1 -1
- data/docs/Tasker/PageSort.html +1 -1
- data/docs/Tasker/PermanentError.html +1 -1
- data/docs/Tasker/ProceduralError.html +1 -1
- data/docs/Tasker/Queries/AllAnnotationTypes.html +1 -1
- data/docs/Tasker/Queries/AllTasks.html +1 -1
- data/docs/Tasker/Queries/BaseQuery.html +1 -1
- data/docs/Tasker/Queries/Helpers.html +1 -1
- data/docs/Tasker/Queries/OneStep.html +1 -1
- data/docs/Tasker/Queries/OneTask.html +1 -1
- data/docs/Tasker/Queries/TasksByAnnotation.html +1 -1
- data/docs/Tasker/Queries/TasksByStatus.html +1 -1
- data/docs/Tasker/Queries.html +1 -1
- data/docs/Tasker/Railtie.html +1 -1
- data/docs/Tasker/Registry/BaseRegistry.html +2 -2
- data/docs/Tasker/Registry/EventPublisher.html +1 -1
- data/docs/Tasker/Registry/InterfaceValidator.html +1 -1
- data/docs/Tasker/Registry/RegistrationError.html +1 -1
- data/docs/Tasker/Registry/RegistryError.html +1 -1
- data/docs/Tasker/Registry/StatisticsCollector.html +1 -1
- data/docs/Tasker/Registry/SubscriberRegistry.html +1 -1
- data/docs/Tasker/Registry/ValidationError.html +1 -1
- data/docs/Tasker/Registry.html +1 -1
- data/docs/Tasker/RetryableError.html +1 -1
- data/docs/Tasker/StateMachine/Compatibility.html +1 -1
- data/docs/Tasker/StateMachine/InvalidStateTransition.html +1 -1
- data/docs/Tasker/StateMachine/StepStateMachine.html +1 -1
- data/docs/Tasker/StateMachine/TaskStateMachine.html +1 -1
- data/docs/Tasker/StateMachine.html +1 -1
- data/docs/Tasker/StepDagRelationship.html +1 -1
- data/docs/Tasker/StepHandler/Api/Config.html +1 -1
- data/docs/Tasker/StepHandler/Api.html +1 -1
- data/docs/Tasker/StepHandler/AutomaticEventPublishing.html +1 -1
- data/docs/Tasker/StepHandler/Base.html +1 -1
- data/docs/Tasker/StepHandler.html +1 -1
- data/docs/Tasker/StepReadinessStatus.html +1 -1
- data/docs/Tasker/Task.html +210 -113
- data/docs/Tasker/TaskAnnotation.html +1 -1
- data/docs/Tasker/TaskAnnotationSerializer.html +1 -1
- data/docs/Tasker/TaskBuilder/StepNameValidator.html +1 -1
- data/docs/Tasker/TaskBuilder/StepTemplateDefiner.html +1 -1
- data/docs/Tasker/TaskBuilder.html +1 -1
- data/docs/Tasker/TaskDiagram/StepToStepEdgeBuilder.html +1 -1
- data/docs/Tasker/TaskDiagram/TaskToRootStepEdgeBuilder.html +1 -1
- data/docs/Tasker/TaskDiagram.html +1 -1
- data/docs/Tasker/TaskDiagramsController.html +1 -1
- data/docs/Tasker/TaskExecutionContext.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/ClassBasedEventRegistrar.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/YamlEventRegistrar.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods.html +6 -44
- data/docs/Tasker/TaskHandler/InstanceMethods.html +1 -1
- data/docs/Tasker/TaskHandler/StepGroup.html +1 -1
- data/docs/Tasker/TaskHandler.html +1 -1
- data/docs/Tasker/TaskNamespace.html +1 -1
- data/docs/Tasker/TaskRunnerJob.html +1 -1
- data/docs/Tasker/TaskSerializer.html +1 -1
- data/docs/Tasker/TaskTransition.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/InvalidObjectTypeError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/TypeResolutionError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/UnknownInterfaceError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema.html +1 -1
- data/docs/Tasker/TasksController.html +1 -1
- data/docs/Tasker/Telemetry/EventMapping.html +1 -1
- data/docs/Tasker/Telemetry/EventRouter.html +1 -1
- data/docs/Tasker/Telemetry/Events/ExportEvents.html +1 -1
- data/docs/Tasker/Telemetry/Events.html +1 -1
- data/docs/Tasker/Telemetry/ExportCoordinator.html +1 -1
- data/docs/Tasker/Telemetry/IntelligentCacheManager.html +2 -2
- data/docs/Tasker/Telemetry/LogBackend.html +1 -1
- data/docs/Tasker/Telemetry/MetricTypes/Counter.html +2 -2
- data/docs/Tasker/Telemetry/MetricTypes/Gauge.html +73 -73
- data/docs/Tasker/Telemetry/MetricTypes/Histogram.html +103 -103
- data/docs/Tasker/Telemetry/MetricTypes.html +1 -1
- data/docs/Tasker/Telemetry/MetricsBackend.html +1 -1
- data/docs/Tasker/Telemetry/MetricsExportService.html +1 -1
- data/docs/Tasker/Telemetry/PluginRegistry.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/BaseExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/CsvExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/JsonExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins.html +1 -1
- data/docs/Tasker/Telemetry/PrometheusExporter.html +1 -1
- data/docs/Tasker/Telemetry/TraceBackend.html +1 -1
- data/docs/Tasker/Telemetry.html +1 -1
- data/docs/Tasker/Types/AuthConfig.html +1 -1
- data/docs/Tasker/Types/BackoffConfig.html +1 -1
- data/docs/Tasker/Types/BaseConfig.html +1 -1
- data/docs/Tasker/Types/CacheConfig.html +1 -1
- data/docs/Tasker/Types/DatabaseConfig.html +1 -1
- data/docs/Tasker/Types/DependencyGraph.html +1 -1
- data/docs/Tasker/Types/DependencyGraphConfig.html +1 -1
- data/docs/Tasker/Types/EngineConfig.html +1 -1
- data/docs/Tasker/Types/ExecutionConfig.html +1 -1
- data/docs/Tasker/Types/GraphEdge.html +1 -1
- data/docs/Tasker/Types/GraphMetadata.html +1 -1
- data/docs/Tasker/Types/GraphNode.html +1 -1
- data/docs/Tasker/Types/HealthConfig.html +1 -1
- data/docs/Tasker/Types/StepSequence.html +1 -1
- data/docs/Tasker/Types/StepTemplate.html +1 -1
- data/docs/Tasker/Types/TaskRequest.html +1 -1
- data/docs/Tasker/Types/TelemetryConfig.html +2 -2
- data/docs/Tasker/Types.html +1 -1
- data/docs/Tasker/WorkflowStep/StepFinder.html +1 -1
- data/docs/Tasker/WorkflowStep.html +1 -1
- data/docs/Tasker/WorkflowStepEdge.html +4 -6
- data/docs/Tasker/WorkflowStepSerializer.html +1 -1
- data/docs/Tasker/WorkflowStepTransition/TransitionDescriptionFormatter.html +1 -1
- data/docs/Tasker/WorkflowStepTransition.html +1 -1
- data/docs/Tasker/WorkflowStepsController.html +1 -1
- data/docs/Tasker.html +5 -21
- data/docs/VISION.md +1 -1
- data/docs/_index.html +77 -21
- data/docs/class_list.html +1 -1
- data/docs/file.README.html +14 -10
- data/docs/index.html +14 -10
- data/docs/method_list.html +1433 -1105
- data/docs/top-level-namespace.html +1 -1
- data/lib/generators/tasker/authenticator_generator.rb +5 -5
- data/lib/generators/tasker/authorization_coordinator_generator.rb +1 -1
- data/lib/generators/tasker/events_generator.rb +1 -1
- data/lib/generators/tasker/task_handler_generator.rb +4 -4
- data/lib/generators/tasker/templates/api_token_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/authorization_coordinator.rb.erb +13 -0
- data/lib/generators/tasker/templates/authorization_coordinator_spec.rb.erb +7 -1
- data/lib/generators/tasker/templates/custom_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/devise_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/initialize.rb.erb +1 -1
- data/lib/generators/tasker/templates/jwt_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/omniauth_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/opentelemetry_initializer.rb +4 -4
- data/lib/generators/tasker/templates/task_config.yaml.erb +25 -25
- data/lib/generators/tasker/templates/task_handler.rb.erb +2 -3
- data/lib/generators/tasker/templates/task_handler_spec.rb.erb +43 -49
- data/lib/tasker/analysis/runtime_graph_analyzer.rb +1 -1
- data/lib/tasker/authentication/coordinator.rb +2 -2
- data/lib/tasker/authorization/base_coordinator.rb +1 -1
- data/lib/tasker/authorization/resource_constants.rb +2 -1
- data/lib/tasker/authorization/resource_registry.rb +7 -0
- data/lib/tasker/authorization.rb +1 -1
- data/lib/tasker/concerns/authenticatable.rb +1 -1
- data/lib/tasker/concerns/controller_authorizable.rb +3 -3
- data/lib/tasker/concerns/structured_logging.rb +2 -2
- data/lib/tasker/events/definition_loader.rb +1 -1
- data/lib/tasker/events/subscribers/metrics_subscriber.rb +1 -1
- data/lib/tasker/events/subscribers/telemetry_subscriber.rb +5 -5
- data/lib/tasker/handler_factory.rb +2 -7
- data/lib/tasker/health/readiness_checker.rb +1 -1
- data/lib/tasker/health/status_checker.rb +1 -1
- data/lib/tasker/logging/correlation_id_generator.rb +1 -1
- data/lib/tasker/orchestration/backoff_calculator.rb +1 -1
- data/lib/tasker/orchestration/connection_builder.rb +1 -1
- data/lib/tasker/orchestration/connection_pool_intelligence.rb +3 -3
- data/lib/tasker/orchestration/step_executor.rb +2 -2
- data/lib/tasker/orchestration/task_finalizer.rb +1 -1
- data/lib/tasker/registry/base_registry.rb +1 -1
- data/lib/tasker/task_builder.rb +1 -1
- data/lib/tasker/task_handler/class_methods.rb +1 -4
- data/lib/tasker/telemetry/intelligent_cache_manager.rb +1 -1
- data/lib/tasker/telemetry/metric_types.rb +9 -57
- data/lib/tasker/telemetry/metrics_backend.rb +3 -3
- data/lib/tasker/telemetry/metrics_export_service.rb +1 -1
- data/lib/tasker/telemetry/prometheus_exporter.rb +2 -2
- data/lib/tasker/types/telemetry_config.rb +1 -1
- data/lib/tasker/version.rb +1 -2
- data/lib/tasks/tasker_tasks.rake +4 -85
- metadata +11 -7
- data/db/functions/get_step_readiness_status_single_and_batch_v02.sql +0 -223
- data/db/migrate/20250710110830_step_readiness_sql_functions_v02.rb +0 -39
- data/docs/REVERSIONING.md +0 -404
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd2231fa336087118193cb1ed54b98838f396210d88b44ff2eb994ebc12cc12f
|
|
4
|
+
data.tar.gz: 1e0f9172ccac70c3d712cdb038779158eb1edcd9e81e9402a3888a0ba12cb85c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4cf9d080d61f3954b1d06749ee71f1a7508bd10272ca7be10476cfe45880d45048ea986fc5a510233ae9f92f549ba160f0ae93cf16a5e92fd3bcd4282deb69fa
|
|
7
|
+
data.tar.gz: c810d613f87f099bfb948f306fb7fc57e568427a7eb453acf2a0a602d270e31bd0f9e8e438e134f5d60e11ea3e63a7b00dc994ec76f664fa331a061453b0b4dc
|
data/README.md
CHANGED
|
@@ -28,7 +28,9 @@ Perfect for processes that involve multiple interdependent steps, require automa
|
|
|
28
28
|
Add Tasker to your Rails app's `Gemfile`:
|
|
29
29
|
|
|
30
30
|
```ruby
|
|
31
|
-
|
|
31
|
+
source 'https://rubygems.pkg.github.com/tasker-systems' do
|
|
32
|
+
gem 'tasker-engine', '~> 1.0.0'
|
|
33
|
+
end
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
Install and run the migrations:
|
|
@@ -52,7 +54,7 @@ end
|
|
|
52
54
|
bundle exec rails tasker:setup
|
|
53
55
|
```
|
|
54
56
|
|
|
55
|
-
### Option 2: Generate Complete Application
|
|
57
|
+
### Option 2: Generate Complete Application (v2.6.1)
|
|
56
58
|
|
|
57
59
|
Create a production-ready Rails application with Tasker integration in one command:
|
|
58
60
|
|
|
@@ -123,7 +125,7 @@ This creates a complete workflow structure:
|
|
|
123
125
|
---
|
|
124
126
|
name: order_process
|
|
125
127
|
namespace_name: default
|
|
126
|
-
version:
|
|
128
|
+
version: 1.0.0
|
|
127
129
|
task_handler_class: OrderProcess
|
|
128
130
|
|
|
129
131
|
step_templates:
|
|
@@ -169,7 +171,7 @@ end
|
|
|
169
171
|
task_request = Tasker::Types::TaskRequest.new(
|
|
170
172
|
name: 'order_process',
|
|
171
173
|
namespace: 'default', # Optional - defaults to 'default'
|
|
172
|
-
version: '
|
|
174
|
+
version: '1.0.0', # Optional - defaults to '0.1.0'
|
|
173
175
|
context: { order_id: 12345 }
|
|
174
176
|
)
|
|
175
177
|
|
|
@@ -177,7 +179,7 @@ task_request = Tasker::Types::TaskRequest.new(
|
|
|
177
179
|
handler = Tasker::HandlerFactory.instance.get(
|
|
178
180
|
'order_process',
|
|
179
181
|
namespace_name: 'default', # Optional - defaults to 'default'
|
|
180
|
-
version: '
|
|
182
|
+
version: '1.0.0' # Optional - defaults to '0.1.0'
|
|
181
183
|
)
|
|
182
184
|
task = handler.initialize_task!(task_request)
|
|
183
185
|
|
|
@@ -192,7 +194,7 @@ Tasker includes enterprise-grade security that works with any Rails authenticati
|
|
|
192
194
|
|
|
193
195
|
```ruby
|
|
194
196
|
# config/initializers/tasker.rb
|
|
195
|
-
Tasker
|
|
197
|
+
Tasker.configuration do |config|
|
|
196
198
|
config.auth do |auth|
|
|
197
199
|
auth.authentication_enabled = true
|
|
198
200
|
auth.authenticator_class = 'YourAuthenticator'
|
|
@@ -288,11 +290,11 @@ Built-in OpenTelemetry integration provides complete observability:
|
|
|
288
290
|
|
|
289
291
|
```ruby
|
|
290
292
|
# config/initializers/tasker.rb
|
|
291
|
-
Tasker
|
|
293
|
+
Tasker.configuration do |config|
|
|
292
294
|
config.telemetry do |tel|
|
|
293
295
|
tel.enabled = true
|
|
294
296
|
tel.service_name = 'my-app-workflows'
|
|
295
|
-
tel.service_version = '
|
|
297
|
+
tel.service_version = '1.0.0'
|
|
296
298
|
end
|
|
297
299
|
end
|
|
298
300
|
```
|
|
@@ -347,7 +349,7 @@ GET /tasker/health/status
|
|
|
347
349
|
**Optional Authentication & Authorization**:
|
|
348
350
|
```ruby
|
|
349
351
|
# config/initializers/tasker.rb
|
|
350
|
-
Tasker
|
|
352
|
+
Tasker.configuration do |config|
|
|
351
353
|
config.health do |health|
|
|
352
354
|
health.status_requires_authentication = true # Secure detailed status
|
|
353
355
|
end
|
|
@@ -404,6 +406,7 @@ end
|
|
|
404
406
|
### 📚 Additional Resources
|
|
405
407
|
- **[Application Generator](docs/APPLICATION_GENERATOR.md)** - One-line app creation with Docker support and validation
|
|
406
408
|
- **[System Overview](docs/OVERVIEW.md)** - Architecture and configuration
|
|
409
|
+
- **[Task Diagrams](docs/TASK_DIAGRAM.md)** - Visual workflow representation
|
|
407
410
|
- **[Troubleshooting](docs/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
408
411
|
|
|
409
412
|
## Requirements & Dependencies
|
|
@@ -158,7 +158,7 @@ module Tasker
|
|
|
158
158
|
#
|
|
159
159
|
# @return [Boolean] True if authentication should be skipped
|
|
160
160
|
def skip_authentication?
|
|
161
|
-
!Tasker
|
|
161
|
+
!Tasker.configuration.telemetry.metrics_auth_required
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
# Override authorization check for analytics endpoint
|
|
@@ -166,7 +166,7 @@ module Tasker
|
|
|
166
166
|
#
|
|
167
167
|
# @return [Boolean] True if authorization should be skipped
|
|
168
168
|
def skip_authorization?
|
|
169
|
-
!Tasker
|
|
169
|
+
!Tasker.configuration.telemetry.metrics_auth_required
|
|
170
170
|
end
|
|
171
171
|
|
|
172
172
|
# Set appropriate cache control headers for analytics endpoints
|
|
@@ -68,7 +68,7 @@ module Tasker
|
|
|
68
68
|
# Authorization methods for GraphQL operations
|
|
69
69
|
|
|
70
70
|
def authorization_enabled?
|
|
71
|
-
Tasker
|
|
71
|
+
Tasker.configuration.auth.authorization_enabled
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def authorize_graphql_operations!(query_string, operation_name)
|
|
@@ -173,10 +173,10 @@ module Tasker
|
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
def build_authorization_coordinator
|
|
176
|
-
coordinator_class = Tasker
|
|
176
|
+
coordinator_class = Tasker.configuration.auth.authorization_coordinator_class.constantize
|
|
177
177
|
coordinator_class.new(current_tasker_user)
|
|
178
178
|
rescue NameError => e
|
|
179
|
-
coordinator_class_name = Tasker
|
|
179
|
+
coordinator_class_name = Tasker.configuration.auth.authorization_coordinator_class
|
|
180
180
|
raise Tasker::Authorization::ConfigurationError,
|
|
181
181
|
"Authorization coordinator class '#{coordinator_class_name}' not found: #{e.message}"
|
|
182
182
|
end
|
|
@@ -62,7 +62,7 @@ module Tasker
|
|
|
62
62
|
#
|
|
63
63
|
# @return [Boolean] True if authentication should be skipped
|
|
64
64
|
def skip_authentication?
|
|
65
|
-
!Tasker
|
|
65
|
+
!Tasker.configuration.telemetry.metrics_auth_required
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
# Override authorization check for metrics endpoint
|
|
@@ -70,7 +70,7 @@ module Tasker
|
|
|
70
70
|
#
|
|
71
71
|
# @return [Boolean] True if authorization should be skipped
|
|
72
72
|
def skip_authorization?
|
|
73
|
-
!Tasker
|
|
73
|
+
!Tasker.configuration.telemetry.metrics_auth_required
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# Export metrics using PrometheusExporter
|
|
@@ -87,7 +87,7 @@ module Tasker
|
|
|
87
87
|
#
|
|
88
88
|
# @return [Boolean] True if metrics are enabled
|
|
89
89
|
def metrics_enabled?
|
|
90
|
-
Tasker
|
|
90
|
+
Tasker.configuration.telemetry.metrics_enabled
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Response when metrics are disabled
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_dependency 'tasker/application_controller'
|
|
5
|
+
|
|
6
|
+
module Tasker
|
|
7
|
+
class TaskDiagramsController < ApplicationController
|
|
8
|
+
include ActionController::MimeResponds
|
|
9
|
+
|
|
10
|
+
before_action :set_full_task, only: %i[index]
|
|
11
|
+
|
|
12
|
+
# GET /tasks/1/task_diagrams
|
|
13
|
+
def index
|
|
14
|
+
respond_to do |format|
|
|
15
|
+
format.html { render(html: @task.diagram(request.base_url).to_html.html_safe) }
|
|
16
|
+
format.json { render(json: @task.diagram(request.base_url).to_json, status: :ok) }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def set_full_task
|
|
23
|
+
@task = query_base.find(params[:task_id])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def query_base
|
|
27
|
+
Tasker::Task.with_all_associated
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -134,7 +134,7 @@ module Tasker
|
|
|
134
134
|
# @return [Integer] Timeout duration in seconds
|
|
135
135
|
def job_timeout_duration
|
|
136
136
|
prometheus_config = begin
|
|
137
|
-
Tasker
|
|
137
|
+
Tasker.configuration.telemetry.prometheus
|
|
138
138
|
rescue StandardError
|
|
139
139
|
{}
|
|
140
140
|
end
|
|
@@ -9,12 +9,12 @@ module Tasker
|
|
|
9
9
|
# When secondary database is enabled, it connects to a database named 'tasker' in database.yml.
|
|
10
10
|
#
|
|
11
11
|
# @example Basic usage with shared database (default)
|
|
12
|
-
# Tasker
|
|
12
|
+
# Tasker.configuration do |config|
|
|
13
13
|
# config.database.enable_secondary_database = false
|
|
14
14
|
# end
|
|
15
15
|
#
|
|
16
16
|
# @example Using a dedicated Tasker database
|
|
17
|
-
# Tasker
|
|
17
|
+
# Tasker.configuration do |config|
|
|
18
18
|
# config.database.enable_secondary_database = true
|
|
19
19
|
# config.database.name = :tasker
|
|
20
20
|
# end
|
|
@@ -35,13 +35,13 @@ module Tasker
|
|
|
35
35
|
# This follows Rails multi-database conventions but only when database is actually available
|
|
36
36
|
def self.configure_database_connections
|
|
37
37
|
# Ensure Tasker configuration is available - fail fast if not
|
|
38
|
-
unless defined?(
|
|
39
|
-
error_message = 'Tasker
|
|
38
|
+
unless defined?(Tasker.configuration)
|
|
39
|
+
error_message = 'Tasker.configuration is not available. This indicates a Rails initialization order issue. ' \
|
|
40
40
|
'Ensure Tasker is properly initialized before models are loaded.'
|
|
41
41
|
raise StandardError, error_message
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
config =
|
|
44
|
+
config = Tasker.configuration.database
|
|
45
45
|
if config.enable_secondary_database && config.name.present?
|
|
46
46
|
# Check if the database configuration actually exists before calling connects_to
|
|
47
47
|
if database_configuration_exists?(config.name)
|
|
@@ -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
|
data/app/models/tasker/task.rb
CHANGED
|
@@ -64,6 +64,7 @@ module Tasker
|
|
|
64
64
|
validate :unique_identity_hash, on: :create
|
|
65
65
|
|
|
66
66
|
delegate :name, to: :named_task
|
|
67
|
+
delegate :to_mermaid, to: :diagram
|
|
67
68
|
delegate :workflow_summary, to: :task_execution_context
|
|
68
69
|
|
|
69
70
|
# State machine integration
|
|
@@ -300,6 +301,14 @@ module Tasker
|
|
|
300
301
|
workflow_steps.includes(:named_step).where(named_step: { name: name }).first
|
|
301
302
|
end
|
|
302
303
|
|
|
304
|
+
# Gets or creates a diagram representation of this task
|
|
305
|
+
#
|
|
306
|
+
# @param base_url [String, nil] The base URL to use for links in the diagram, defaults to nil
|
|
307
|
+
# @return [Tasker::TaskDiagram] The diagram representation of this task
|
|
308
|
+
def diagram(base_url = nil)
|
|
309
|
+
@diagram ||= Tasker::TaskDiagram.new(self, base_url)
|
|
310
|
+
end
|
|
311
|
+
|
|
303
312
|
def runtime_analyzer
|
|
304
313
|
@runtime_analyzer ||= Tasker::Analysis::RuntimeGraphAnalyzer.new(task: self)
|
|
305
314
|
end
|
|
@@ -326,6 +335,7 @@ module Tasker
|
|
|
326
335
|
def reload
|
|
327
336
|
super
|
|
328
337
|
@task_execution_context = nil
|
|
338
|
+
@diagram = nil
|
|
329
339
|
end
|
|
330
340
|
|
|
331
341
|
delegate :namespace_name, to: :named_task
|
|
@@ -401,7 +411,7 @@ module Tasker
|
|
|
401
411
|
#
|
|
402
412
|
# @return [Object] The identity strategy instance
|
|
403
413
|
def identity_strategy
|
|
404
|
-
@identity_strategy ||= Tasker
|
|
414
|
+
@identity_strategy ||= Tasker.configuration.engine.identity_strategy_instance
|
|
405
415
|
end
|
|
406
416
|
|
|
407
417
|
# Sets the identity hash for this task using the configured identity strategy
|