diff --git a/DocumentOperator.Domain/Common/Exceptions/DomainException.cs b/DocumentOperator.Domain/Common/Exceptions/DomainException.cs
new file mode 100644
index 0000000..70cdee8
--- /dev/null
+++ b/DocumentOperator.Domain/Common/Exceptions/DomainException.cs
@@ -0,0 +1,25 @@
+namespace DocumentOperator.Domain.Common.Exceptions;
+
+///
+/// Base exception for all domain-related exceptions.
+/// Caught by the Exception Handling Middleware in the API layer.
+///
+public abstract class DomainException : Exception
+{
+ ///
+ /// Error code for categorization and logging.
+ ///
+ public string ErrorCode { get; }
+
+ protected DomainException(string message, string errorCode)
+ : base(message)
+ {
+ ErrorCode = errorCode;
+ }
+
+ protected DomainException(string message, string errorCode, Exception innerException)
+ : base(message, innerException)
+ {
+ ErrorCode = errorCode;
+ }
+}
\ No newline at end of file
diff --git a/DocumentOperator.Domain/Common/Exceptions/DomainValidationException.cs b/DocumentOperator.Domain/Common/Exceptions/DomainValidationException.cs
new file mode 100644
index 0000000..fd13406
--- /dev/null
+++ b/DocumentOperator.Domain/Common/Exceptions/DomainValidationException.cs
@@ -0,0 +1,28 @@
+namespace DocumentOperator.Domain.Common.Exceptions;
+
+///
+/// Exception thrown when domain validation fails (e.g., invalid Value Objects).
+/// Maps to HTTP 400 Bad Request in the API layer.
+///
+public class DomainValidationException : DomainException
+{
+ public string PropertyName { get; }
+
+ public DomainValidationException(string message)
+ : base(message, "DOMAIN_VALIDATION_ERROR")
+ {
+ PropertyName = string.Empty;
+ }
+
+ public DomainValidationException(string propertyName, string message)
+ : base(message, "DOMAIN_VALIDATION_ERROR")
+ {
+ PropertyName = propertyName;
+ }
+
+ public DomainValidationException(string message, Exception innerException)
+ : base(message, "DOMAIN_VALIDATION_ERROR", innerException)
+ {
+ PropertyName = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/DocumentOperator.Domain/Common/Exceptions/NotFoundException.cs b/DocumentOperator.Domain/Common/Exceptions/NotFoundException.cs
new file mode 100644
index 0000000..73cd81a
--- /dev/null
+++ b/DocumentOperator.Domain/Common/Exceptions/NotFoundException.cs
@@ -0,0 +1,25 @@
+namespace DocumentOperator.Domain.Common.Exceptions;
+
+///
+/// Exception thrown when a requested resource is not found.
+/// Maps to HTTP 404 Not Found in the API layer.
+///
+public class NotFoundException : DomainException
+{
+ public string ResourceType { get; }
+ public object ResourceId { get; }
+
+ public NotFoundException(string resourceType, object resourceId)
+ : base($"{resourceType} with ID '{resourceId}' was not found.", "RESOURCE_NOT_FOUND")
+ {
+ ResourceType = resourceType;
+ ResourceId = resourceId;
+ }
+
+ public NotFoundException(string resourceType, object resourceId, string customMessage)
+ : base(customMessage, "RESOURCE_NOT_FOUND")
+ {
+ ResourceType = resourceType;
+ ResourceId = resourceId;
+ }
+}
\ No newline at end of file
diff --git a/DocumentOperator.Domain/Common/Exceptions/PdfProcessingException.cs b/DocumentOperator.Domain/Common/Exceptions/PdfProcessingException.cs
new file mode 100644
index 0000000..ccd73c8
--- /dev/null
+++ b/DocumentOperator.Domain/Common/Exceptions/PdfProcessingException.cs
@@ -0,0 +1,34 @@
+namespace DocumentOperator.Domain.Common.Exceptions;
+
+///
+/// Exception thrown when PDF processing operations fail.
+/// Maps to HTTP 500 Internal Server Error or 422 Unprocessable Entity in the API layer.
+///
+public class PdfProcessingException : DomainException
+{
+ public string Operation { get; }
+
+ public PdfProcessingException(string operation, string message)
+ : base($"PDF processing failed during '{operation}': {message}", "PDF_PROCESSING_ERROR")
+ {
+ Operation = operation;
+ }
+
+ public PdfProcessingException(string operation, string message, Exception innerException)
+ : base($"PDF processing failed during '{operation}': {message}", "PDF_PROCESSING_ERROR", innerException)
+ {
+ Operation = operation;
+ }
+
+ public PdfProcessingException(string message)
+ : base(message, "PDF_PROCESSING_ERROR")
+ {
+ Operation = "Unknown";
+ }
+
+ public PdfProcessingException(string message, Exception innerException)
+ : base(message, "PDF_PROCESSING_ERROR", innerException)
+ {
+ Operation = "Unknown";
+ }
+}
\ No newline at end of file
diff --git a/DocumentOperator.Domain/DocumentOperator.Domain.csproj b/DocumentOperator.Domain/DocumentOperator.Domain.csproj
index daf38a3..1b2cd7a 100644
--- a/DocumentOperator.Domain/DocumentOperator.Domain.csproj
+++ b/DocumentOperator.Domain/DocumentOperator.Domain.csproj
@@ -7,7 +7,6 @@
-
diff --git a/ROADMAP.md b/ROADMAP.md
index add2992..2fdc923 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -722,15 +722,15 @@ DocumentOperator.Domain/
---
-#### 🔄 Step 2.1: Domain Exceptions erstellen - **NEXT**
+#### ✅ Step 2.1: Domain Exceptions erstellen - **COMPLETED**
**Aufgabe:** Custom Exception-Klassen für fachliche Fehler
-**Zu erstellen:**
-1. [ ] `DomainException.cs` (Basis-Exception)
-2. [ ] `DomainValidationException.cs` (Value Object Validierung)
-3. [ ] `NotFoundException.cs` (Resource nicht gefunden)
-4. [ ] `PdfProcessingException.cs` (PDF-spezifische Fehler)
+**Erstellt:**
+1. [x] `DomainException.cs` (Basis-Exception)
+2. [x] `DomainValidationException.cs` (Value Object Validierung)
+3. [x] `NotFoundException.cs` (Resource nicht gefunden)
+4. [x] `PdfProcessingException.cs` (PDF-spezifische Fehler)
**Wo:** `Domain/Common/Exceptions/`
@@ -755,7 +755,7 @@ if (notFound)
---
-#### ⏳ Step 2.2: Value Objects erstellen
+#### 🔄 Step 2.2: Value Objects erstellen - **NEXT**
**Aufgabe:** Typsichere, selbst-validierende Wert-Objekte
@@ -1566,7 +1566,8 @@ Request mit X-API-Key → Middleware
### 🔄 In Progress
- **Phase 2:** Domain Layer
- - **NEXT:** Step 2.1 - Domain Exceptions erstellen
+ - ✅ Step 2.1 - Domain Exceptions
+ - **NEXT:** Step 2.2 - Value Objects
### ⏳ Pending
- Phase 3-9
@@ -1629,7 +1630,8 @@ Request mit X-API-Key → Middleware
| 2024-XX-XX | Phase 1 | Configuration, Serilog, Options Pattern |
| 2024-XX-XX | Phase 1 | **Decision:** Exception-based statt Ardalis.Result |
| 2024-XX-XX | Phase 1 | ✅ Phase 1 completed |
-| 2024-XX-XX | Phase 2 | 🔄 Starting Domain Layer - Exceptions |
+| 2024-XX-XX | Phase 2 | ✅ Step 2.1 completed - Domain Exceptions created |
+| 2024-XX-XX | Phase 2 | 🔄 Starting Step 2.2 - Value Objects |
---