# Changelog Alle nennenswerten Änderungen an FLORIAN. Format nach [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), Versionierung nach [Semantic Versioning](https://semver.org/lang/de/). Die Regeln dazu stehen in [docs/VERSIONIERUNG.md](docs/VERSIONIERUNG.md). ## [Unveröffentlicht] Aufräumarbeiten vor Phase 9. Drei Punkte, die sich über mehrere Phasen angesammelt hatten und in jeder Phase Zeit gekostet haben. ### Hinzugefügt - **ESLint** hat endlich eine Konfiguration (`eslint.config.mjs`, Flat Config). Bis dahin gab es das Skript `npm run lint`, aber nichts, was es hätte prüfen können — ein Werkzeug, das aussieht, als prüfe es etwas, und nichts prüft, ist schlechter als gar keines. Bewusst **ohne** Formatierungsregeln: die macht Prettier. Dazu `npm run lint:fix`. - **Eine eigene Wehr für die E2E-Tests.** `npm run db:test-reset` legt `ff-teststelle` neu an — vollständig, mit denselben Beispieldaten, aber unter eigener Kennung. Ein Riegel im Skript bricht ab, wenn die Testkennung mit der der Beispielwehr übereinstimmt. - `tests/e2e/wehr.ts` — Zugangsdaten und Anmeldung an einer Stelle statt achtmal wortgleich in acht Dateien. Schlägt die Anmeldung fehl, sagt die Meldung, dass die Testwehr fehlt, statt zweihundertmal „Timeout". ### Behoben - **Die E2E-Tests schrieben in die Beispielwehr.** Nach fünf Phasen standen dort 120 Atemschutz-Überwachungen statt einer, 115 Geräte statt 45 und 39 Einsätze statt 8. Zweimal fielen Tests aus, weil ein gesuchter Eintrag von Seite 1 gerutscht war; bei jedem Lauf unterschieden sich alle 72 Bildschirmfotos. Der Bestand ist einmal zurückgesetzt, die Tests laufen jetzt gegen die eigene Wehr. - **`
` in einem `

` auf der Einsatzseite** — die Meldung stand seit Phase 3 in der Konsole und ist der klassische Auslöser für einen Hydration-Fehler. Die Wurzel war das `Badge`: es rendert jetzt ein `` statt eines `

`. Ein Abzeichen ist Fließtext-Inhalt, und die Darstellung ändert sich dadurch nicht. - **Die Fehlerfläche der Karte konnte nie etwas anzeigen** — der Zustand dahinter wurde nirgends gesetzt. Eine gescheiterte Abfrage sah damit aus wie „keine Hydranten vorhanden". Gefunden hat das der neue Linter. - **Die Lagekarte rechnete bei jedem Rendern neu.** Ein `?? []` erzeugte jedes Mal ein neues leeres Feld und machte damit zwei `useMemo` wirkungslos — bei einer Karte mit dreißig Elementen und einem Ereignisstrom im Zwei-Sekunden- Takt kein akademischer Punkt. - Deutsche Anführungszeichen in vier Ansichten schlossen mit einem geraden Zoll-Zeichen statt mit dem typografischen. - Unbenutzte Importe in fünf Dateien. ### Geändert - `npm run lint` ruft jetzt `eslint .` statt des in Next 15.5 abgekündigten `next lint`. - **`tests/e2e` ist nicht mehr vom Typecheck ausgenommen.** Die Ausnahme hat beim Umbau einen doppelt deklarierten Bezeichner durchgelassen, den erst der Testlauf gemeldet hat — `npx tsc --noEmit` hatte geschwiegen. --- ## [0.9.0] — 2026-09-04 Phase 8: Lokale KI. Ein Wiki mit semantischer Suche, Diktat, Berichtsassistent und Belegerfassung — alles gegen selbst betriebene Modelle. **Nichts, was ein Modell erzeugt, gelangt ungeprüft in einen Nachweis.** Jede KI-Ausgabe ist zuerst ein eigener Datensatz und nicht ein Feld im Zieldokument. Sie ist gekennzeichnet, sie steht daneben statt mittendrin, und sie braucht zwei gleich große Knöpfe, bevor etwas mit ihr geschieht. **Es läuft alles im Haus.** Ollama und faster-whisper als Container daneben, kein Anbieter, kein Schlüssel. Es gibt keinen Rückfall auf einen Cloud-Dienst: fehlen die Container, fehlt die Funktion. ### Hinzugefügt **Datenmodell** - `KiVorgang` — jede Befragung eines Modells mit Eingabe, Ausgabe, Modell, Dauer und der Entscheidung darüber. Auch Fehlschläge: ein Modell, das dreimal am Tag in eine Zeitüberschreitung läuft, ist eine Information. - `Wikiseite`, `Wikiabschnitt` (mit `vector(768)`) und `Wikiversion`. - `Diktat` mit Aufnahme in MinIO, `Belegentwurf` mit allen Feldern optional — ein Modell, das den Betrag nicht findet, soll nichts erfinden. **Postgres mit pgvector** - Eigenes Image (`docker/postgres/Dockerfile`), weil FLORIAN PostGIS **und** pgvector braucht und es kein offizielles Image mit beidem gibt. - HNSW-Index statt IVFFlat: IVFFlat muss auf gefülltem Bestand trainiert werden, HNSW ist ab der ersten Zeile brauchbar. Ein Wiki wächst Seite für Seite — es gibt nie den Moment, an dem man den Index einmal aufbaut. **Wiki** - Markdown, selbst gerendert **ohne HTML**: der Text kommt von Anwendern, und jeder Weg über `dangerouslySetInnerHTML` wäre ein Weg für ein `