diff --git a/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ApiException.cs b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ApiException.cs
new file mode 100644
index 0000000..7e88849
--- /dev/null
+++ b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ApiException.cs
@@ -0,0 +1,32 @@
+using DigitalData.TaskFlow.Domain.Enums;
+
+namespace DigitalData.TaskFlow.Application.Common.Exceptions;
+
+///
+/// Represents an API-facing exception that carries HTTP and domain meta information.
+///
+public class ApiException : Exception
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// HTTP status code to return.
+ /// Domain meta code to return.
+ /// Response message.
+ public ApiException(int statusCode, MetaCode metaCode, string message)
+ : base(message)
+ {
+ StatusCode = statusCode;
+ MetaCode = metaCode;
+ }
+
+ ///
+ /// Gets the HTTP status code.
+ ///
+ public int StatusCode { get; }
+
+ ///
+ /// Gets the domain meta code.
+ ///
+ public MetaCode MetaCode { get; }
+}
diff --git a/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ConflictApiException.cs b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ConflictApiException.cs
new file mode 100644
index 0000000..937e56d
--- /dev/null
+++ b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/ConflictApiException.cs
@@ -0,0 +1,19 @@
+using DigitalData.TaskFlow.Domain.Enums;
+
+namespace DigitalData.TaskFlow.Application.Common.Exceptions;
+
+///
+/// Represents a 409 API exception.
+///
+public sealed class ConflictApiException : ApiException
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Domain meta code to return.
+ /// Response message.
+ public ConflictApiException(MetaCode metaCode, string message)
+ : base(409, metaCode, message)
+ {
+ }
+}
diff --git a/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/NotFoundApiException.cs b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/NotFoundApiException.cs
new file mode 100644
index 0000000..bbc75c7
--- /dev/null
+++ b/src/core/DigitalData.TaskFlow.Application/Common/Exceptions/NotFoundApiException.cs
@@ -0,0 +1,18 @@
+using DigitalData.TaskFlow.Domain.Enums;
+
+namespace DigitalData.TaskFlow.Application.Common.Exceptions;
+
+///
+/// Represents a 404 API exception.
+///
+public sealed class NotFoundApiException : ApiException
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Response message.
+ public NotFoundApiException(string message)
+ : base(404, MetaCode.NotFound, message)
+ {
+ }
+}
diff --git a/src/core/DigitalData.TaskFlow.Application/Features/Documents/Queries/GetDocument/GetDocumentQuery.cs b/src/core/DigitalData.TaskFlow.Application/Features/Documents/Queries/GetDocument/GetDocumentQuery.cs
index c54e6f9..206b481 100644
--- a/src/core/DigitalData.TaskFlow.Application/Features/Documents/Queries/GetDocument/GetDocumentQuery.cs
+++ b/src/core/DigitalData.TaskFlow.Application/Features/Documents/Queries/GetDocument/GetDocumentQuery.cs
@@ -2,6 +2,7 @@ using DigitalData.TaskFlow.Application.Common.Factories;
using DigitalData.TaskFlow.Application.Common.Interfaces;
using DigitalData.TaskFlow.Domain.Common;
using DigitalData.TaskFlow.Domain.Documents;
+using DigitalData.TaskFlow.Domain.Enums;
using FluentValidation;
using MediatR;
diff --git a/src/core/DigitalData.TaskFlow.Application/Features/Workflows/Commands/CloseWorkflow/CloseWorkflowCommand.cs b/src/core/DigitalData.TaskFlow.Application/Features/Workflows/Commands/CloseWorkflow/CloseWorkflowCommand.cs
index 932bd5e..332c77b 100644
--- a/src/core/DigitalData.TaskFlow.Application/Features/Workflows/Commands/CloseWorkflow/CloseWorkflowCommand.cs
+++ b/src/core/DigitalData.TaskFlow.Application/Features/Workflows/Commands/CloseWorkflow/CloseWorkflowCommand.cs
@@ -1,8 +1,10 @@
+using DigitalData.TaskFlow.Application.Common.Exceptions;
using DigitalData.TaskFlow.Application.Common.Interfaces;
using DigitalData.TaskFlow.Application.Common.Factories;
using AutoMapper;
using DigitalData.TaskFlow.Domain.Closing;
using DigitalData.TaskFlow.Domain.Common;
+using DigitalData.TaskFlow.Domain.Enums;
using FluentValidation;
using MediatR;
@@ -77,6 +79,16 @@ public sealed class CloseWorkflowCommandHandler(IWorkflowRepository workflowRepo
decision,
cancellationToken);
+ if (result.ProcessId <= 0)
+ {
+ throw new NotFoundApiException("Vorgang nicht gefunden");
+ }
+
+ if (!result.IsClosed)
+ {
+ throw new ConflictApiException(MetaCode.AlreadyClosed, "Vorgang bereits abgeschlossen");
+ }
+
return ApiEnvelopeFactory.Create(result);
}
}