Eine veroeffentlichte Vorlagen-Version ist fuer immer unveraenderlich — daran haengt, dass ein archivierter Lauf in zehn Jahren noch genau die Schritte zeigt, mit denen er gestartet wurde. Die Regel steht deshalb zweimal: im Service, der die verstaendliche Meldung gibt, und in der Datenbank, die die Garantie gibt. Vier Trigger fangen Schreibzugriffe ab, die nicht durch den Service kommen — Migrationen, psql, der Seed und ab Phase 4 die Connectoren — und versperren den Rueckweg nach ENTWURF, der alles andere ausgehebelt haette. - Service: anlegen, Kopfdaten bearbeiten, Entwurf als tiefe Kopie der letzten veroeffentlichten Version, speichern, veroeffentlichen, verwerfen, duplizieren, archivieren - Hoechstens ein Entwurf je Vorlage, durchgesetzt vom partiellen Index; zwei gleichzeitige Klicks auf „Bearbeiten“ bekommen denselben Entwurf statt eines Fehlers - Optimistisches Sperren ueber geaendertAm: wer auf einem ueberholten Stand speichert, wird abgewiesen statt die Arbeit des anderen spurlos zu ersetzen - JSON-Export und -Import samt Format-Dokumentation; der Export ist nachsichtig, der Import streng - src/lib/validierung.ts als einzige Zod-Quelle mit deutschen Meldungen, per ESLint-Regel erzwungen Der unabhaengige Review fand drei Blocker, alle an der Mandantengrenze: der Suchfilter brachte ein zweites OR mit und ueberschrieb die Kundenbedingung, Historie und Aufbau einer Version filterten gar nicht. Zu queries/vorlagen.ts gab es keinen Test — jetzt gibt es tests/vorlagen-sicht.test.ts. 428 Tests gruen (vorher 336). Schliesst #009 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.2 KiB
3.2 KiB
#012 M7 – Platzhalter, Namensregeln, Escaping
Status: offen Meilenstein: v0.1.0 Labels: phase-1, backend, security Geschätzt: 8 h Tatsächlich: –
Ziel
Reine, framework-freie Service-Schicht mit dichter Testabdeckung. Hier entstehen die fertigen PowerShell-Befehle, die der Techniker kopiert — und hier darf nichts schiefgehen, weder beim Escaping noch beim generierten Passwort.
Aufgaben
- Platzhalter-Auflösung
{{key}}in Schritt-Titel, Hilfetext und Befehlstext - Eingebaut aus Gerät und Lauf:
{{hostname}},{{seriennummer}},{{inventarnummer}},{{ticket}},{{datum}},{{techniker}}; im ModusDIENSTLEISTUNGzusätzlich{{kunde}}und{{kundenkuerzel}}, im ModusINTERNleer - Eingebaut aus dem Mitarbeiter:
{{mitarbeiter}}(Alias{{benutzer}}),{{vorname}},{{nachname}},{{upn}},{{sam}},{{mail}},{{abteilung}},{{titel}},{{vorgesetzter}},{{vorgesetzter_sam}},{{dn}},{{ou}} - Aus der gewählten Abteilung:
{{ou}}falls nicht vom Mitarbeiter,{{gruppen}}kommagetrennt {{ou}}eines synchronisierten Mitarbeiters ist der Eltern-Container seinesdn(alles nach dem ersten Komma)- Dazu die in der Vorlage definierten Variablen; unbekannte Platzhalter bleiben sichtbar stehen
{{generiertes_passwort}}: 20 Zeichen aus Groß, Klein, Ziffern und Sonderzeichen ohne verwechselbare Zeichen, je Anzeige neu erzeugt, nie gespeichert; Hinweis „Passwort sofort in den Passwortmanager übernehmen“; in der Druckansicht[Passwort – nicht gespeichert]- Namensregeln (
Einstellung.namensregelnglobal, im ModusDIENSTLEISTUNGzusätzlichKunde.namensregelnmit Fallback):upn,sam(höchstens 20 Zeichen),mail,hostname - Transliteration (ä→ae, ö→oe, ü→ue, ß→ss, Akzente entfernt), Kleinschreibung, Leerzeichen entfernt,
{nnn}-Zähler,{v}für den ersten Buchstaben des Vornamens,{kundenkuerzel} - Shell-Escaping je Shell: PowerShell (doppelte Anführungszeichen verdoppeln, Backtick maskieren), Bash, Cmd
- HTML-Escaping ersetzter Werte; Markdown im Hilfetext sicher gerendert, kein rohes HTML
- „Alle Befehle als Skript kopieren“ je Abschnitt: alle
BEFEHL-Schritte in Reihenfolge, getrennt durch Leerzeilen, je mit# Schritt: <Titel>davor, Zeilenumbruch passend zur Shell
Akzeptanzkriterien
- Test: „Jörg Müller-Lüdenscheid“ ergibt
joerg.mueller-luedenscheid@firma.deundjmuellerluedensch(auf 20 Zeichen gekürzt) - Test:
{{generiertes_passwort}}erscheint im angezeigten Befehl, steht aber nicht inSchrittergebnis,Kommentar,Protokolloder der Druckansicht; zwei Aufrufe liefern verschiedene Passwörter - Test: ein Wert mit
"und`wird für PowerShell korrekt maskiert und bricht den Befehl nicht - Test: unbekannte Platzhalter bleiben als
{{key}}stehen - Test:
{{ou}}wird ausCN=Maria Huber,OU=Buchhaltung,OU=Benutzer,DC=firma,DC=localzuOU=Buchhaltung,OU=Benutzer,DC=firma,DC=local - Test: Skript-Kopie liefert die Befehle in Abschnittsreihenfolge mit Kommentarzeilen
- Test: im Modus
INTERNsind{{kunde}}und{{kundenkuerzel}}leer - Test: ein Wert mit
<script>landet HTML-escaped in der Anzeige