diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Contracts/IActivityExecutionsApi.cs b/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Contracts/IActivityExecutionsApi.cs index f7ae99343..2238c8162 100644 --- a/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Contracts/IActivityExecutionsApi.cs +++ b/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Contracts/IActivityExecutionsApi.cs @@ -27,4 +27,22 @@ public interface IActivityExecutionsApi /// The response containing a list of activity executions. [Get("/activity-executions/list")] Task> ListAsync(ListActivityExecutionsRequest request, CancellationToken cancellationToken = default); + + /// + /// Lists activity execution summaries for a given activity in a workflow instance. + /// + /// The request. + /// An optional cancellation token. + /// The response containing a list of activity execution summaries. + [Get("/activity-execution-summaries/list")] + Task> ListSummariesAsync(ListActivityExecutionsRequest request, CancellationToken cancellationToken = default); + + /// + /// Gets a single activity execution by ID. + /// + /// The ID of the activity execution. + /// An optional cancellation token. + /// The activity execution. + [Get("/activity-executions/{id}")] + Task GetAsync(string id, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Models/ActivityExecutionRecordSummary.cs b/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Models/ActivityExecutionRecordSummary.cs new file mode 100644 index 000000000..a224c62de --- /dev/null +++ b/src/clients/Elsa.Api.Client/Resources/ActivityExecutions/Models/ActivityExecutionRecordSummary.cs @@ -0,0 +1,82 @@ +using System.Linq.Expressions; +using Elsa.Api.Client.Resources.WorkflowInstances.Models; +using Elsa.Api.Client.Shared.Models; + +namespace Elsa.Api.Client.Resources.ActivityExecutions.Models; + +/// +/// Represents a summarized view of a single activity execution of an activity instance. +/// +public class ActivityExecutionRecordSummary : Entity +{ + /// + /// Gets or sets the workflow instance ID. + /// + public string WorkflowInstanceId { get; set; } = default!; + + /// + /// Gets or sets the activity ID. + /// + public string ActivityId { get; set; } = default!; + + /// + /// Gets or sets the activity node ID. + /// + public string ActivityNodeId { get; set; } = default!; + + /// + /// The type of the activity. + /// + public string ActivityType { get; set; } = default!; + + /// + /// The version of the activity type. + /// + public int ActivityTypeVersion { get; set; } + + /// + /// The name of the activity. + /// + public string? ActivityName { get; set; } + + /// + /// Gets or sets the time at which the activity execution began. + /// + public DateTimeOffset StartedAt { get; set; } + + /// + /// Gets or sets whether the activity has any bookmarks. + /// + public bool HasBookmarks { get; set; } + + /// + /// Gets or sets the status of the activity. + /// + public ActivityStatus Status { get; set; } + + /// + /// Gets or sets the time at which the activity execution completed. + /// + public DateTimeOffset? CompletedAt { get; set; } + + /// + /// Returns a summary view of the specified . + /// + public static ActivityExecutionRecordSummary FromRecord(ActivityExecutionRecord record) + { + return new ActivityExecutionRecordSummary + { + Id = record.Id, + WorkflowInstanceId = record.WorkflowInstanceId, + ActivityId = record.ActivityId, + ActivityNodeId = record.ActivityNodeId, + ActivityType = record.ActivityType, + ActivityTypeVersion = record.ActivityTypeVersion, + ActivityName = record.ActivityName, + StartedAt = record.StartedAt, + HasBookmarks = record.HasBookmarks, + Status = record.Status, + CompletedAt = record.CompletedAt + }; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Endpoint.cs new file mode 100644 index 000000000..55638298e --- /dev/null +++ b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Endpoint.cs @@ -0,0 +1,38 @@ +using Elsa.Abstractions; +using Elsa.Common.Entities; +using Elsa.Models; +using Elsa.Workflows.Runtime.Contracts; +using Elsa.Workflows.Runtime.Entities; +using Elsa.Workflows.Runtime.Filters; +using Elsa.Workflows.Runtime.OrderDefinitions; +using JetBrains.Annotations; + +namespace Elsa.Workflows.Api.Endpoints.ActivityExecutionSummaries.ListSummaries; + +/// +/// Lists a summary view of the executions for a given activity. +/// +[PublicAPI] +internal class Endpoint(IActivityExecutionStore store) : ElsaEndpoint> +{ + /// + public override void Configure() + { + Get("/activity-execution-summaries/list"); + ConfigurePermissions("read:activity-execution"); + } + + /// + public override async Task> ExecuteAsync(Request request, CancellationToken cancellationToken) + { + var filter = new ActivityExecutionRecordFilter + { + WorkflowInstanceId = request.WorkflowInstanceId, + ActivityNodeId = request.ActivityNodeId, + Completed = request.Completed + }; + var order = new ActivityExecutionRecordOrder(x => x.StartedAt, OrderDirection.Ascending); + var records = (await store.FindManySummariesAsync(filter, order, cancellationToken)).ToList(); + return new ListResponse(records); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Models.cs b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Models.cs new file mode 100644 index 000000000..b90456857 --- /dev/null +++ b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries/ListSummaries/Models.cs @@ -0,0 +1,22 @@ +namespace Elsa.Workflows.Api.Endpoints.ActivityExecutionSummaries.ListSummaries; + +/// +/// A request for a list of activity execution log record summaries for a given activity in a workflow instance. +/// +internal class Request +{ + /// + /// The ID of the workflow instance to get the execution log for. + /// + public string WorkflowInstanceId { get; set; } = default!; + + /// + /// The node ID of the activity to get the execution record for. + /// + public string ActivityNodeId { get; set; } = default!; + + /// + /// Whether to include completed activity execution records. If not specified, all activity execution records will be included. + /// + public bool? Completed { get; set; } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/Get/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/Get/Endpoint.cs new file mode 100644 index 000000000..8828ebb8b --- /dev/null +++ b/src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/Get/Endpoint.cs @@ -0,0 +1,41 @@ +using Elsa.Abstractions; +using Elsa.Workflows.Runtime.Contracts; +using Elsa.Workflows.Runtime.Entities; +using Elsa.Workflows.Runtime.Filters; +using JetBrains.Annotations; + +namespace Elsa.Workflows.Api.Endpoints.ActivityExecutions.Get; + +/// +/// Gets an individual execution for a given activity. +/// +[PublicAPI] +internal class Endpoint(IActivityExecutionStore store) : ElsaEndpointWithoutRequest +{ + /// + public override void Configure() + { + Get("/activity-executions/{id}"); + ConfigurePermissions("read:activity-execution"); + } + + /// + public override async Task HandleAsync(CancellationToken cancellationToken) + { + var id = Route("id"); + var filter = new ActivityExecutionRecordFilter + { + Id = id + }; + + var record = await store.FindAsync(filter, cancellationToken); + + if (record == null) + { + await SendNotFoundAsync(cancellationToken); + return; + } + + await SendOkAsync(record, cancellationToken); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Entities/ActivityExecutionRecordSummary.cs b/src/modules/Elsa.Workflows.Runtime/Entities/ActivityExecutionRecordSummary.cs index ae26ba8fe..9b13941cb 100644 --- a/src/modules/Elsa.Workflows.Runtime/Entities/ActivityExecutionRecordSummary.cs +++ b/src/modules/Elsa.Workflows.Runtime/Entities/ActivityExecutionRecordSummary.cs @@ -42,7 +42,7 @@ public class ActivityExecutionRecordSummary : Entity /// /// Gets or sets the time at which the activity execution began. /// - public DateTimeOffset StartedAt { get; set; } = default!; + public DateTimeOffset StartedAt { get; set; } /// /// Gets or sets whether the activity has any bookmarks. @@ -60,7 +60,7 @@ public class ActivityExecutionRecordSummary : Entity public DateTimeOffset? CompletedAt { get; set; } /// - /// Returns a summary view of the specified . + /// Returns a summary view of the specified . /// public static ActivityExecutionRecordSummary FromRecord(ActivityExecutionRecord record) { @@ -81,7 +81,7 @@ public class ActivityExecutionRecordSummary : Entity } /// - /// Returns a summary view of the specified . + /// Returns a summary view of the specified . /// public static Expression> FromRecordExpression() {