< Summary

Information
Class: Elsa.UserTasks.Endpoints.UserTaskParticipantLookupApiRequest
Assembly: Elsa.UserTasks
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.UserTasks/Endpoints/UserTaskApiModels.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 4
Coverable lines: 4
Total lines: 155
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Search()100%210%
get_Type()100%210%
get_Cursor()100%210%
get_Limit()100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.UserTasks/Endpoints/UserTaskApiModels.cs

#LineLine coverage
 1using System.Text.Json;
 2using Elsa.UserTasks.Models;
 3using Microsoft.AspNetCore.Http;
 4
 5namespace Elsa.UserTasks.Endpoints;
 6
 7public sealed class ListUserTasksRequest
 8{
 9    /// <summary>One of <c>assigned</c>, <c>available</c>, <c>history</c>, <c>all</c>, or <c>needs-attention</c>.</summa
 10    public string? Scope { get; set; }
 11    public string? Cursor { get; set; }
 12    public int Limit { get; set; } = 50;
 13    public string? Sort { get; set; }
 14    public string? Direction { get; set; }
 15    /// <summary>Repeatable. Unknown values are ignored rather than rejected.</summary>
 16    public string[]? Status { get; set; }
 17    public int? PriorityFrom { get; set; }
 18    public int? PriorityTo { get; set; }
 19    /// <summary>A derived due filter: <c>overdue</c>, <c>today</c>, <c>thisWeek</c>, or <c>noDueDate</c>.</summary>
 20    public string? Due { get; set; }
 21    public DateTimeOffset? From { get; set; }
 22    public DateTimeOffset? To { get; set; }
 23    public string? WorkflowDefinitionId { get; set; }
 24    public string? WorkflowInstanceId { get; set; }
 25    public string? Reference { get; set; }
 26    public string? TaskType { get; set; }
 27    public string? Search { get; set; }
 28    public bool IncludeTotalCount { get; set; }
 29}
 30
 31public sealed record UserTaskListResponse(IReadOnlyCollection<UserTaskSummary> Items, string? NextCursor, int? TotalCoun
 32
 33public class UserTaskMutationApiRequest
 34{
 35    public int ExpectedRevision { get; set; }
 36    /// <summary>Reused verbatim across retries of one user action so a retry is idempotent, never a second command.</su
 37    public string? OperationId { get; set; }
 38    public string? Reason { get; set; }
 39}
 40
 41public sealed class AssignUserTaskApiRequest : UserTaskMutationApiRequest
 42{
 43    public UserTaskParticipantSummary Assignee { get; set; } = null!;
 44}
 45
 46public sealed class ScheduleUserTaskApiRequest : UserTaskMutationApiRequest
 47{
 48    public int? Priority { get; set; }
 49    public DateTimeOffset? DueAt { get; set; }
 50}
 51
 52public sealed class CompleteUserTaskApiRequest
 53{
 54    public int ExpectedRevision { get; set; }
 55    public string OperationId { get; set; } = "";
 56    public string ActionKey { get; set; } = "";
 57    public JsonElement? Data { get; set; }
 58}
 59
 60public sealed class CancelUserTaskApiRequest
 61{
 62    public int ExpectedRevision { get; set; }
 63    public string OperationId { get; set; } = "";
 64    public string Reason { get; set; } = "";
 65}
 66
 67public sealed class RevealUserTaskFieldApiRequest
 68{
 69    public string FieldKey { get; set; } = "";
 70}
 71
 72public sealed record RevealUserTaskFieldResponse(string FieldKey, JsonElement? Value);
 73
 74/// <summary>
 75/// The uniform command envelope. <c>status</c> is <c>completed</c> for a synchronous state change and
 76/// <c>accepted</c> for a terminal command that resumes the workflow asynchronously.
 77/// </summary>
 78public sealed record UserTaskOperationResponse(string OperationId, string Status, int Revision, UserTaskSummary? Task);
 79
 80/// <summary>A safe error body. Codes are stable; messages never carry exception or payload detail.</summary>
 81public sealed record UserTaskErrorResponse(string Code, string Message);
 82
 83public sealed class IssueUserTaskInvitationApiRequest
 84{
 85    public int ExpectedRevision { get; set; }
 86    public string VerifierName { get; set; } = "";
 87    public IReadOnlyCollection<string> AllowedActions { get; set; } = [];
 88    public string? Recipient { get; set; }
 89    public TimeSpan? Lifetime { get; set; }
 90    public string? OperationId { get; set; }
 91}
 92
 93public sealed record UserTaskInvitationListResponse(IReadOnlyCollection<UserTaskInvitationSummary> Items);
 94
 95public sealed class VerifyUserTaskInvitationApiRequest
 96{
 97    public string? Code { get; set; }
 98    public string? State { get; set; }
 99}
 100
 101public sealed record UserTaskGuestSessionResponse(string? SessionCredential, string? TaskId, DateTimeOffset? ExpiresAt);
 102
 103public sealed class UserTaskParticipantLookupApiRequest
 104{
 0105    public string? Search { get; set; }
 0106    public string? Type { get; set; }
 0107    public string? Cursor { get; set; }
 0108    public int Limit { get; set; } = 50;
 109}
 110
 111public sealed record UserTaskParticipantSearchResponse(IReadOnlyCollection<UserTaskParticipantSummary> Items, string? Ne
 112
 113/// <summary>
 114/// Maps the domain's conflict codes onto HTTP semantics and safe copy. Keeping this in one place stops an
 115/// individual endpoint from inventing a status that leaks whether a task exists.
 116/// </summary>
 117internal static class UserTaskErrors
 118{
 119    public static int StatusCodeFor(string code) => code switch
 120    {
 121        // A denied command answers exactly like a missing one. The transport layer already rejected a
 122        // caller without the module permission, so reaching a domain denial means the relationship check
 123        // failed — and answering 403 there would tell an ID-guessing caller that the task exists.
 124        "not-found" or "forbidden" => StatusCodes.Status404NotFound,
 125        "revision-conflict" or "idempotency-conflict" or "terminal" or "transition-in-progress" or "not-claimable" => St
 126        "invalid-action" or "reserved-action" or "form-required" or "form-invalid" or "form-resolution-failed"
 127            or "form-provider-missing" or "payload-too-large" or "cancellation-disabled" or "reason-required"
 128            or "invalid-priority" or "excluded-assignee" or "cross-tenant-assignee" or "timeout-not-due" => StatusCodes.
 129        _ => StatusCodes.Status409Conflict
 130    };
 131
 132    public static UserTaskErrorResponse Describe(string code) => new(code, code switch
 133    {
 134        // Same copy for both, so the message cannot re-introduce the distinction the status code hides.
 135        "not-found" or "forbidden" => "This task is no longer available.",
 136        "revision-conflict" => "The task changed since it was loaded. Reload it and try again.",
 137        "idempotency-conflict" => "That operation ID was already used with a different request.",
 138        "terminal" => "This task has already reached a final state.",
 139        "transition-in-progress" => "This task is already finishing. Reload it to see the result.",
 140        "not-claimable" => "This task is no longer available to claim.",
 141        "invalid-action" => "That action is not configured for this task.",
 142        "reserved-action" => "That action is reserved and cannot be selected.",
 143        "form-required" => "This task does not accept a response payload.",
 144        "form-invalid" => "The response did not pass validation.",
 145        "form-resolution-failed" or "form-provider-missing" => "This task's form is unavailable. Ask an operator to retr
 146        "payload-too-large" => "The response is too large.",
 147        "cancellation-disabled" => "Cancellation is not enabled for this task.",
 148        "reason-required" => "A reason is required.",
 149        "invalid-priority" => "Priority must be between 0 and 100.",
 150        "excluded-assignee" => "That participant is excluded from this task.",
 151        "cross-tenant-assignee" => "That participant belongs to a different tenant.",
 152        "timeout-not-due" => "This task is not due for timeout.",
 153        _ => "The request could not be completed."
 154    });
 155}