121 lines
8.3 KiB
Markdown
121 lines
8.3 KiB
Markdown
# Changelog
|
||
|
||
Alle nennenswerten Änderungen an Laufzettel werden in dieser Datei dokumentiert.
|
||
|
||
Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/),
|
||
und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||
|
||
## [Unveröffentlicht]
|
||
|
||
### Hinzugefügt
|
||
|
||
- Projektgerüst: Next 16 mit App Router und TypeScript strict, Tailwind 4, Vitest 5,
|
||
Playwright 1.63, ESLint flat config, Prettier, husky mit lint-staged und commitlint (#005)
|
||
- Gestaltung: Design-Token als CSS-Variablen, selbst gehostete Schriften, Wortmarke und
|
||
Bildmarke `[ ✓ ]`, Versionsanzeige unten links (#005)
|
||
- Betriebsstand mit Docker Compose: die Datenbank ist von außen nicht erreichbar — kein
|
||
veröffentlichter Port und ein Netz ohne Gateway; Migrationen laufen beim Start in einem
|
||
eigenen Einmal-Dienst, der Seed bleibt ein bewusster Handgriff (#005)
|
||
- Healthcheck `GET /api/gesundheit` und Sicherheitskopfzeilen samt CSP-Nonce je Anfrage (#005)
|
||
- shadcn/ui eingerichtet: sein Variablen-Vertrag wird aus den Laufzettel-Token gespeist, damit
|
||
kopierte Bauteile ohne Nacharbeit passen (#005)
|
||
- `pnpm pruefe:doku` hält Dokumentation und Code zusammen: Version im Changelog, Issue-Dateien
|
||
gegen ihre Übersicht, keine Verweise auf fehlende Dateien, keine fehlenden Bilder (#005)
|
||
- `pnpm docs:screenshots` erzeugt Screenshots reproduzierbar und prüft dabei gleich, dass am
|
||
Handy nicht horizontal gescrollt wird (#005)
|
||
- Issues, Labels und Meilensteine für alle vier Phasen im Gitea-Tracker (#001–#019)
|
||
- Vollständiges Datenmodell in deutscher Benennung: 20 Tabellen, 9 Aufzählungen, erste
|
||
Migration, idempotenter Seed für Betriebsmodus, eigene Organisation und Administrator (#006)
|
||
- Erzeugung der `tagCode`s für die QR-Aufkleber, mit Vergabebuch, aus dem nie gelöscht wird —
|
||
ein Code kommt auch nach dem Löschen eines Geräts nicht zurück (#006)
|
||
- Verschlüsselung von Geheimnissen mit AES-256-GCM aus `APP_SECRET`, für das LDAP-Bind-Passwort
|
||
und später die Zugangsdaten der Connectoren (#006)
|
||
- Anmeldung über einen generischen OIDC-Anbieter mit Discovery, PKCE, `state` und `nonce`;
|
||
unbekannte Benutzer entstehen beim ersten Login, die Rolle kommt bei jeder Anmeldung neu aus
|
||
den Gruppen (#007)
|
||
- Lokale Anmeldung mit E-Mail und Passwort als Notfallzugang, nur bei `AUTH_LOCAL_ENABLED=true`
|
||
(#007)
|
||
- Rechte in einer Tabelle mit vier Rollen; geprüft ausschließlich serverseitig, Rolle und
|
||
Aktiv-Status pro Anfrage aus der Datenbank (#007)
|
||
- Benutzerverwaltung für Administratoren: Rolle setzen, Konto abschalten, lokales Konto
|
||
anlegen (#007)
|
||
- Navigation zeigt nur, was die eigene Rolle darf (#007)
|
||
- Betriebsmodus **Intern** und **Dienstleistung**, umschaltbar ohne Neustart. Im Modus Intern
|
||
erscheint die eigene Organisation nirgends; der Wechsel nimmt alle Geräte, Personen,
|
||
Abteilungen und Läufe mit, weil jede Zeile ohnehin schon eine Kunden-Zuordnung trägt (#008)
|
||
- Bestätigungsdialog für den Moduswechsel, der die Folgen aus derselben Prüfung zeigt, die der
|
||
Wechsel danach durchsetzt (#008)
|
||
- Kundenverwaltung im Modus Dienstleistung: anlegen, bearbeiten, archivieren statt löschen (#008)
|
||
- Admin → Einstellungen: Betriebsmodus, Name der eigenen Organisation, globale Namensregeln,
|
||
Sperr-OU und die Anzeige der Adresse, die in den QR-Codes steckt (#008)
|
||
- Navigation und Beschriftungen folgen dem Betriebsmodus — ein Codepfad, nur ein- und
|
||
ausgeblendete Einträge (#008)
|
||
- Versionierte Vorlagen: „Bearbeiten“ erzeugt eine tiefe Kopie der zuletzt veröffentlichten
|
||
Version als Entwurf, je Vorlage gibt es höchstens einen. Veröffentlichen hält Zeitpunkt,
|
||
Urheber und Änderungsnotiz fest (#009)
|
||
- Vorlagen duplizieren und archivieren statt löschen (#009)
|
||
- JSON-Export und -Import für Vorlagen, Format dokumentiert in `docs/vorlagen-format.md` (#009)
|
||
- Zwei Redakteure am selben Entwurf treten sich nicht mehr auf die Füße: wer auf einem überholten
|
||
Stand speichert, wird abgewiesen statt die Arbeit des anderen spurlos zu überschreiben (#009)
|
||
- Vorlagenliste mit Suche, Filter nach Kategorie und Schlagwort und dem Kennzeichen
|
||
„Entwurf vorhanden“; eine Vorlage lässt sich anlegen, duplizieren, archivieren und als JSON
|
||
ein- und ausspielen (#010)
|
||
- Vorlagen-Editor: Abschnitte, Schritte und Variablen anlegen, bearbeiten, löschen und sortieren
|
||
— mit dem Finger, der Maus, der Tastatur oder zwei Knöpfen an jeder Zeile (#010)
|
||
- Typabhängige Felder je Schritt: Auswahloptionen, Zahlenbereich mit Einheit, mehrzeiliger Text,
|
||
Shell und Befehlstext; Hilfetexte als Markdown, dazu ein Doku-Link (#010)
|
||
- Warnung im Editor, wenn ein Platzhalter zu keiner Variablen und zu keinem eingebauten Wert
|
||
gehört — sie blockiert nichts, sie zeigt den Tippfehler, bevor der Techniker ihn im Lauf findet
|
||
(#010)
|
||
- Vorschau der Vorlage mit Beispielwerten, so wie ein Lauf sie zeigen wird (#010)
|
||
- Versionsgeschichte je Vorlage: wer wann mit welcher Notiz veröffentlicht hat und wie viele Läufe
|
||
an einer Version hängen (#010)
|
||
|
||
### Sicherheit
|
||
|
||
- Der Compose-Stand bricht ab, wenn `APP_SECRET`, `POSTGRES_PASSWORD` oder `APP_URL` fehlen,
|
||
statt mit Standardwerten zu starten (#005)
|
||
- Die Mandantengrenze steht als zusammengesetzter Fremdschlüssel in der Datenbank: ein Lauf kann
|
||
strukturell kein Gerät, keine Person und keine Abteilung eines fremden Kunden wählen (#006)
|
||
- Ein Bind-Passwort ohne Versionspräfix wird von der Datenbank abgewiesen, ein versehentlich im
|
||
Klartext geschriebenes fällt damit sofort auf (#006)
|
||
- Ein Lauf nimmt seine Schrittergebnisse und Kommentare beim Löschen nicht mehr mit, und ein
|
||
Protokolleintrag kann seinen Urheber nicht mehr verlieren (#006)
|
||
- Das Rücksprungziel nach der Anmeldung wird aufgelöst und gegen die eigene Herkunft geprüft,
|
||
statt nur Präfixe zu vergleichen — `/<TAB>/fremd.example` wäre sonst eine offene Weiterleitung
|
||
gewesen (#007)
|
||
- Alle Umleitungen gehen über `APP_URL` statt über die Herkunft der Anfrage; hinter einem Reverse
|
||
Proxy zeigten sie sonst auf den internen Host (#007)
|
||
- Eine Anmeldung über den Anbieter verknüpft nur mit einem bestehenden Konto, wenn die Adresse
|
||
bestätigt ist (#007)
|
||
- Ohne eingerichtete `OIDC_GROUP_*`-Zuordnung bleibt die Rolle unangetastet, statt jeden auf
|
||
`LESER` herabzustufen (#007)
|
||
- Der letzte aktive Administrator kann sich weder herabstufen noch abschalten (#007)
|
||
- Beim Abschalten eines Kontos werden laufende Sitzungen sofort ungültig (#007)
|
||
- Im Modus Intern wird eine vom Client mitgeschickte Kunden-Zuordnung verworfen, nicht bloß
|
||
abgelehnt — es gibt in diesem Modus keine Kundenwahl (#008)
|
||
- Der Rückweg nach Intern wird abgelehnt, solange mehr als ein nicht archivierter Kunde
|
||
existiert (#008)
|
||
- Die eigene Organisation lässt sich nicht archivieren (#008)
|
||
- Eine veröffentlichte Vorlagen-Version ist unveränderlich: jeder Schreibversuch wird abgewiesen,
|
||
und ein bestehender Lauf zeigt auch nach neuen Veröffentlichungen genau die Schritte, mit denen
|
||
er gestartet wurde (#009)
|
||
- Die Unveränderlichkeit setzt zusätzlich die Datenbank durch, damit auch Migrationen, `psql` und
|
||
spätere Connectoren nicht daran vorbeischreiben können; der Rückweg nach Entwurf ist versperrt
|
||
(#009)
|
||
- Vorlagen eines fremden Kunden bleiben auch bei Suche und Filtern verborgen, und Historie wie
|
||
Aufbau einer Version geben nichts heraus, was der Benutzer nicht sehen darf (#009)
|
||
- Der Doku-Link eines Schritts nimmt nur `http` und `https` an; über eine importierte Datei wäre
|
||
ein `javascript:`-Link sonst fremder Code im Browser des Technikers (#009)
|
||
- Hilfetexte werden als Markdown ohne rohes HTML gerendert — ein Skript im Hilfetext einer
|
||
eingespielten Vorlage bleibt sichtbarer Text (#010)
|
||
- Der Doku-Link eines Schritts wird auch in der Vorschau nur dann verlinkt, wenn er `http` oder
|
||
`https` ist — dort hat ihn das Schema noch nicht gesehen (#010)
|
||
- Die Content-Security-Policy lockert `unsafe-eval` und WebSocket-Verbindungen **nur** im
|
||
Entwicklungsmodus; ein Test prüft die Entscheidung im Proxy selbst und nicht bloß die Funktion
|
||
darunter (#010)
|
||
- Eine abgelaufene Anmeldung beendet den Vorgang mit einer Meldung, statt die Seite auszuhängen —
|
||
im Editor wäre sonst jede ungespeicherte Arbeit verloren gewesen (#010)
|
||
- Eine archivierte Kundenzuordnung bleibt beim Speichern der Kopfdaten erhalten, statt sich
|
||
stillschweigend in „für alle Kunden“ zu verwandeln (#010)
|