# UID-Suche

> Navigation zu einem Datensatz über seine persistente UID

---

Eine **UID** (`_UID` in GEDCOM 5.5.1, `UID` in GEDCOM 7.0) ist eine persistente Kennung, die einem Datensatz zugewiesen wird. Die UID übersteht XREF-Umnummerierungen und Baum-Migrationen und ist damit ein stabiler Referenzpunkt.

Diese Funktion ermöglicht die direkte Navigation zu einem Datensatz über seine UID. Das URL-Muster ist:

- `/tree/{baum}/goto-uid/{uid}` — auf einen Baum beschränkt
- `/goto-uid/{uid}` — global (durchsucht alle Bäume)

**Verhalten:**

- **0 Treffer** → 404
- **1 sichtbarer Treffer** → Weiterleitung zum Datensatz
- **>1 sichtbarer Treffer** → Auswahl-Liste (UIDs mit unterschiedlicher Groß/Klein-Schreibung oder dieselbe UID in mehreren Datensätzen)

Der UID-Vergleich ist **case-insensitive** (GEDCOM-Spezifikationen definieren UID nicht als case-sensitive). Der gespeicherte Wert ist wörtlich; die Übereinstimmung wird case-insensitiv geprüft, sodass UIDs mit unterschiedlicher Groß/Klein-Schreibung eine Auswahl-Liste zurückliefern statt einer möglicherweise falschen einzelnen Weiterleitung.

UIDs können über die **Schnellsuche** gesucht werden. Für kürzere UIDs, die als XREF durchgehen könnten, kann das Präfix `uid:` vorangestellt werden.

### Standard-Navigation (`goto-id`)

`goto-id` ist das Standard-Navigationsziel für **jeden** LinkEnhancer-Link — sowohl untypisiert (`wt=@REF@`) als auch typisiert (`wt=<type>@REF@`) — und löst eine Referenz auf, die entweder ein **XREF** oder eine **UID** ist. Das URL-Muster ist:

- `/tree/{baum}/goto-id/{id}` — auf einen Baum beschränkt (fällt auf globale Suche zurück, wenn im Baum nichts gefunden wird, mit Flash-Benachrichtigung)
- `/goto-id/{id}` — global (durchsucht alle Bäume)

**Verhalten** (gemeinsamer `IdResolver`): Die ID wird längenbasiert und bidirektional versucht — eine lange ID (≥ 18 Zeichen) zuerst als UID, eine kurze zuerst als XREF — und fällt auf die andere zurück, wenn die erste nichts ergibt, sodass eine Auflösung nie verloren geht. 0 Treffer → 404, 1 sichtbarer Treffer → Weiterleitung, >1 → Auswahl-Liste.




