# Deduplicate Relations

Diseño original para fuzzygraph.

## Funcion a implementar

### deduplicate_relations

- **Dominio:** datascience
- **Lang:** Python
- **Purity:** pure
- **Signature:**
  ```python
  def deduplicate_relations(
      relations: list[RelationCandidate],
      entity_id_map: dict[str, str],
  ) -> list[RelationCandidate]:
  ```
- **Parametros:**
  - `relations`: relaciones candidatas (con from_name/to_name originales)
  - `entity_id_map`: mapping de nombre normalizado → entity_id final (output de deduplicate_entities). Permite resolver nombres que fueron mergeados: si "John Smith" y "Smith, John" se mergearon en entity_123, ambos nombres mapean a entity_123.
- **Retorno:** lista deduplicada de RelationCandidate con from/to resueltos a IDs finales
- **Algoritmo:**
  1. **Resolver nombres a IDs:** Para cada relacion, mapear from_name y to_name al entity_id via entity_id_map. Si un nombre no tiene match, intentar fuzzy match contra las keys del map.
  2. **Deduplicar por (from_id, to_id, relation_type):**
     - Si multiples relaciones tienen el mismo (from, to, type): mergear
     - Descripcion: concatenar descripciones unicas
     - Confidence: max
     - Self-loops (from_id == to_id): descartar
  3. Retornar lista limpia
- **Deps:** `levenshtein_distance` (para fuzzy match de nombres no resueltos)
- **Tests:**
  - 2 relaciones identicas (from, to, type) → 1
  - Relacion con nombre mergeado → se resuelve al ID correcto
  - Self-loop → descartado
  - Relacion con nombre no mapeado → intenta fuzzy match, si falla descarta con warning
