From 98bce1b0da675715b2e5482c0ad61ba21135f62f Mon Sep 17 00:00:00 2001
From: Server-Bibliothek <server-bibliothek@lokal>
Date: Di, 04 Aug 2026 07:00:04 +0200
Subject: [PATCH] Add a desktop client that knows what is installed locally

---
 packages/bibliothek-types/src/index.ts |  160 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 160 insertions(+), 0 deletions(-)

diff --git a/packages/bibliothek-types/src/index.ts b/packages/bibliothek-types/src/index.ts
new file mode 100644
index 0000000..a5250b8
--- /dev/null
+++ b/packages/bibliothek-types/src/index.ts
@@ -0,0 +1,160 @@
+/** Geteilte Typen zwischen Server und Client. */
+
+/**
+ * Bezugsquelle, aus der die Datei einer Software geholt und aktuell gehalten wird.
+ * `manuell` bedeutet: die Datei wird von Hand hochgeladen und nicht automatisch aktualisiert.
+ */
+export type QuelleTyp = 'direkt' | 'github' | 'winget' | 'svn' | 'git' | 'manuell';
+
+/** Einstufung einer Software — gliedert den Katalog und steuert die Hinweise. */
+export type Einstufung = 'lizenzfrei' | 'lizenzpflichtig' | 'intern';
+
+/** Alle Einstufungen mit Anzeigetext, in der Reihenfolge der Katalog-Reiter. */
+export const EINSTUFUNGEN: Array<{ id: Einstufung; text: string }> = [
+  { id: 'lizenzfrei', text: 'Lizenzfrei' },
+  { id: 'lizenzpflichtig', text: 'Lizenzpflichtig' },
+  { id: 'intern', text: 'Intern' },
+];
+
+/**
+ * Wie das Programm auf den Rechner kommt. `unbestimmt` ist der Ausgangswert —
+ * ein Eintrag muss nicht sofort eingeordnet werden.
+ */
+export type Programmart = 'unbestimmt' | 'installer' | 'eigenstaendig';
+
+/** Alle Programmarten mit Anzeigetext, in der Reihenfolge des Auswahlfelds. */
+export const PROGRAMMARTEN: Array<{ id: Programmart; text: string }> = [
+  { id: 'unbestimmt', text: 'Unbestimmt' },
+  { id: 'installer', text: 'Installationsprogramm' },
+  { id: 'eigenstaendig', text: 'Eigenständiges Programm' },
+];
+
+/** Ein Bau-Geheimnis, das ein Repository für seinen Bau anfordert. */
+export interface GeheimnisBedarf {
+  /** Name der Umgebungsvariablen, z. B. `ANTHROPIC_API_KEY`. */
+  name: string;
+  beschreibung: string;
+}
+
+/** Stand eines Bau-Geheimnisses in der Oberfläche — nie der Wert selbst. */
+export interface GeheimnisUebersicht {
+  name: string;
+  hinterlegt: boolean;
+  zeichen: number;
+}
+
+/** Ein Software-Eintrag im Katalog. */
+export interface Software {
+  id: number;
+  name: string;
+  beschreibung: string;
+  /** Id der übergeordneten Software, falls dieser Eintrag ein Zusatzinhalt dazu ist (0 = eigenständiges Tool). */
+  elternId: number;
+  /** Typ der Bezugsquelle (leer, falls noch keine gesetzt). */
+  quelleTyp: QuelleTyp | '';
+  /** Quell-spezifische Angabe: URL (direkt), `besitzer/repo` (github), Paket-ID (winget), Repo-URL (svn/git). Bei `manuell` leer. */
+  quelleWert: string;
+  /** Nur bei Quelle `git`: Befehl, der das Tool baut (im Wurzelverzeichnis der Arbeitskopie ausgeführt). */
+  bauBefehl: string;
+  /** Nur bei Quelle `git`: Pfad des Bau-Ergebnisses relativ zur Arbeitskopie, `*` im Dateinamen erlaubt. */
+  bauErgebnis: string;
+  /** Einstufung: lizenzfrei, lizenzpflichtig (Schlüssel über den Support) oder intern (Eigenentwicklung). */
+  einstufung: Einstufung;
+  /** Installationsprogramm oder eigenständige Datei — bestimmt den Hinweis am Eintrag. */
+  programmart: Programmart;
+  /** Freier Hinweis am Eintrag, z. B. „braucht Adminrechte". Leer = keiner. */
+  hinweis: string;
+  /** Link zur Anleitung (WikiJS intern oder extern), leer falls keine hinterlegt. */
+  anleitungUrl: string;
+  /** Aktuelle Versions-/Stand-Kennung, vom Abgleich gesetzt (Release-Tag, ETag, winget-Version, SVN-Revision). */
+  version: string;
+  /** Aktuell bereitgestellte Datei im Ablageordner (leer, solange noch nichts vorliegt). */
+  dateiname: string;
+  /** Zeitpunkt, zu dem die bereitgestellte Datei zuletzt tatsächlich erneuert wurde (unser Abruf). */
+  dateiStandVom: string;
+  /** Veröffentlichungsdatum beim Anbieter, sofern die Quelle es mitliefert. */
+  veroeffentlichtAm: string;
+  /** Windows-Signaturstatus der bereitgestellten Datei (Valid, NotSigned, …). */
+  signaturStatus: string;
+  /** Signaturgeber der bereitgestellten Datei (leer, wenn unsigniert). */
+  signaturHerausgeber: string;
+  /** Optional: erwarteter Signaturgeber. Weicht er ab, wird die Datei nicht bereitgestellt. */
+  erwarteterHerausgeber: string;
+  /** Vom Repository angeforderte Bau-Geheimnisse (aus `software-bibliothek.json`). */
+  benoetigteGeheimnisse: GeheimnisBedarf[];
+  /** Zeitpunkt des letzten Abgleichs (leer, falls nie geprüft). */
+  letzterAbgleich: string;
+  /** War der letzte Abgleich erfolgreich? */
+  abgleichErfolg: boolean;
+  /** Meldung des letzten Abgleichs (z.B. „Aktualisiert." oder ein Fehlertext). */
+  abgleichMeldung: string;
+  erstelltAm: string;
+  aktualisiertAm: string;
+}
+
+/** Nutzlast beim Anlegen/Bearbeiten (server-verwaltete Felder wie Version/Datei/Abgleich ausgenommen). */
+export interface SoftwareEingabe {
+  name: string;
+  beschreibung: string;
+  elternId: number;
+  quelleTyp: QuelleTyp | '';
+  quelleWert: string;
+  bauBefehl: string;
+  bauErgebnis: string;
+  einstufung: Einstufung;
+  programmart: Programmart;
+  hinweis: string;
+  anleitungUrl: string;
+  erwarteterHerausgeber: string;
+}
+
+/** Ergebnis eines Bezugsquellen-Abgleichs, das in die DB zurückgeschrieben wird. */
+export interface AbgleichErgebnis {
+  version: string;
+  dateiname: string;
+  erfolg: boolean;
+  meldung: string;
+  /** Wurde tatsächlich eine neue Datei bereitgestellt? Nur dann zählt es als Update. */
+  geaendert: boolean;
+  signaturStatus: string;
+  signaturHerausgeber: string;
+  veroeffentlichtAm: string;
+  benoetigteGeheimnisse: GeheimnisBedarf[];
+}
+
+/** Einstellungen der Anwendung (Datei `konfiguration.json` neben der Anwendung). */
+export interface Einstellungen {
+  /** Ablageort für Datenbank und Programm-Dateien. Leer = Ordner „data" neben der Anwendung. */
+  datenOrdner: string;
+  /** Port, auf dem die Oberfläche erreichbar ist. */
+  port: number;
+  /**
+   * Kennung für Git-Zugriffe über SSH. Leer = die SSH-Konfiguration des
+   * Dienstbenutzers entscheidet. Hier zentral gepflegt, damit ein Kontowechsel
+   * keine Anpassung an den Katalogeinträgen erfordert.
+   */
+  gitBenutzer: string;
+  /** Optionaler Pfad zum privaten SSH-Schlüssel für Git-Zugriffe. */
+  gitSchluessel: string;
+}
+
+/** Einstellungen samt der daraus abgeleiteten, tatsächlich genutzten Pfade. */
+export interface EinstellungenAnsicht {
+  einstellungen: Einstellungen;
+  /** Vollständiger Pfad der Konfigurationsdatei. */
+  konfigurationsDatei: string;
+  /** Tatsächlich verwendeter Datenordner (aufgelöst aus der Einstellung). */
+  effektiverDatenOrdner: string;
+  /** Läuft gerade auf diesem Port (Änderungen wirken erst nach Neustart). */
+  laufenderPort: number;
+}
+
+/** Ein protokollierter Zugriff/Download aus dem Netzwerk. */
+export interface ZugriffslogEintrag {
+  id: number;
+  zeitpunkt: string;
+  ipAdresse: string;
+  rechnername: string;
+  angegebenerName: string;
+  aktion: string;
+}

--
Gitblit v1.9.3