feat(domain): add workflow API core models and meta codes

This commit is contained in:
2026-10-09 23:05:47 +02:00
parent b0fd71e193
commit 986d0aa256
16 changed files with 453 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
namespace DigitalData.TaskFlow.Domain.Closing;
/// <summary>
/// Represents the user decision payload for closing a workflow process.
/// </summary>
public sealed record CloseWorkflowDecision
{
/// <summary>
/// Gets the selected closing method identifier.
/// </summary>
public required int ClosingMethodId { get; init; }
/// <summary>
/// Gets the optional comment attached to the decision.
/// </summary>
public string? Comment { get; init; }
/// <summary>
/// Gets the optional rejection reason identifier.
/// </summary>
public int? RejectionReasonId { get; init; }
}

View File

@@ -0,0 +1,17 @@
namespace DigitalData.TaskFlow.Domain.Closing;
/// <summary>
/// Represents the result of a workflow closing operation.
/// </summary>
public sealed record CloseWorkflowResult
{
/// <summary>
/// Gets the process identifier.
/// </summary>
public required int ProcessId { get; init; }
/// <summary>
/// Gets a value indicating whether the process was closed successfully.
/// </summary>
public required bool IsClosed { get; init; }
}

View File

@@ -0,0 +1,18 @@
namespace DigitalData.TaskFlow.Domain.Common;
/// <summary>
/// Represents the standard API envelope that contains meta information and payload data.
/// </summary>
/// <typeparam name="T">Type of the payload in the response.</typeparam>
public sealed record ApiEnvelope<T>
{
/// <summary>
/// Gets the list of metadata entries describing the business result.
/// </summary>
public required IReadOnlyList<MetaEntry> Meta { get; init; }
/// <summary>
/// Gets the payload data returned by the endpoint.
/// </summary>
public T? Data { get; init; }
}

View File

@@ -0,0 +1,17 @@
namespace DigitalData.TaskFlow.Domain.Common;
/// <summary>
/// Represents a single metadata item describing the business result state of an API response.
/// </summary>
public sealed record MetaEntry
{
/// <summary>
/// Gets the domain-specific result code.
/// </summary>
public required int Code { get; init; }
/// <summary>
/// Gets the human-readable message that belongs to <see cref="Code"/>.
/// </summary>
public required string Message { get; init; }
}

View File

@@ -0,0 +1,27 @@
namespace DigitalData.TaskFlow.Domain.Documents;
/// <summary>
/// Represents binary document content returned by the document endpoint.
/// </summary>
public sealed record DocumentBinaryResult
{
/// <summary>
/// Gets the raw binary content.
/// </summary>
public required byte[] Content { get; init; }
/// <summary>
/// Gets the MIME content type.
/// </summary>
public required string ContentType { get; init; }
/// <summary>
/// Gets the file name used for download.
/// </summary>
public required string FileName { get; init; }
/// <summary>
/// Gets the content length in bytes.
/// </summary>
public required long Length { get; init; }
}

View File

@@ -0,0 +1,42 @@
namespace DigitalData.TaskFlow.Domain.Enums;
/// <summary>
/// Defines domain-level result codes used in API meta responses.
/// </summary>
public enum MetaCode
{
/// <summary>
/// Operation completed successfully.
/// </summary>
Ok = 0,
/// <summary>
/// Request is valid but no open workflows are available.
/// </summary>
NoOpenWorkflows = 1,
/// <summary>
/// Caller has no access to the requested resource.
/// </summary>
NoAccess = 2,
/// <summary>
/// Request is invalid or authentication failed according to endpoint rules.
/// </summary>
InvalidRequest = 4,
/// <summary>
/// Internal server error occurred.
/// </summary>
InternalError = 5,
/// <summary>
/// Requested resource was not found.
/// </summary>
NotFound = 6,
/// <summary>
/// Target workflow was already closed.
/// </summary>
AlreadyClosed = 7
}

View File

@@ -0,0 +1,32 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents a completed approval action for a workflow process.
/// </summary>
public sealed record ApprovalItem
{
/// <summary>
/// Gets the process identifier.
/// </summary>
public required int ProcessId { get; init; }
/// <summary>
/// Gets the approval sequence index.
/// </summary>
public required int Sequence { get; init; }
/// <summary>
/// Gets the user name or identifier of the approver.
/// </summary>
public required string ApprovedBy { get; init; }
/// <summary>
/// Gets the UTC timestamp when approval was recorded.
/// </summary>
public required DateTime ApprovedAtUtc { get; init; }
/// <summary>
/// Gets the optional approval comment.
/// </summary>
public string? Comment { get; init; }
}

View File

@@ -0,0 +1,27 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents a workflow closing option available for user decision.
/// </summary>
public sealed record ClosingMethodItem
{
/// <summary>
/// Gets the closing method identifier.
/// </summary>
public required int ClosingMethodId { get; init; }
/// <summary>
/// Gets the display name of the method.
/// </summary>
public required string Name { get; init; }
/// <summary>
/// Gets a value indicating whether a comment is mandatory for this method.
/// </summary>
public required bool CommentRequired { get; init; }
/// <summary>
/// Gets a value indicating whether this method represents a rejection.
/// </summary>
public required bool IsRejection { get; init; }
}

View File

