# WP3-001-001 – Discovery Route Model
## Implementation Plan

- **Status:** Draft
- **Version:** 0.1
- **Datum:** 2026-08-01
- **Scope:** Implementierung von WP3-001-001
- **Owner:** ED
- **Review:** PL

## Referenzen

- `WP3-001_Discovery_Framework_Foundation_v0.2.md`
- `WP3-001-001–Discovery_Route_Model_v0.2.md`
- `docs/architecture/ADR002/ADR002_SOURCE_DELIVERY_MODEL_V4.md`
- `docs/domain/DM001_Domain_Model_v0.7.md`
- `docs/domain/DM002_Persistence_Model_v0.6.md`

---

# 1. Ziel

Dieser Implementation Plan überführt WP3-001-001 in einen konkreten, kleinen Codeauftrag.

Implementiert wird ausschließlich das unveränderliche Konfigurationsmodell `DiscoveryRoute` einschließlich seiner Invarianten und Unit Tests.

Es erfolgen noch keine Änderungen an

- Runtime,
- Composition Root,
- Vocabulary Configuration,
- Candidate Discovery,
- bestehenden Providern,
- oder bestehenden Application Services.

---

# 2. Befund im aktuellen Projektstand

Der aktuelle Code besitzt bereits

- `CandidateDiscoveryGateway` als Application Port,
- `DiscoveredCandidate` als Rückgabeobjekt der Candidate Discovery,
- `LegacyCandidateDiscoveryAdapter` als bestehende Gateway-Implementierung,
- `Vocabulary` und `SubVocabulary` als objektbasierte Vocabulary-Konfiguration,
- `VocabularyRegistry` zur Auflösung von Vocabulary und SubVocabulary,
- sowie eine einfache PSR-4-ähnliche Autoload-Struktur unter `src/`.

Ein eigenes Modell für Discovery Routes existiert noch nicht.

WP3-001-001 ergänzt deshalb genau eine neue Klasse. Bestehende Aufrufpfade bleiben unangetastet.

---

# 3. Vorgesehene Dateien

## Neue Produktivdatei

```text
src/Infrastructure/Discovery/Configuration/DiscoveryRoute.php
```

## Neue Testdatei

```text
tests/Infrastructure/Discovery/Configuration/DiscoveryRouteTest.php
```

## Keine geänderten Dateien

In WP3-001-001 werden keine bestehenden Dateien geändert.

Insbesondere unverändert bleiben

- `src/Application/Reconciliation/CandidateDiscoveryGateway.php`
- `src/Application/Reconciliation/ReconciliationCommand.php`
- `src/Infrastructure/Reconciliation/LegacyCandidateDiscoveryAdapter.php`
- `src/Infrastructure/Composition/ReconciliationCompositionRoot.php`
- `src/Infrastructure/Configuration/Configuration.php`
- `config/vocabularies.php`

---

# 4. Namespace und Schichtzuordnung

Vorgesehener Namespace:

```php
App\Infrastructure\Discovery\Configuration
```

Begründung:

- `DiscoveryRoute` ist kein Domain Aggregate und kein persistentes Domain Object.
- Die Klasse repräsentiert die Konfiguration eines technischen Discovery-Wegs.
- Die spätere `DiscoveryConfigurationRegistry` kann im selben Namespace abgelegt werden.
- Router und Adapter bleiben dadurch von der Konfigurationsdarstellung getrennt.

Die Klasse soll nicht unter `App\Model` abgelegt werden. Dieser Namespace enthält derzeit vor allem Legacy-nahe Vocabulary- und Reconciliation-Modelle und soll durch WP3 nicht weiter vermischt werden.

---

# 5. Klassenmodell

```text
DiscoveryRoute
├── targetVocabularyUri: string
├── scopeVocabularyUri: string
├── candidateSource: string
├── discoveryMethod: string
├── adapterKey: string
└── enabled: bool = true
```

Vorgesehene PHP-Ausprägung:

```php
final readonly class DiscoveryRoute
```

Die Properties werden als öffentliche `readonly` Constructor Properties umgesetzt.

Damit folgt die Klasse dem bereits verwendeten einfachen Konfigurationsstil von `Vocabulary`, `SubVocabulary` und `DiscoveredCandidate`, ergänzt jedoch die für WP3-001-001 erforderliche Validierung.

---

# 6. Constructor Contract

Vorgesehene Signatur:

```php
public function __construct(
    public readonly string $targetVocabularyUri,
    public readonly string $scopeVocabularyUri,
    public readonly string $candidateSource,
    public readonly string $discoveryMethod,
    public readonly string $adapterKey,
    public readonly bool $enabled = true,
)
```

Die Parameterreihenfolge folgt der fachlichen Leserichtung:

```text
Target Vocabulary
→ Discovery Scope
→ Candidate Source
→ Discovery Method
→ Candidate Discovery Adapter
```

`enabled` steht als optionaler technischer Status am Ende.

---

# 7. Invarianten und Validierung

Folgende String-Properties sind verpflichtend:

- `targetVocabularyUri`
- `scopeVocabularyUri`
- `candidateSource`
- `discoveryMethod`
- `adapterKey`

Für jede dieser Properties gilt:

