# ED-04-001 – SourceDelivery Domain Object

**Status:** Final

**Related**

- ED-04_SourceDelivery_Aggregate.md
- ADR002_SOURCE_DELIVERY_MODEL_V4.md
- DM001_Domain_Model_v0.7_FINAL.md

---

# 1. Ziel

Dieses Work Package implementiert das Domain Object `SourceDelivery` gemäß ADR002 und DM001.

`SourceDelivery` repräsentiert die fachliche Identität einer eingehenden Lieferung und bildet den Aggregate Root des Delivery-Modells.

Der bestehende Interpretation-and-Reconciliation-Kern bleibt unverändert.

---

# 2. Scope

Implementiert werden

- das Domain Object `SourceDelivery`,
- seine fachlichen Attribute,
- seine Invarianten,
- sowie die zulässigen Zustandsübergänge.

Nicht Bestandteil dieses Work Packages sind

- Persistenz,
- Repository,
- Application Service,
- Integrationstests.

Diese werden in den nachfolgenden ED-04-00x Work Packages umgesetzt.

---

# 3. Verantwortlichkeit

`SourceDelivery` ist verantwortlich für

- die Identität einer Lieferung,
- die Zuordnung zu genau einem Tenant,
- die Zuordnung zu genau einem `SourceSystem`,
- den verwendeten `DeliveryChannel`,
- den Bearbeitungsstatus,
- optionale externe Lieferkennungen,
- den zeitlichen Lebenszyklus einer Lieferung.

Nicht Bestandteil des Aggregates sind

- `SourceValue`,
- `ContextItem`,
- `InterpretationGraph`,
- `InterpretationNode`,
- `ReconciliationResult`.

---

# 4. Attribute

| Attribut | Typ |
|----------|-----|
| id | SourceDeliveryId |
| tenantId | TenantId |
| sourceSystemId | SourceSystemId |
| deliveryChannel | DeliveryChannel |
| status | SourceDeliveryStatus |
| externalDeliveryId | string |
| receivedAt | DateTimeImmutable |
| completedAt | DateTimeImmutable? |


`externalDeliveryId` wird in der ersten Implementierungsphase als optionaler string modelliert. Eine spätere Typisierung als eigenes Value Object bleibt möglich, falls sich daraus fachliche Invarianten oder Validierungsregeln ergeben.




---

# 5. Erzeugung

Neue Lieferungen werden ausschließlich über eine Factory erzeugt.

```php
SourceDelivery::create(...)
```

Die Factory

- erzeugt eine neue Identität,
- setzt `receivedAt`,
- initialisiert den Status mit `RECEIVED`.

---

# 6. Zustandsübergänge

Das Domain Object unterstützt ausschließlich fachlich definierte Zustandsübergänge.

```text
RECEIVED
    ↓
PROCESSING
    ↓
COMPLETED
```

oder

```text
RECEIVED
    ↓
PROCESSING
    ↓
FAILED
```

Dafür werden folgende Methoden bereitgestellt:

```php
markProcessing()

markCompleted()

markFailed()
```

Eine allgemeine Methode

```php
setStatus(...)
```

wird bewusst nicht angeboten.

---

# 7. Invarianten

Beim Erzeugen gelten folgende Regeln:

- `tenantId` ist verpflichtend.
- `sourceSystemId` ist verpflichtend.
- `deliveryChannel` ist verpflichtend.
- `receivedAt` ist verpflichtend.
- `status` wird mit `RECEIVED` initialisiert.

Für Statuswechsel gelten folgende Regeln:

- `COMPLETED` setzt `completedAt`.
- `FAILED` verändert `completedAt` nicht.
- Bereits abgeschlossene Lieferungen können nicht erneut abgeschlossen werden.

---

# 8. Öffentliche API

Die öffentliche API des Domain Objects umfasst ausschließlich:

```text
create()

markProcessing()

markCompleted()

markFailed()
```

Beliebige Setter für fachlich relevante Attribute werden nicht bereitgestellt.

---

# 9. Nicht Bestandteil

Dieses Work Package implementiert bewusst nicht

- Repository-Logik,
- Persistenz,
- Datenbankzugriffe,
- SourceValue-Verwaltung,
- ContextItem-Verwaltung,
- Reconciliation-Funktionalität.

---

# 10. Akzeptanzkriterien

Das Work Package gilt als abgeschlossen, wenn

- `SourceDelivery` erzeugt werden kann,
- alle Invarianten geprüft werden,
- alle zulässigen Zustandsübergänge implementiert sind,
- `completedAt` korrekt gesetzt wird,
- keine fachlich ungültigen Zustandswechsel möglich sind,
- Unit Tests erfolgreich ausgeführt werden.