@@ -0,0 +1,37 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents workflow data for the Contracts source system.
/// </summary>
public sealed record ContractsSourceBlock : SourceBlock
{
/// <summary>
/// Gets available approval profiles.
/// </summary>
public required IReadOnlyList<ProfileItem> Profiles { get; init; }
/// <summary>
/// Gets workflow listing items.
/// </summary>
public required IReadOnlyList<WorkflowListingItem> Listing { get; init; }
/// <summary>
/// Gets already executed approvals.
/// </summary>
public required IReadOnlyList<ApprovalItem> Approvals { get; init; }
/// <summary>
/// Gets document references for workflows.
/// </summary>
public required IReadOnlyList<DocumentReferenceItem> Documents { get; init; }
/// <summary>
/// Gets available closing methods for workflows.
/// </summary>
public required IReadOnlyList<ClosingMethodItem> ClosingMethods { get; init; }
/// <summary>
/// Gets available rejection reasons for rejection-type methods.
/// </summary>
public required IReadOnlyList<RejectionReasonItem> RejectionReasons { get; init; }
}

View File

@@ -0,0 +1,27 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents a lightweight document reference linked to a workflow process.
/// </summary>
public sealed record DocumentReferenceItem
{
/// <summary>
/// Gets the document identifier used for binary retrieval.
/// </summary>
public required string Id { get; init; }
/// <summary>
/// Gets the process identifier.
/// </summary>
public required int ProcessId { get; init; }
/// <summary>
/// Gets the document title.
/// </summary>
public required string Title { get; init; }
/// <summary>
/// Gets the document subtitle.
/// </summary>
public required string Subtitle { get; init; }
}

View File

@@ -0,0 +1,37 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents workflow data for the Ferdinand source system.
/// </summary>
public sealed record FerdinandSourceBlock : SourceBlock
{
/// <summary>
/// Gets available approval profiles.
/// </summary>
public required IReadOnlyList<ProfileItem> Profiles { get; init; }
/// <summary>
/// Gets workflow listing items.
/// </summary>
public required IReadOnlyList<WorkflowListingItem> Listing { get; init; }
/// <summary>
/// Gets already executed approvals.
/// </summary>
public required IReadOnlyList<ApprovalItem> Approvals { get; init; }
/// <summary>
/// Gets document references for workflows.
/// </summary>
public required IReadOnlyList<DocumentReferenceItem> Documents { get; init; }
/// <summary>
/// Gets available closing methods for workflows.
/// </summary>
public required IReadOnlyList<ClosingMethodItem> ClosingMethods { get; init; }
/// <summary>
/// Gets available rejection reasons for rejection-type methods.
/// </summary>
public required IReadOnlyList<RejectionReasonItem> RejectionReasons { get; init; }
}

View File

@@ -0,0 +1,22 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents an approval profile for workflow processing.
/// </summary>
public sealed record ProfileItem
{
/// <summary>
/// Gets the profile identifier.
/// </summary>
public required int ProfileId { get; init; }
/// <summary>
/// Gets the display title of the profile.
/// </summary>
public required string Title { get; init; }
/// <summary>
/// Gets the optional priority value.
/// </summary>
public int? Priority { get; init; }
}

View File

@@ -0,0 +1,17 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents a rejection reason that can be selected for rejection methods.
/// </summary>
public sealed record RejectionReasonItem
{
/// <summary>
/// Gets the rejection reason identifier.
/// </summary>
public required int RejectionReasonId { get; init; }
/// <summary>
/// Gets the display name of the rejection reason.
/// </summary>
public required string Name { get; init; }
}

View File

@@ -0,0 +1,12 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Base type for source-specific workflow blocks.
/// </summary>
public abstract record SourceBlock
{
/// <summary>
/// Gets the source system name.
/// </summary>
public required string Source { get; init; }
}

View File

@@ -0,0 +1,87 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents a single workflow listing row.
/// </summary>
public sealed record WorkflowListingItem
{
/// <summary>
/// Gets the process identifier.
/// </summary>
public required int ProcessId { get; init; }
/// <summary>
/// Gets the profile identifier associated with the process.
/// </summary>
public required int ProfileId { get; init; }
/// <summary>
/// Gets the voucher type.
/// </summary>
public required string VoucherType { get; init; }
/// <summary>
/// Gets the voucher number.
/// </summary>
public required string VoucherNumber { get; init; }
/// <summary>
/// Gets the voucher date.
/// </summary>
public required DateOnly VoucherDate { get; init; }
/// <summary>
/// Gets the cost center number.
/// </summary>
public required string CostCenter { get; init; }
/// <summary>
/// Gets the cost center description.
/// </summary>
public required string CostCenterDescription { get; init; }
/// <summary>
/// Gets the client number.
/// </summary>
public required int ClientNumber { get; init; }
/// <summary>
/// Gets the client name.
/// </summary>
public required string ClientName { get; init; }
/// <summary>
/// Gets the supplier number.
/// </summary>
public required string SupplierNumber { get; init; }
/// <summary>
/// Gets the supplier name.
/// </summary>
public required string SupplierName { get; init; }
/// <summary>
/// Gets the net amount.
/// </summary>
public required decimal NetAmount { get; init; }
/// <summary>
/// Gets the gross amount.
/// </summary>
public required decimal GrossAmount { get; init; }
/// <summary>
/// Gets the discount amount.
/// </summary>
public required decimal DiscountAmount { get; init; }
/// <summary>
/// Gets the currency.
/// </summary>
public required string Currency { get; init; }
/// <summary>
/// Gets the priority value.
/// </summary>
public required int Priority { get; init; }
}

View File

@@ -0,0 +1,12 @@
namespace DigitalData.TaskFlow.Domain.Workflows;
/// <summary>
/// Represents the workflow payload grouped by source systems.
/// </summary>
public sealed record WorkflowSourcesResponse
{
/// <summary>
/// Gets the source blocks included in the response.
/// </summary>
public required IReadOnlyList<SourceBlock> Sources { get; init; }
}