# WP2-005 – Relational Repositories and Data Mapper

## Status

Implemented on the baseline `reconcile_ADR001.WP2_20260720_6.zip`.

## Scope

WP2-005 implements the accepted architecture decision
`ADR001-WP2-005_RELATIONAL_REPOSITORIES_AND_DATA_MAPPER_v3.md`.

The package introduces:

- the application contracts `SourceValueRepository` and `ReconciliationResultRepository`,
- the infrastructure implementations `RelationalSourceValueRepository` and `RelationalReconciliationResultRepository`,
- specialized insert mappers for the currently persistable DM001/DM002 parts,
- assignment of technical database IDs by persistence,
- translation from a selected candidate URI to the candidate's technical foreign key,
- persistence exceptions at the application boundary,
- Composition Root factory methods for both repositories,
- isolated repository and mapper tests.

## Deliberate boundaries

WP2-005 is insert-only. Persisting an aggregate that already has a technical ID is rejected.

WP2-005 does not introduce:

- rehydration or read repositories,
- update/delete semantics,
- transaction coordination across both aggregate repositories,
- automatic persistence in the productive reconciliation flow,
- placeholder rows for DM002 tables without a corresponding current domain representation.

Cross-repository transaction coordination remains part of WP2-007.

`interpretation_node_property` is not written in this package because the current `InterpretationNode` domain object does not expose a property collection. No artificial placeholder mapping was introduced.

## Application contracts

- `App\Application\Persistence\SourceValueRepository`
- `App\Application\Persistence\ReconciliationResultRepository`

## Infrastructure implementations

- `App\Infrastructure\Persistence\Repository\RelationalSourceValueRepository`
- `App\Infrastructure\Persistence\Repository\RelationalReconciliationResultRepository`

## Data mappers

- `SourceValueMapper`
- `InterpretationGraphMapper`
- `InterpretationNodeMapper`
- `ReconciliationResultMapper`
- `CandidateItemMapper`
- `MatchDecisionMapper`

`JsonValueEncoder` centralizes strict JSON serialization for `provenance_json` and `payload_json`.

## Persistence order

### SourceValue aggregate

1. `source_value`
2. `interpretation_graph`
3. `interpretation_node`

### ReconciliationResult aggregate

1. `reconciliation_result`
2. `candidate_item`
3. `match_decision`

Candidate items are inserted before match decisions so that a selected candidate URI can be translated to `selected_candidate_item_id`.

## Composition Root

The Composition Root now exposes:

```php
$sourceValueRepository = $root->createSourceValueRepository();
$resultRepository = $root->createReconciliationResultRepository();
```

Creating either repository opens the configured shared PDO connection lazily through the existing `DatabaseConnectionFactory`.

## Tests

Run:

```bash
php tests/Persistence/RelationalRepositoriesTest.php
```

The test verifies:

- insert ordering,
- technical ID assignment,
- JSON encoding,
- selected candidate foreign-key translation,
- rejection of a result without persistent `InterpretationNode` ID,
- insert-only behavior.

All existing PHP regression tests passed in the engineering workspace. For the regression run, the database configuration file already introduced by WP2-003 must be present in `config/database.php`.
