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>
5.7 KiB
5.7 KiB
#011 M6 – Mitarbeiter, Abteilungen, Geräte
Status: erledigt Meilenstein: v0.1.0 Labels: phase-1, backend, frontend Geschätzt: 9 h Tatsächlich: 2 h 15 min
Ziel
Die Stammdaten, an denen die Historie hängt. Mitarbeiter und Geräte werden nie gelöscht, damit archivierte Läufe für immer auf sie zeigen können.
Aufgaben
- Mitarbeiterliste: Suche über Anzeigename, Mail, UPN und
sam, Filter nach Abteilung und Aktiv-Status - Mitarbeitersuche als wiederverwendbare Komponente: standardmäßig nur aktive, Umschalter „auch deaktivierte“ fürs Offboarding
- Mitarbeiterseite: Stammdaten, Abteilung, Vorgesetzter, seine Geräte, alle Läufe chronologisch (Onboarding, Übergaben, Offboarding)
- Mitarbeiter manuell anlegen und bearbeiten (
herkunft = MANUELL); synchronisierte Felder sind beiherkunft = ABGLEICHgesperrt - Deaktivieren statt löschen (
aktiv = false) - Abteilungen: Name (eindeutig je Kunde), Ziel-OU, Standardgruppen (
String[]), Mail-Domain, Notizen - Geräte: Stammdaten nach Vorgabe, Pflichtregel „
hostnameoderbezeichnungmuss gesetzt sein“, Besitzer optional - Geräteliste mit Suche über Hostname, Bezeichnung, Seriennummer und
tagCode, Filter nach Typ - CSV-Import für Geräte (
hostname,label,serialNumber,inventoryNumber,type,model),tagCodewird beim Import erzeugt; eigenersrc/lib/csv.ts - Archivieren statt Löschen, sobald Läufe an einem Gerät oder einer Abteilung hängen
- Screenshots Mitarbeiterliste, Mitarbeiterseite, Geräteliste, Abteilungen in
docs/screenshots/m6/
Akzeptanzkriterien
- Test: Mitarbeitersuche liefert standardmäßig nur
aktiv = true; mit Umschalter auch deaktivierte - Test: ein Gerät ohne
hostnameund ohnebezeichnungwird abgelehnt - Test: ein Gerät mit Läufen lässt sich nicht löschen, nur archivieren
- Test:
tagCodeeines bestehenden Geräts lässt sich nicht ändern - Test: CSV-Import erzeugt je Zeile einen
tagCode, meldet fehlerhafte Zeilen einzeln und bricht nicht ab - Test: bei
herkunft = ABGLEICHlehnt der Service Änderungen an synchronisierten Feldern ab
Beim Bauen aufgefallen
- Der CSV-Import hat Zeilen still verloren und Erfolg gemeldet. Ein Anführungszeichen, das in
einer Zelle beginnt und nicht schließt, verschluckte 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 ist genau das Gegenteil des Akzeptanzkriteriums. Der Zerleger setzt jetzt am Zeilenende neu auf: ein Wert reicht standardmäßig nicht über die Zeile hinaus. Das Format erlaubt es, für Hostnamen und Seriennummern ist ein Umbruch aber praktisch immer ein vergessenes Anführungszeichen — und mit dieser Grenze endet der Schaden an der Zeile, in der er beginnt. Wer eine selbst erzeugte Datei zurückliest, schaltetwerteUeberZeilenein. ungepflegteAbteilungenkannte die Kundengrenze nicht. Gruppiert wurde nach dem Namen allein, also galt „Vertrieb“ als gepflegt, sobald irgendein Kunde eine Abteilung dieses Namens hatte. Beim Kunden ohne sie blieben{{ou}}und{{gruppen}}im Lauf leer, ohne dass die Seite es je sagte. Die Funktion direkt darüber machte es seit jeher richtig — zwei Funktionen im selben Modul, die sich widersprachen.- Die Besitzerauswahl bot Personen fremder Kunden an. Die Liste wurde einmal für die ganze Seite geholt und in jede Karte gegeben. Der Dienst wies die Wahl ab — aber erst nach dem Klick, und die Oberfläche hatte etwas angeboten, das sie nicht einlösen konnte.
- Ein Techniker konnte ein Gerät endgültig löschen. Abteilungen und Mitarbeiter haben gar
keinen Löschweg, Geräte schon — und der Tag-Code ist danach für immer verbrannt. Löschen verlangt
jetzt
verwaltung; die Ausnahme steht ausdrücklich inCLAUDE.md. - Derselbe Kunde wurde zweimal verschieden dargestellt. Die Mitarbeiterliste blendete die eigene Organisation immer aus, die Geräteliste zeigte sie immer an. Im Modus Dienstleistung hieß „keine Kundenangabe“ damit nicht „kein Kunde“, sondern „ausgerechnet dieser eine“. Jetzt liefern beide Lesemodelle den Namen, und die Seite entscheidet anhand des Betriebsmodus, ob sie ihn zeigt.
- Ein Kommentar hat wieder eine Zusage gemacht, die der Code nicht hielt („zwei verschiedene Gründe, aber nicht dieselbe Meldung“) — gerendert wurde nur eine, und wer die Rolle nicht hatte, sah gesperrte Felder ohne jede Erklärung. Vierter Meilenstein in Folge mit genau dieser Sorte Fehler.
FELDstand neunmal wortgleich in neun Dateien. Jetzt einmal insrc/lib/formular.ts.- Die E2E-Tests haben ihre Daten liegen gelassen. Sie können nichts löschen — die Anwendung kennt bewusst keinen Löschweg für Personen und Abteilungen —, also räumen sie am Ende über die Datenbank auf. Ohne das sähe jede Datenbank, gegen die sie laufen, nach ein paar Durchläufen aus wie ein Messie-Keller.
- Die Mitarbeitersuche ist ein eigenes Bauteil (
src/components/mitarbeiter-suche.tsx), weil #013 sie beim Starten eines Laufs und #014 beim Zuweisen eines Geräts wieder braucht.
Offen geblieben
- Ab 501 aktiven Personen lässt sich ein Besitzer nicht mehr über das Auswahlfeld zuordnen. Die
Grenze schützt davor, ein Verzeichnis mit zehntausend Personen in ein
<select>zu gießen; die Zuweisung über die Geräteseite mit Suche kommt mit #014. Bis dahin sagt das Formular es ausdrücklich, statt einen Weg zu versprechen, den es nicht gibt.