feat(stammdaten): Mitarbeiter, Abteilungen und Geraete #25

Merged
florian.wilde merged 1 commits from feat/11-mitarbeiter-geraete into main 2026-09-25 10:52:45 +00:00
Owner

Schließt #11.

Die Stammdaten, an denen die Historie hängt: Personen, Abteilungen und Geräte. Gelöscht wird nichts, woran ein Lauf hängen kann — Personen werden deaktiviert, Geräte und Abteilungen archiviert.

Was dazugekommen ist

  • Mitarbeiterliste mit Suche über Anzeigename, Mail, UPN und sAMAccountName (im Ticket steht mal das eine, mal das andere), Filter nach Abteilung, standardmäßig nur aktive. Die Suche ist ein eigenes Bauteil, weil #013 sie beim Starten eines Laufs und #014 beim Zuweisen eines Geräts wieder braucht.
  • Personenseite mit Stammdaten, zugeordneten Geräten und Vorgesetztem. Wer aus dem Verzeichnis kommt, ist vollständig gesperrt — alle Stammdaten werden dort gepflegt, und der nächste Abgleich würde eine Änderung ohnehin zurückdrehen. Deaktivieren bleibt möglich: das Offboarding wartet nicht auf den nächsten Abgleich.
  • Abteilungen unter Admin mit Ziel-OU, Standardgruppen und Mail-Domain — daraus entstehen in #012 die Befehle, die ein Konto anlegen. Dazu die Namen, die bei Personen vorkommen, aber nicht gepflegt sind: ohne Ziel-OU bleiben {{ou}} und {{gruppen}} im Lauf leer, und genau das soll man sehen.
  • Geräte mit Suche über Hostname, Bezeichnung, Seriennummer und Tag-Code, CSV-Import mit einem Ergebnis je Zeile.
  • Neues Recht mitarbeiterBearbeiten (ADMIN, REDAKTEUR, TECHNIKER — beim Onboarding steht der Techniker vor der Person, bevor der Abgleich gelaufen ist).

Der Review

Zwei Blocker. Der schwerere meldete Erfolg:

Ein Anführungszeichen, das in einer Zelle beginnt und nicht schließt, verschluckte im CSV-Import alle Folgezeilen bis zum nächsten ". Der Import sagte „3 von 3 Zeilen angelegt“, zwei Geräte fehlten, und in einer Bezeichnung stand der Text der verschluckten Zeilen. Umgekehrt starb der ganze Import an einer Datei, in der nirgends mehr ein " folgte — beides das Gegenteil des Akzeptanzkriteriums.

Die Entscheidung dazu: ein Wert reicht standardmäßig nicht über die Zeile hinaus. Das Format erlaubt es, und csvErzeugen schreibt es auch so; beim Lesen einer fremden Datei ist es trotzdem die schlechtere Annahme. Ein Umbruch in einem Hostnamen kommt nicht vor, ein vergessenes schließendes Anführungszeichen ständig — und mit dieser Grenze endet der Schaden an der Zeile, in der er beginnt.

Der zweite Blocker: ungepflegteAbteilungen gruppierte über alle Kunden hinweg. „Vertrieb“ galt als gepflegt, sobald irgendein Kunde eine Abteilung dieses Namens hatte.

Dazu sieben weitere Befunde, alle behoben:

  • Die Besitzerauswahl bot Personen fremder Kunden an — der Dienst wies die Wahl ab, aber erst nach dem Klick.
  • Ein Techniker konnte ein Gerät endgültig löschen und damit den Tag-Code für immer verbrennen. Das verlangt jetzt verwaltung; die Ausnahme steht ausdrücklich in CLAUDE.md.
  • Derselbe Kunde wurde in zwei Listen verschieden dargestellt.
  • Ein Kommentar versprach zwei verschiedene Meldungen, gerendert wurde eine — der vierte Meilenstein in Folge mit dieser Sorte Fehler.
  • FELD stand neunmal wortgleich in neun Dateien.
  • Die E2E-Tests ließen ihre Daten liegen; sie räumen jetzt über die Datenbank auf, weil die Anwendung bewusst keinen Löschweg kennt.

