> ## Documentation Index
> Fetch the complete documentation index at: https://developers.jobhandy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Mitarbeiter synchronisieren

> Entwerfen Sie eine fortsetzbare Mitarbeitersynchronisation mit stabiler Identität, eindeutiger Zuordnung, Dry-Run-Validierung, partiellen Updates und Reconciliation.

Eine zuverlässige Synchronisation trennt Identitätsabgleich, Tenant-Zuordnung, Validierung, Mutation und Checkpointing. Erstellen Sie nicht bei jedem Importlauf einen neuen JobHandy-Mitarbeiter.

## Source-of-Truth-Modell

Legen Sie vor der Implementierung für jedes gemappte Feld die fachliche Verantwortung fest.

| Feldgruppe                   | Empfohlener Verantwortlicher                                              | Verhalten der Integration                                                           |
| ---------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Geschäftliche E-Mail-Adresse | HR-/Kundenprozess bei der Erstellung; über diesen Endpoint nicht patchbar | Änderung als getrennten fachlichen Prozess behandeln                                |
| Personalnummer               | Kunden-HR-System, sofern stabil                                           | Als Matching-Key verwenden, wenn Eindeutigkeit garantiert ist                       |
| Kontakt- und Adressdaten     | Abgestimmtes Quellsystem                                                  | Nur geänderte unterstützte Felder patchen                                           |
| `blocked`                    | Abgestimmter Offboarding-/Kontoprozess                                    | Explizit setzen; nicht als Löschung behandeln                                       |
| Tenant                       | Zuordnungsprozess                                                         | Beim Create auflösen; Public Patch verschiebt bereits zugeordnete Mitarbeiter nicht |
| Division                     | HR-Organisationsquelle                                                    | Innerhalb desselben Tenants patchen oder mit `null` entfernen                       |
| JobHandy-`id`                | JobHandy                                                                  | Nach Match oder Create speichern und für spätere Requests verwenden                 |

## Reihenfolge des Matchings

1. Gespeicherte JobHandy-Mitarbeiter-ID
2. Stabile `employeeNumber`, wenn das Quellsystem Eindeutigkeit garantiert
3. Ein anderes ausdrücklich vereinbartes eindeutiges Mapping
4. E-Mail-Adresse nur, wenn der Kunde deren Unveränderlichkeit und Eindeutigkeit garantiert

Wenn eine Abfrage null oder mehr als einen plausiblen Treffer liefert, stoppen Sie die automatische Erstellung und leiten Sie den Datensatz zur Reconciliation weiter.

## Swimlane der Synchronisation

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
sequenceDiagram
    participant HR as HR-System
    participant INT as Integration
    participant API as JobHandy API
    participant MAIL as Passwort-E-Mail-Prozess

    HR->>INT: Mitarbeiteränderung und Quellversion
    INT->>API: Über gespeicherte ID oder employeeNumber suchen
    alt Mitarbeiter vorhanden
        API-->>INT: Aktueller Mitarbeiter
        INT->>INT: Von der Integration verantwortete Felder vergleichen
        opt Änderungen erkannt
            INT->>API: PATCH ?dryRun=true
            API-->>INT: Projizierter Mitarbeiter
            INT->>API: PATCH
            API-->>INT: Gespeicherter Mitarbeiter + Request-ID
        end
    else Mitarbeiter nicht vorhanden
        INT->>API: POST ?dryRun=true
        API-->>INT: Projizierter Mitarbeiter
        INT->>API: POST
        API-->>INT: Erstellte Mitarbeiter-ID + Request-ID
        API->>MAIL: E-Mail zur Passwortvergabe senden
    else Mehrdeutiger Treffer
        INT->>INT: Stoppen und Reconciliation-Eintrag erstellen
    end
    INT->>HR: JobHandy-ID, Version und Ergebnis speichern