<pre class="mermaid">sequenceDiagram
    autonumber
    participant U as 👤 Nutzer (Browser)
    participant JS as LE JavaScript
    participant WT as webtrees-Server
    participant IR as IdResolver
    participant DB as Datenbank

    Note over U,JS: Klick auf einen LE-Link
    U-&gt;&gt;JS: Klick auf #@wt=@I234@
    JS-&gt;&gt;JS: detect href &#34;#@…&#34;
    JS-&gt;&gt;WT: GET /tree/5/goto-id/I234
    WT-&gt;&gt;IR: resolve(&#34;I234&#34;, tree=5)

    alt ID short (&lt; 18 chars) → try as XREF first
        IR-&gt;&gt;DB: SELECT … WHERE xref = &#39;I234&#39;
        DB--&gt;&gt;IR: Treffer?
    else ID long (&gt;= 18 chars) → try as UID first
        IR-&gt;&gt;DB: SELECT … FROM le_uid_index WHERE uid = &#39;…&#39;
        DB--&gt;&gt;IR: Treffer?
    end

    alt ✅ 1 Treffer
        IR--&gt;&gt;WT: Record
        WT--&gt;&gt;U: Weiterleitung zur Record-Seite
    else 0 Treffer → Fallback
        IR-&gt;&gt;IR: andere Richtung versuchen (XREF ⇄ UID)
    else &gt;1 matches
        WT--&gt;&gt;U: Auswahl-Liste
    end

    Note over IR,DB: Bidirektional — XREF ⇄ UID&lt;br/&gt;eine Auflösung geht nie verloren
</pre>

Ein typisierter `wt=<type>@REF@`-Link ist eine **Legacy**-Form: der Typ-Buchstabe wird nicht mehr für das Routing verwendet (alle Links gehen über `goto-id`) und ist nur dokumentarisch — er steuert weiterhin den Diagramm-Link für Personen und den Typ-Mismatch-Hinweis in der Querverweis-Übersicht. Neue Links sollten die untypisierte `wt=@REF@`-Form verwenden.

### XREF-Route (`goto-xref`)

Es ist auch die Route `/tree/{baum}/goto-xref/{xref}` verfügbar, die es erlaubt, unabhängig vom Record-Typ zum entsprechenden Datensatz im Baum zu navigieren.

### Querverweis-Übersicht: UID-Ziele in anderen Bäumen

In der Admin-*Querverweis-Übersicht* wird ein Link, dessen UID-Ziel nicht im eigenen Baum des Datensatzes gefunden wird, normalerweise als *"Ziel nicht gefunden"* angezeigt. Wenn die UID-Funktion aktiviert ist, wird ein solches Ziel zusätzlich **global** (über die anderen Bäume hinweg) aufgelöst; wenn Treffer existieren, wird es als **nicht eindeutig** (`?`) mit der Trefferanzahl angezeigt: bis zu 3 Treffer werden als direkte Cross-Tree-Links aufgelistet, mehr als 3 kollabieren zu einem einzelnen `goto-id`-Link (Titel = die UID). Dieses Verhalten ist hart an der UID-Funktions-Einstellung gated und gilt nie für Ziele, die einen expliziten Baum benennen.

### Index

Der UID-Index wird in der Tabelle `le_uid_index` gespeichert (eine Zeile pro UID-Tag-Vorkommen, unterschieden durch `tag_path`). Er wird ausschließlich durch <a href="https://codeberg.org/bschwede/linkenhancer/src/branch/main/cli/build-uid-index.php" target="_blank" rel="noopener"><code>build-uid-index.php</code></a>
 gepflegt (kein Live-Scan bei Anfragen).

- **Initialer Build** (erster Lauf oder `--rebuild`): Vollständiger Scan aller GEDCOM-Tabellen, Extraktion aller UID-Tags via `UidTagCollector`.
- **Inkrementelle Läufe**: Nur Datensätze, deren MD5-Fingerprint sich geändert hat (oder hinzugefügt/entfernt wurden), werden neu gescannt.

Cron-Beispiel (alle 10 Minuten, max. 5000 Datensätze pro Lauf):

```
*/10 * * * * cd /path/to/webtrees && php modules_v4/linkenhancer/cli/build-uid-index.php --limit=5000 >> /var/log/linkenhancer-uid-index.log 2>&1
```

Die Funktion kann auf der Modul-Admin-Seite ein-/ausgeschaltet werden ("Aktivieren" → [5] UID-Suche). Der aktuelle Index-Status (Zeilenanzahl, letzter Build-Zeitpunkt) wird dort angezeigt.

Während die Funktion ausgeschaltet ist, werden Index-Builds automatisch übersprungen (der Cron-Lauf beendet sich mit Exit 0 ohne Arbeit). `--force` baut den Index trotzdem (z.B. zur Vorbereitung der Reaktivierung), und `--flush` funktioniert unabhängig vom Schalter.

> **Hinweis:** UID-Tags auf jeder Verschachtelungsebene werden indexiert (z.B. `0 @I1@ INDI`, `1 _UID`, `1 FAMF`, `2 _UID`). Der Tag-Pfad wird pro Zeile gespeichert, sodass Duplikate in der Auswahl-Liste unterscheidbar sind.