Offen geblieben

Ab 501 aktiven Personen lässt sich ein Besitzer nicht mehr über das Auswahlfeld zuordnen. Die Zuweisung mit Suche kommt mit #014; bis dahin sagt das Formular es ausdrücklich, statt einen Weg zu versprechen, den es nicht gibt.

Prüfung

pnpm lint && pnpm typecheck && pnpm format:pruefen && pnpm test && pnpm pruefe:doku grün, 610 Tests, dazu 18 E2E-Abläufe gegen den gebauten Stand. Screenshots in docs/screenshots/m6/, je Desktop und Handy, kein horizontales Scrollen bei 390 px.

🤖 Generated with Claude Code

Schließt #11. Die Stammdaten, an denen die Historie hängt: Personen, Abteilungen und Geräte. **Gelöscht wird nichts**, woran ein Lauf hängen kann — Personen werden deaktiviert, Geräte und Abteilungen archiviert. ## Was dazugekommen ist - **Mitarbeiterliste** mit Suche über Anzeigename, Mail, UPN und sAMAccountName (im Ticket steht mal das eine, mal das andere), Filter nach Abteilung, standardmäßig nur aktive. Die Suche ist ein eigenes Bauteil, weil #013 sie beim Starten eines Laufs und #014 beim Zuweisen eines Geräts wieder braucht. - **Personenseite** mit Stammdaten, zugeordneten Geräten und Vorgesetztem. Wer aus dem Verzeichnis kommt, ist vollständig gesperrt — alle Stammdaten werden dort gepflegt, und der nächste Abgleich würde eine Änderung ohnehin zurückdrehen. Deaktivieren bleibt möglich: das Offboarding wartet nicht auf den nächsten Abgleich. - **Abteilungen** unter Admin mit Ziel-OU, Standardgruppen und Mail-Domain — daraus entstehen in #012 die Befehle, die ein Konto anlegen. Dazu die Namen, die bei Personen vorkommen, aber nicht gepflegt sind: ohne Ziel-OU bleiben `{{ou}}` und `{{gruppen}}` im Lauf leer, und genau das soll man sehen. - **Geräte** mit Suche über Hostname, Bezeichnung, Seriennummer und Tag-Code, CSV-Import mit einem Ergebnis je Zeile. - Neues Recht `mitarbeiterBearbeiten` (ADMIN, REDAKTEUR, TECHNIKER — beim Onboarding steht der Techniker vor der Person, bevor der Abgleich gelaufen ist). ## Der Review **Zwei Blocker.** Der schwerere meldete Erfolg: Ein Anführungszeichen, das in einer Zelle beginnt und nicht schließt, verschluckte im CSV-Import alle Folgezeilen bis zum nächsten `"`. Der Import sagte „3 von 3 Zeilen angelegt“, zwei Geräte fehlten, und in einer Bezeichnung stand der Text der verschluckten Zeilen. Umgekehrt starb der ganze Import an einer Datei, in der nirgends mehr ein `"` folgte — beides das Gegenteil des Akzeptanzkriteriums. Die Entscheidung dazu: **ein Wert reicht standardmäßig nicht über die Zeile hinaus.** Das Format erlaubt es, und `csvErzeugen` schreibt es auch so; beim Lesen einer fremden Datei ist es trotzdem die schlechtere Annahme. Ein Umbruch in einem Hostnamen kommt nicht vor, ein vergessenes schließendes Anführungszeichen ständig — und mit dieser Grenze endet der Schaden an der Zeile, in der er beginnt. Der zweite Blocker: `ungepflegteAbteilungen` gruppierte über alle Kunden hinweg. „Vertrieb“ galt als gepflegt, sobald irgendein Kunde eine Abteilung dieses Namens hatte. Dazu sieben weitere Befunde, alle behoben: - Die Besitzerauswahl bot Personen fremder Kunden an — der Dienst wies die Wahl ab, aber erst nach dem Klick. - Ein Techniker konnte ein Gerät endgültig löschen und damit den Tag-Code für immer verbrennen. Das verlangt jetzt `verwaltung`; die Ausnahme steht ausdrücklich in `CLAUDE.md`. - Derselbe Kunde wurde in zwei Listen verschieden dargestellt. - Ein Kommentar versprach zwei verschiedene Meldungen, gerendert wurde eine — der vierte Meilenstein in Folge mit dieser Sorte Fehler. - `FELD` stand neunmal wortgleich in neun Dateien. - Die E2E-Tests ließen ihre Daten liegen; sie räumen jetzt über die Datenbank auf, weil die Anwendung bewusst keinen Löschweg kennt. ## Offen geblieben Ab 501 aktiven Personen lässt sich ein Besitzer nicht mehr über das Auswahlfeld zuordnen. Die Zuweisung mit Suche kommt mit #014; bis dahin sagt das Formular es ausdrücklich, statt einen Weg zu versprechen, den es nicht gibt. ## Prüfung `pnpm lint && pnpm typecheck && pnpm format:pruefen && pnpm test && pnpm pruefe:doku` grün, **610 Tests**, dazu **18 E2E-Abläufe** gegen den gebauten Stand. Screenshots in `docs/screenshots/m6/`, je Desktop und Handy, kein horizontales Scrollen bei 390 px. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
florian.wilde added 1 commit 2026-09-25 10:52:33 +00:00
feat(stammdaten): Mitarbeiter, Abteilungen und Geraete
Prüfung / pruefung (pull_request) Canceled after 0s
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (pull_request) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
86d55917f9
Die Stammdaten, an denen die Historie haengt. Personen werden deaktiviert,
Geraete und Abteilungen archiviert — geloescht wird nichts, woran ein Lauf
haengen kann.