```

## Zuordnung auflösen

* Senden Sie `X-Tenant-ID`, wenn der Key mehrere mögliche Tenants enthält.
* Senden Sie `divisionId`, wenn der ausgewählte Tenant keine eindeutige zulässige Division ergibt.
* Verwenden Sie ausschließlich eine Division innerhalb des Ziel-Tenants und API-Key-Scopes.
* `divisionId: null` entfernt die Divisionszuordnung, verschiebt den Mitarbeiter aber nicht in einen anderen Tenant.

## Mitarbeiter finden

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --get 'https://api.jobhandy.io/v1/employees' \
  --header 'X-API-Key: YOUR_API_KEY' \
  --header 'X-Tenant-ID: {{tenantId}}' \
  --data-urlencode 'filter=employeeNumber=EMP-1042'
```

Speichern Sie nach einem erfolgreichen Match die zurückgegebene JobHandy-`id`.

## Sicher erstellen

<Steps>
  <Step title="Bestehenden Treffer ausschließen">
    Suchen Sie anhand der gespeicherten JobHandy-ID oder stabilen Personalnummer.
  </Step>

  <Step title="Zuordnung und Payload validieren">
    Rufen Sie `POST /employees?dryRun=true` mit den finalen Headern und dem finalen Body auf.
  </Step>

  <Step title="Create ausführen">
    Senden Sie dieselbe Anfrage ohne `dryRun=true`.
  </Step>

  <Step title="Reale ID speichern">
    Speichern Sie ausschließlich die ID aus der `201`-Response ohne Dry Run.
  </Step>

  <Step title="Side Effect dokumentieren">
    Ein erfolgreiches Create sendet eine E-Mail zur Passwortvergabe. Erstellen Sie keine doppelten Konten, um diese E-Mail erneut auszulösen.
  </Step>
</Steps>

## Nur geänderte Felder patchen

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "phoneNumber": "+49 221 1234567",
  "divisionId": "68920e08eeaea4f2301eecb3"
}
```

Nullable Patch-Eigenschaften können mit `null` geleert werden. Lassen Sie Eigenschaften weg, die unverändert bleiben sollen.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "phoneNumber": null,
  "divisionId": null
}
```

## Checkpoint-Modell

Speichern Sie mindestens:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
sourceEmployeeId
jobHandyEmployeeId
sourceVersion or watermark
lastSuccessfulAtUtc
lastRequestId
lastResult
```

## Reconciliation nach Timeout

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
    A[Create oder Patch mit Timeout] --> B[Mitarbeiter lesen oder suchen]
    B --> C{Gewünschter Zustand vorhanden?}
    C -- Ja --> D[Erfolg und Checkpoint speichern]
    C -- Nein --> E{Ressource sicher matchbar?}
    E -- Ja --> F[Neu bewerten und mit neuer Request-ID wiederholen]
    E -- Nein --> G[Manuelle Reconciliation]
```

## Häufige Fehler

| Fehler                         | Bedeutung                                                                   | Maßnahme                                                      |
| ------------------------------ | --------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `DUPLICATE_RESOURCE`           | Eine Eindeutigkeitsregel wird bereits durch einen anderen Datensatz erfüllt | Vorhandenen Mitarbeiter finden und abgleichen                 |
| `EMPLOYEE_PLACEMENT_AMBIGUOUS` | Divisionsbeschränkter Scope ergibt kein eindeutiges Ziel                    | Zulässige `divisionId` senden                                 |
| `TENANT_CONTEXT_AMBIGUOUS`     | Mehr als ein Tenant ist möglich                                             | `X-Tenant-ID` senden                                          |
| `INVALID_REFERENCE`            | Referenzierter Tenant oder referenzierte Division ist nicht verfügbar       | Scope und Referenzen aktualisieren                            |
| `409` oder `422` nach Dry Run  | Zustand hat sich geändert oder finale Validierung weicht ab                 | Erneut lesen und validieren; keinen blinden Retry durchführen |
