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

---
 desktop/frontend/src/bruecke.ts |   69 ++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/desktop/frontend/src/bruecke.ts b/desktop/frontend/src/bruecke.ts
new file mode 100644
index 0000000..67b919c
--- /dev/null
+++ b/desktop/frontend/src/bruecke.ts
@@ -0,0 +1,69 @@
+/**
+ * Typisierter Zugang zur Python-Seite.
+ *
+ * pywebview hängt seine Brücke erst ein, wenn das Fenster bereit ist, und meldet
+ * das über das Ereignis `pywebviewready`. Jeder Aufruf davor liefe ins Leere —
+ * deshalb wartet `bruecke()` einmalig darauf.
+ */
+import type { Software } from 'bibliothek-types';
+
+/** Zustand einer Datei im Werkzeug-Ordner, ermittelt über ihre Prüfsumme. */
+export type LokalerZustand = 'fehlt' | 'aktuell' | 'veraltet' | 'fremd';
+
+export interface LokalerBefund {
+  zustand: LokalerZustand;
+  dateiname: string;
+  abgelegteVersion: string;
+  pfad: string;
+}
+
+/** Katalogeintrag, angereichert um das, was auf diesem Rechner liegt. */
+export interface EintragMitBefund extends Software {
+  /** Nur bei eigenständigen Programmen gefüllt — bei Installern sagt der Ordner nichts. */
+  lokal: LokalerBefund | null;
+  /** Fließt dieser Eintrag in die Update-Meldung ein? */
+  ueberwacht: boolean;
+}
+
+export interface Einstellungen {
+  serverAdresse: string;
+  werkzeugOrdner: string;
+}
+
+interface PywebviewApi {
+  einstellungen(): Promise<{ einstellungen: Einstellungen; vorgaben: Einstellungen }>;
+  einstellungen_speichern(
+    serverAdresse: string,
+    werkzeugOrdner: string
+  ): Promise<{ ok: boolean; einstellungen: Einstellungen; vorgaben: Einstellungen }>;
+  katalog(): Promise<{ ok: boolean; meldung?: string; eintraege: EintragMitBefund[]; ordner?: string }>;
+  herunterladen(
+    softwareId: number,
+    dateiname: string,
+    version: string,
+    programmart: string
+  ): Promise<{ ok: boolean; meldung: string; pfad?: string }>;
+  ordner_oeffnen(unterordner?: string): Promise<{ ok: boolean }>;
+  verknuepfung_anlegen(pfad: string, name: string): Promise<{ ok: boolean; meldung?: string }>;
+}
+
+declare global {
+  interface Window {
+    pywebview?: { api: PywebviewApi };
+  }
+}
+
+let bereit: Promise<PywebviewApi> | undefined;
+
+export function bruecke(): Promise<PywebviewApi> {
+  if (!bereit) {
+    bereit = new Promise((aufloesen) => {
+      if (window.pywebview?.api) {
+        aufloesen(window.pywebview.api);
+        return;
+      }
+      window.addEventListener('pywebviewready', () => aufloesen(window.pywebview!.api), { once: true });
+    });
+  }
+  return bereit;
+}

--
Gitblit v1.9.3