feat(verzeichnis): LDAP-Abgleich, Zeitplan, CSV-Import und Log #30

Merged
florian.wilde merged 1 commits from feat/16-verzeichnis-ldap into main 2026-09-26 00:21:57 +00:00
Owner

Meilenstein M11: Personen der eigenen Firma kommen aus dem Active Directory.

Was drin ist

  • LDAP-Schicht unter src/server/ldap/: ldaps://, ldap+starttls:// und ldap://, eigenes CA-Zertifikat, TLS ab 1.2, searchPaginated in 1000er-Seiten. objectGUID kommt als Puffer und wird gemischt-endian zur GUID umsortiert.
  • Abgleich: anlegen, aktualisieren, übernehmen, deaktivieren — nie löschen. Vorgesetzte werden in einem zweiten Durchgang über den DN aufgelöst, gespeichert wird die Kennung.
  • Zeitplan über node-cron im selben Prozess, gestartet aus src/instrumentation.ts, Sperre in der Datenbank. ZEITPLAN_AKTIV=false schaltet ihn ab.
  • Admin → Verzeichnis: Quelle anlegen und bearbeiten, Verbindungstest mit den gemappten Feldern, bearbeitbare Attributzuordnung, CA-Zertifikat sichtbar und entfernbar, Abgleich-Log der letzten zehn Läufe.
  • CSV-Import für Personen und Abteilungsvorschläge aus den department-Werten.

Drei Regeln gegen den teuersten Fehler

Eine kaputte Eingabe darf nicht aussehen wie „alle sind gegangen":

  1. Lässt sich kein einziger gelesener Eintrag zuordnen, wird niemand deaktiviert — der Lauf meldet einen Fehler mit Namen. Ein Tippfehler im Kennungsattribut hätte sonst die gesamte Belegschaft abgeschaltet und dabei ERFOLG gemeldet.
  2. Übersprungene Einträge werden am dn erkannt und aus der Abschaltung genommen: sie standen im Ergebnis, nur ohne brauchbare Kennung.
  3. Eine von Hand angelegte Person wird übernommen, nicht verdoppelt — beim Onboarding entsteht sie hier und das AD-Konto danach.

Prüfung

pnpm lint && pnpm typecheck && pnpm format:pruefen && pnpm test && pnpm pruefe:doku grün — 1098 Tests (vorher 980), davon 28 gegen einen echten OpenLDAP-Container. 71 Ende-zu-Ende-Tests (vorher 67) gegen den gebauten Stand, dazu von Hand durchgeklickt: Attributzuordnung ändern, speichern, neu laden, in der Datenbank nachgesehen. Screenshots in docs/screenshots/m11/.

Der unabhängige Review fand einen Blocker (Regel 1 oben), acht Befunde und sieben Anmerkungen; alle sind abgearbeitet und in docs/issues/016-verzeichnis-ldap.md festgehalten.

Closes #16

🤖 Generated with Claude Code

Meilenstein M11: Personen der eigenen Firma kommen aus dem Active Directory. ## Was drin ist - **LDAP-Schicht** unter `src/server/ldap/`: `ldaps://`, `ldap+starttls://` und `ldap://`, eigenes CA-Zertifikat, TLS ab 1.2, `searchPaginated` in 1000er-Seiten. `objectGUID` kommt als Puffer und wird gemischt-endian zur GUID umsortiert. - **Abgleich**: anlegen, aktualisieren, übernehmen, deaktivieren — nie löschen. Vorgesetzte werden in einem zweiten Durchgang über den DN aufgelöst, gespeichert wird die Kennung. - **Zeitplan** über `node-cron` im selben Prozess, gestartet aus `src/instrumentation.ts`, Sperre in der Datenbank. `ZEITPLAN_AKTIV=false` schaltet ihn ab. - **Admin → Verzeichnis**: Quelle anlegen und bearbeiten, Verbindungstest mit den gemappten Feldern, bearbeitbare Attributzuordnung, CA-Zertifikat sichtbar und entfernbar, Abgleich-Log der letzten zehn Läufe. - **CSV-Import** für Personen und **Abteilungsvorschläge** aus den `department`-Werten. ## Drei Regeln gegen den teuersten Fehler Eine kaputte Eingabe darf nicht aussehen wie „alle sind gegangen": 1. Lässt sich **kein einziger** gelesener Eintrag zuordnen, wird niemand deaktiviert — der Lauf meldet einen Fehler mit Namen. Ein Tippfehler im Kennungsattribut hätte sonst die gesamte Belegschaft abgeschaltet und dabei `ERFOLG` gemeldet. 2. Übersprungene Einträge werden am `dn` erkannt und aus der Abschaltung genommen: sie standen im Ergebnis, nur ohne brauchbare Kennung. 3. Eine von Hand angelegte Person wird **übernommen**, nicht verdoppelt — beim Onboarding entsteht sie hier und das AD-Konto danach. ## Prüfung `pnpm lint && pnpm typecheck && pnpm format:pruefen && pnpm test && pnpm pruefe:doku` grün — **1098 Tests** (vorher 980), davon 28 gegen einen echten OpenLDAP-Container. **71 Ende-zu-Ende-Tests** (vorher 67) gegen den **gebauten** Stand, dazu von Hand durchgeklickt: Attributzuordnung ändern, speichern, neu laden, in der Datenbank nachgesehen. Screenshots in `docs/screenshots/m11/`. Der unabhängige Review fand einen Blocker (Regel 1 oben), acht Befunde und sieben Anmerkungen; alle sind abgearbeitet und in `docs/issues/016-verzeichnis-ldap.md` festgehalten. Closes #16 🤖 Generated with [Claude Code](https://claude.com/claude-code)
florian.wilde added 1 commit 2026-09-26 00:21:47 +00:00
feat(verzeichnis): LDAP-Abgleich, Zeitplan, CSV-Import und Log
Prüfung / pruefung (push) Canceled after 0s
Prüfung / pruefung (pull_request) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
Prüfung / e2e (pull_request) Canceled after 0s
16059e7846
Quelle anlegen, Verbindung testen, nach Zeitplan oder auf Knopfdruck
abgleichen. Gelesen wird seitenweise mit searchPaginated, objectGUID
kommt als Puffer und wird gemischt-endian zur GUID umsortiert. Wer im
Verzeichnis verschwindet, wird hier inaktiv und nie geloescht.

Drei Regeln verhindern, dass eine kaputte Eingabe wie "alle sind
gegangen" aussieht: laesst sich kein einziger Eintrag zuordnen, wird
niemand deaktiviert; uebersprungene Eintraege werden am dn erkannt und
ausgenommen; eine von Hand angelegte Person wird uebernommen statt
verdoppelt.

Der Zeitplan laeuft ueber node-cron im selben Prozess, gestartet aus
src/instrumentation.ts, und nimmt keine eigene Sperre - die liegt in der
Datenbank, damit zwei Instanzen sich einig sind.

Closes #16

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
florian.wilde merged commit ae290345b7 into main 2026-09-26 00:21:57 +00:00
florian.wilde deleted branch feat/16-verzeichnis-ldap 2026-09-26 00:21:57 +00:00
Sign in to join this conversation.