# ED-02-003 Rehydration

**Status:** Ready for Implementation  
**Parent:** ED-02 Context Persistence

## Ziel

Dieses Dokument beschreibt die Rehydration der in `context_item` persistierten Kontextdaten
in den bestehenden Domain-Objektgraphen des `SourceValue`-Aggregats.

## Scope

ED-02-003 umfasst:

- Laden der persistierten `context_item`-Datensätze
- Erzeugung von `ContextItem`-Domain-Objekten
- Einbindung der ContextItems in das rehydrierte `SourceValue`
- Erhalt einer deterministischen Reihenfolge
- Rückwärtskompatibilität für SourceValues ohne ContextItems

Nicht Bestandteil:

- relationales Feldmapping (ED-02-001)
- Repository-Schreiblogik (ED-02-002)
- Änderungen am Domain-Modell
- Testspezifikation (ED-02-004)
- Provenance- oder SourceDelivery-Modellierung

## Ausgangspunkt

Das Domain-Modell aus ED-01 besteht aus:

```text
SourceValue
 └── ContextItem[*]
      ├── contextTypeUri
      └── value
```

Die Persistenz liefert pro `SourceValue` null bis viele Datensätze aus:

```text
context_item
-------------
id
source_value_id
context_type_uri
value
```

## Rehydrationsablauf

Beim Laden eines `SourceValue` erfolgt die Rehydration in dieser Reihenfolge:

1. Stammdaten des `SourceValue` laden.
2. Zugehörige Datensätze aus `context_item` laden.
3. Datensätze nach `id ASC` sortieren.
4. Für jeden Datensatz ein `ContextItem` erzeugen.
5. Die erzeugten ContextItems in derselben Reihenfolge an das `SourceValue` anhängen.
6. Das vollständig rehydrierte `SourceValue` zurückgeben.

## SQL-Ladeabfrage

Die ContextItems werden über die technische Beziehung zum Aggregate geladen:

```sql
SELECT
    id,
    source_value_id,
    context_type_uri,
    value
FROM context_item
WHERE source_value_id = :source_value_id
ORDER BY id ASC;
```

Die Spalten `id` und `source_value_id` werden ausschließlich von der Persistenzschicht
verwendet.

## Erzeugung der Domain-Objekte

Für jeden Datensatz wird ein Domain-Objekt erzeugt:

```php
$contextItem = new ContextItem(
    $row['context_type_uri'],
    $row['value']
);
```

Anschließend wird das Objekt über die bestehende Domain-API an das Aggregate angefügt:

```php
$sourceValue->addContextItem($contextItem);
```

Die Persistenzschicht umgeht keine Domain-Invarianten.

## Umgang mit leerem Context-Bestand

Existieren für ein `SourceValue` keine Datensätze in `context_item`, wird das Aggregate mit
einer leeren Context-Liste rehydriert.

Dies entspricht dem Zustand vor ED-01 und gewährleistet Rückwärtskompatibilität für bereits
persistierte SourceValues.

## Reihenfolge

Die Tabelle enthält keine fachliche Sortierspalte.

Für ED-02 gilt daher:

- Ladefolge: `id ASC`
- deterministischer Wiederaufbau
- keine Zusicherung einer fachlich definierten Reihenfolge
- keine Einführung von `sort_order`

Die technische Reihenfolge entspricht bei unverändertem Aggregate-Bestand regelmäßig der
Einfügereihenfolge.

## Fehlerverhalten

Ungültige persistierte Daten werden nicht stillschweigend korrigiert oder ignoriert.

Wenn beispielsweise

- `context_type_uri` leer ist oder
- `value` leer ist,

schlägt die Erzeugung des `ContextItem` entsprechend den Domain-Invarianten fehl.

Der Fehler wird über den bestehenden Persistenz- beziehungsweise Transaktionspfad
weitergegeben.

Damit bleiben Datenfehler sichtbar und überprüfbar.

## Aggregate-Konsistenz

Ein rehydriertes `SourceValue` gilt erst dann als vollständig geladen, wenn seine zugehörigen
ContextItems verarbeitet wurden.

Es wird kein teilweise rehydriertes Aggregate an die Anwendungsschicht zurückgegeben.

## Akzeptanzkriterien

ED-02-003 ist abgeschlossen, wenn:

- alle ContextItems eines `SourceValue` geladen werden,
- pro Datensatz genau ein `ContextItem` erzeugt wird,
- die vorhandene Domain-API verwendet wird,
- die Reihenfolge über `id ASC` deterministisch bleibt,
- SourceValues ohne ContextItems korrekt geladen werden,
- ungültige persistierte Werte nicht stillschweigend verändert werden,
- keine Datenbankidentität in das Domain-Modell übertragen wird,
- das vollständig rehydrierte Aggregate zurückgegeben wird.