- Mitarbeiterliste mit Suche ueber Anzeigename, Mail, UPN und sAMAccountName,
  Filter nach Abteilung, standardmaessig nur aktive; die Suche ist ein eigenes
  Bauteil, weil #013 und #014 sie wieder brauchen
- Personenseite mit Stammdaten, Geraeten, Vorgesetztem; was aus dem Verzeichnis
  kommt, ist gesperrt — der naechste Abgleich wuerde es ohnehin zurueckdrehen
- Abteilungen unter Admin: Ziel-OU, Standardgruppen, Mail-Domain, dazu die
  Namen, die bei Personen vorkommen, aber nicht gepflegt sind
- Geraete mit Suche ueber Hostname, Bezeichnung, Seriennummer und Tag-Code;
  CSV-Import mit einem Ergebnis je Zeile
- Neues Recht mitarbeiterBearbeiten; die Seitenleiste fuehrt Personen und
  Geraete unter einem Eintrag, im Modus Dienstleistung anders beschriftet

Der unabhaengige Review fand zwei Blocker. Der schwerere meldete Erfolg: ein
nicht geschlossenes Anfuehrungszeichen verschluckte im CSV-Import alle
Folgezeilen bis zum naechsten `"`, und der Import sagte „3 von 3 Zeilen
angelegt". Ein Wert reicht jetzt nicht mehr ueber die Zeile hinaus — fuer
Hostnamen und Seriennummern ist ein Umbruch praktisch immer ein vergessenes
Anfuehrungszeichen, und so endet der Schaden an seiner Zeile. Der zweite:
ungepflegte Abteilungen wurden ueber alle Kunden hinweg gruppiert.

Dazu sieben weitere Befunde, alle behoben — darunter eine Besitzerauswahl, die
Personen fremder Kunden anbot, und ein Techniker, der ein Geraet endgueltig
loeschen konnte.

610 Tests gruen, 18 E2E-Ablaeufe gegen den gebauten Stand.

Schliesst #011

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
florian.wilde merged commit f85bc87324 into main 2026-09-25 10:52:45 +00:00
florian.wilde deleted branch feat/11-mitarbeiter-geraete 2026-09-25 10:52:45 +00:00
Sign in to join this conversation.