refactor: extract shared shell reload response models and address review feedback (#7355)

* feat: add specification and quality checklist for Shell Reload API endpoints

* feat: implement Shell Reload API endpoints and associated documentation

* feat: enhance Shell Reload API documentation and add tasks for implementation phases

* feat: implement Shell Reload API features with endpoints, interface contracts, models, and component tests

* feat: update Shell Reload API responses and tests to reflect changes in error handling and response structure

* Fix shell reload follow-up review issues (#7354)

* Initial plan

* Address shell reload review feedback

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

* Dispose shell reload semaphore

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

* Harden shell reload follow-up fixes

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

* Update src/modules/Elsa.Workflows.Api/Endpoints/Shells/Reload/Endpoint.cs

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Potential fix for pull request finding 'Missed opportunity to use Where'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

* Update src/modules/Elsa.Workflows.Api/Endpoints/Shells/Reload/Endpoint.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Initial plan

* Extract shared ShellsResponseModels.cs to eliminate Response/ShellResponse duplication and null! vs default! inconsistency

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

* Merge origin/main - resolve add/add conflicts in shell reload endpoints (fix missing trailing newline)

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot 2026-03-09 09:17:28 +01:00 committed by GitHub
parent 21e982c2c6
commit 794a35dd76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 69 deletions

View file

@ -1,5 +1,6 @@
using Elsa.Abstractions;
using Elsa.Workflows.Api.Contracts;
using Elsa.Workflows.Api.Endpoints.Shells;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Elsa.Workflows;
@ -27,7 +28,7 @@ internal class Reload(IShellReloadOrchestrator shellReloadOrchestrator, IApiSeri
}
var serializerOptions = apiSerializer.GetOptions();
var response = Elsa.Workflows.Api.Endpoints.Shells.Reload.Response.FromResult(result);
var response = ShellReloadResponse.FromResult(result);
var statusCode = result.Status switch
{
ShellReloadStatus.Busy => StatusCodes.Status409Conflict,
@ -39,7 +40,7 @@ internal class Reload(IShellReloadOrchestrator shellReloadOrchestrator, IApiSeri
await SendJsonAsync(response, statusCode, serializerOptions, cancellationToken);
}
private async Task SendJsonAsync(Response response, int statusCode, System.Text.Json.JsonSerializerOptions serializerOptions, CancellationToken cancellationToken)
private async Task SendJsonAsync(ShellReloadResponse response, int statusCode, System.Text.Json.JsonSerializerOptions serializerOptions, CancellationToken cancellationToken)
{
HttpContext.Response.StatusCode = statusCode;
await HttpContext.Response.WriteAsJsonAsync(response, serializerOptions, cancellationToken);

View file

@ -1,33 +1 @@
using Elsa.Workflows.Api.Contracts;
namespace Elsa.Workflows.Api.Endpoints.Shells.Reload;
internal class Response
{
public ShellReloadStatus Status { get; init; }
public string? RequestedShellId { get; init; }
public DateTimeOffset ReloadedAt { get; init; }
public IReadOnlyCollection<ShellResponse> Shells { get; init; } = [];
public static Response FromResult(ShellReloadResult result) => new()
{
Status = result.Status,
RequestedShellId = result.RequestedShellId,
ReloadedAt = result.ReloadedAt,
Shells = result.Shells.Select(x => new ShellResponse
{
ShellId = x.ShellId,
Outcome = x.Outcome,
Requested = x.Requested,
Message = x.Message
}).ToArray()
};
}
internal class ShellResponse
{
public string ShellId { get; init; } = null!;
public ShellReloadItemOutcome Outcome { get; init; }
public bool Requested { get; init; }
public string? Message { get; init; }
}
// Response models for this endpoint are defined in the shared ShellsResponseModels.cs file.

View file

@ -1,5 +1,6 @@
using Elsa.Abstractions;
using Elsa.Workflows.Api.Contracts;
using Elsa.Workflows.Api.Endpoints.Shells;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
@ -17,7 +18,7 @@ internal class ReloadAll(IShellReloadOrchestrator shellReloadOrchestrator) : Els
public override async Task HandleAsync(CancellationToken cancellationToken)
{
var result = await shellReloadOrchestrator.ReloadAllAsync(cancellationToken);
var response = Elsa.Workflows.Api.Endpoints.Shells.ReloadAll.Response.FromResult(result);
var response = ShellReloadResponse.FromResult(result);
switch (result.Status)
{

View file

@ -1,33 +1 @@
using Elsa.Workflows.Api.Contracts;
namespace Elsa.Workflows.Api.Endpoints.Shells.ReloadAll;
internal class Response
{
public ShellReloadStatus Status { get; init; }
public string? RequestedShellId { get; init; }
public DateTimeOffset ReloadedAt { get; init; }
public IReadOnlyCollection<ShellResponse> Shells { get; init; } = [];
public static Response FromResult(ShellReloadResult result) => new()
{
Status = result.Status,
RequestedShellId = result.RequestedShellId,
ReloadedAt = result.ReloadedAt,
Shells = result.Shells.Select(x => new ShellResponse
{
ShellId = x.ShellId,
Outcome = x.Outcome,
Requested = x.Requested,
Message = x.Message
}).ToArray()
};
}
internal class ShellResponse
{
public string ShellId { get; init; } = default!;
public ShellReloadItemOutcome Outcome { get; init; }
public bool Requested { get; init; }
public string? Message { get; init; }
}
// Response models for this endpoint are defined in the shared ShellsResponseModels.cs file.

View file

@ -0,0 +1,33 @@
using Elsa.Workflows.Api.Contracts;
namespace Elsa.Workflows.Api.Endpoints.Shells;
internal class ShellReloadResponse
{
public ShellReloadStatus Status { get; init; }
public string? RequestedShellId { get; init; }
public DateTimeOffset ReloadedAt { get; init; }
public IReadOnlyCollection<ShellReloadItemResponse> Shells { get; init; } = [];
public static ShellReloadResponse FromResult(ShellReloadResult result) => new()
{
Status = result.Status,
RequestedShellId = result.RequestedShellId,
ReloadedAt = result.ReloadedAt,
Shells = result.Shells.Select(x => new ShellReloadItemResponse
{
ShellId = x.ShellId,
Outcome = x.Outcome,
Requested = x.Requested,
Message = x.Message
}).ToArray()
};
}
internal class ShellReloadItemResponse
{
public string ShellId { get; init; } = default!;
public ShellReloadItemOutcome Outcome { get; init; }
public bool Requested { get; init; }
public string? Message { get; init; }
}