Phase 8: Lokale KI

Wiki mit semantischer Suche ueber pgvector, Diktat ueber faster-whisper,
Berichtsassistent und Belegerfassung — alles gegen selbst betriebene
Modelle. Dazu zwei Protokollansichten: was die Maschine getan hat und was
Menschen getan haben.

Nichts, was ein Modell erzeugt, gelangt ungeprueft in einen Nachweis. Jede
Ausgabe ist zuerst ein eigener Datensatz, gekennzeichnet, mit zwei gleich
grossen Knoepfen davor. Die Datenbank haelt gegen: Eingabe, Ausgabe und
Modell sind unveraenderlich, geloescht wird nicht, entschieden wird einmal.

Kein Rueckfall auf einen Anbieter: fehlen die Container, fehlt die Funktion.
Dafuer bleibt alles andere ohne Modell vollstaendig benutzbar — geprueft von
vierzehn E2E-Tests, die ohne laufendes Modell durchlaufen.

Postgres bringt jetzt PostGIS und pgvector mit (eigenes Image), Ollama und
faster-whisper stehen im Compose-Profil "ki".

73 neue Unit-Tests, 14 neue E2E-Tests, Version 0.9.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-04 11:06:03 +02:00
co-authored by Claude Opus 5
parent 12243f177d
commit f7ccd9a908
134 changed files with 8624 additions and 72 deletions
+36 -1
View File
@@ -144,6 +144,15 @@ export const RECHTE = {
bereich: "Benachrichtigungen",
bezeichnung: "Textvorlagen der Wehr bearbeiten",
},
// Wissen und lokale KI (Phase 8)
"wiki.lesen": { bereich: "Wissen", bezeichnung: "Dienstvorschriften und Unterlagen lesen" },
"wiki.bearbeiten": { bereich: "Wissen", bezeichnung: "Wiki-Seiten anlegen und ändern" },
/// Diktat, Berichtsentwurf, Frage ans Wiki. Wer schreibt, darf sich helfen
/// lassen — entschieden wird trotzdem von Hand.
"ki.nutzen": { bereich: "Wissen", bezeichnung: "KI-Unterstützung benutzen" },
"ki.protokoll": { bereich: "Wissen", bezeichnung: "Alle KI-Vorgänge einsehen" },
"beleg.erfassen": { bereich: "Kasse", bezeichnung: "Belege fotografieren und erfassen" },
} as const;
export type Recht = keyof typeof RECHTE;
@@ -172,6 +181,9 @@ const GRUNDRECHTE: Recht[] = [
// Benachrichtigungswege selbst ein — das ist keine Sache des Kommandanten.
"termin.lesen",
"benachrichtigung.eigene",
// Dienstvorschriften sind zum Lesen da. Eine Wehr, in der nur die Führung
// nachschlagen darf, hat kein Wiki, sondern einen Aktenschrank.
"wiki.lesen",
];
/**
@@ -207,6 +219,10 @@ export const ROLLEN_RECHTE: Record<Exclude<Rolle, "SUPERADMIN">, Recht[]> = {
"termin.bearbeiten",
"termin.anwesenheit",
"benachrichtigung.vorlagen",
"wiki.bearbeiten",
"ki.nutzen",
"ki.protokoll",
"beleg.erfassen",
],
GERAETEWART: [
@@ -217,6 +233,7 @@ export const ROLLEN_RECHTE: Record<Exclude<Rolle, "SUPERADMIN">, Recht[]> = {
"pruefung.planen",
"pruefung.durchfuehren",
"datei.hochladen",
"ki.nutzen",
],
ATEMSCHUTZGERAETEWART: [
@@ -228,9 +245,20 @@ export const ROLLEN_RECHTE: Record<Exclude<Rolle, "SUPERADMIN">, Recht[]> = {
"atemschutz.bearbeiten",
"atemschutz.ueberwachung",
"datei.hochladen",
"ki.nutzen",
],
KASSIER: [...GRUNDRECHTE, "kasse.lesen", "kasse.bearbeiten", "kasse.abschluss", "datei.hochladen"],
KASSIER: [
...GRUNDRECHTE,
"kasse.lesen",
"kasse.bearbeiten",
"kasse.abschluss",
"datei.hochladen",
// Die Belegerfassung gehört zur Kasse: der Kassier fotografiert die
// Quittung und zeichnet gegen, was das Modell gelesen hat.
"beleg.erfassen",
"ki.nutzen",
],
SCHRIFTFUEHRER: [
...GRUNDRECHTE,
@@ -244,6 +272,10 @@ export const ROLLEN_RECHTE: Record<Exclude<Rolle, "SUPERADMIN">, Recht[]> = {
"termin.bearbeiten",
"termin.anwesenheit",
"benachrichtigung.vorlagen",
// Und er ist derjenige, der Berichte schreibt — also derjenige, dem
// Diktat und Berichtsentwurf am meisten nützen.
"wiki.bearbeiten",
"ki.nutzen",
],
AUSBILDER: [
@@ -254,6 +286,9 @@ export const ROLLEN_RECHTE: Record<Exclude<Rolle, "SUPERADMIN">, Recht[]> = {
// Übungstermine anlegen und die Anwesenheit abhaken gehört zur Ausbildung.
"termin.bearbeiten",
"termin.anwesenheit",
// Ausbildungsunterlagen sind der halbe Inhalt des Wikis.
"wiki.bearbeiten",
"ki.nutzen",
],
MITGLIED: [...GRUNDRECHTE],