```text
trim(value) darf nicht leer sein
```

Bei einer Verletzung wird eine `InvalidArgumentException` ausgelöst.

Vorgesehene Fehlermeldungen:

```text
DiscoveryRoute.targetVocabularyUri must not be empty.
DiscoveryRoute.scopeVocabularyUri must not be empty.
DiscoveryRoute.candidateSource must not be empty.
DiscoveryRoute.discoveryMethod must not be empty.
DiscoveryRoute.adapterKey must not be empty.
```

## Bewusste Begrenzungen

In WP3-001-001 erfolgt keine

- syntaktische URI-Validierung,
- Prüfung, ob Target Vocabulary oder Discovery Scope im `VocabularyRegistry` existieren,
- Prüfung, ob der `adapterKey` registriert ist,
- Normalisierung oder Veränderung übergebener Werte,
- Einführung kontrollierter Enums für Candidate Source oder Discovery Method.

Diese Prüfungen benötigen andere Komponenten und gehören nicht in das isolierte Route Model.

---

# 8. Target Vocabulary und Discovery Scope

Die Klasse erlaubt ausdrücklich beide gültigen Fälle.

## Root Vocabulary

```text
targetVocabularyUri = http://matcult-the.vocnet.org
scopeVocabularyUri  = http://matcult-the.vocnet.org
```

## SubVocabulary

```text
targetVocabularyUri = http://matcult-the.vocnet.org
scopeVocabularyUri  = http://matcult-the.vocnet.org/00000019
```

Die Klasse erzwingt keine Gleichheit und keine Ungleichheit zwischen beiden Properties.

Die fachliche Auflösung und Konsistenzprüfung erfolgt später über Vocabulary Registry, Discovery Configuration Registry und Router.

---

# 9. Bewusst nicht implementierte Properties und Methoden

WP3-001-001 führt insbesondere nicht ein:

- `priority`
- Route-ID
- Fallback-Konfiguration
- Tenant-Zuordnung
- Adapterinstanz
- technische Parameter
- Endpoint
- Credentials
- Methoden zur Route-Auswahl
- Methoden zur Candidate Discovery
- Equality- oder Hash-Methoden

Getter-Methoden werden nicht zusätzlich eingeführt, da die Properties bereits unveränderlich öffentlich lesbar sind.

---

# 10. Unit-Test-Plan

Die Tests folgen dem bestehenden projektinternen Stil als direkt ausführbare PHP-Datei mit eigenständigen Assertion-Funktionen.

## Erfolgsfälle

1. Eine Route für ein Root Vocabulary kann erzeugt werden.
2. Eine Route für ein SubVocabulary kann erzeugt werden.
3. Alle übergebenen Property-Werte bleiben unverändert erhalten.
4. `enabled` besitzt ohne explizite Übergabe den Wert `true`.
5. `enabled` kann explizit auf `false` gesetzt werden.

## Fehlerfälle

Für jede verpflichtende String-Property wird jeweils geprüft:

1. leerer String wird abgelehnt,
2. ausschließlich aus Whitespace bestehender String wird abgelehnt.

## Nicht getestete Integrationen

Der Test prüft ausdrücklich nicht

- Vocabulary Registry,
- Adapter Registry,
- Router,
- Runtime,
- oder produktive Candidate Discovery.

## Erwartete Testausgabe

```text
WP3-001-001 Discovery Route Model: OK
```

---

# 11. Akzeptanzabbildung

| Akzeptanzkriterium aus WP3-001-001 | Umsetzung im Code bzw. Test |
|---|---|
| `DiscoveryRoute` implementiert | neue finale readonly Klasse |
| alle Pflichtattribute vorhanden | Constructor Properties |
| Target Vocabulary und Scope getrennt | zwei eigenständige Properties |
| Invarianten geprüft | Constructor Validation |
| Standardwerte gesetzt | `enabled = true` |
| Unit Tests erfolgreich | `DiscoveryRouteTest.php` |

---

# 12. Implementierungsreihenfolge

1. Verzeichnis `src/Infrastructure/Discovery/Configuration/` anlegen.
2. `DiscoveryRoute.php` erstellen.
3. Constructor Properties und Defaultwert implementieren.
4. Validierung der fünf Pflichtwerte implementieren.
5. Verzeichnis `tests/Infrastructure/Discovery/Configuration/` anlegen.
6. `DiscoveryRouteTest.php` erstellen.
7. neuen Unit Test ausführen.
8. alle bestehenden Tests ausführen.
9. ausschließlich neue oder geänderte Dateien in bestehender Ordnerstruktur als ZIP liefern.

---

# 13. Erwarteter Änderungsumfang

```text
2 neue Dateien
0 geänderte Dateien
0 Datenbankmigrationen
0 Konfigurationsänderungen
0 Runtime-Änderungen
```

Das Risiko für bestehendes Verhalten ist damit sehr gering.

---

# 14. Folgepaket

Nach erfolgreicher Implementierung und Abnahme verwendet WP3-001-002 die Klasse `DiscoveryRoute` in der `DiscoveryConfigurationRegistry`.

Erst dort werden mehrere Route-Instanzen gesammelt und anhand von `scopeVocabularyUri` aufgelöst.
