Diese Datei ist für die technische Übergabe gedacht: sie erklärt, wie das
Projekt aufgebaut ist, welche Entscheidungen warum getroffen wurden, und was
bei einer Anpassung an eine andere Infrastruktur zu beachten ist.
Für die Bedienungsanleitung (Endnutzer-Sicht) siehe README.md.
Für die Entwicklungshistorie (was wurde wann gebaut) siehe CHANGELOG.md.
requirements.txtdata/bibliothek.db) – eine einzelne Datei, kein Datenbankserverapp.run(host="0.0.0.0", ...))Bewusste Design-Entscheidung: keine Frameworks/Build-Tools, damit eine Person
ohne Programmiererfahrung (Zielgruppe dieses Projekts) das System mit einem
Doppelklick starten kann, ohne npm install o. Ä.
server-bibliothek/
├── app.py Haupt-Flask-Anwendung, alle Routen
├── updater.py Update-Check-Logik (winget/GitHub/Direkt-Link)
├── automatische_pruefung.py Eigenständiges Skript für geplante Update-Checks
├── requirements.txt Python-Abhängigkeiten (nur Flask)
├── data/
│ ├── bibliothek.db SQLite-Datenbank (wird beim ersten Start angelegt)
│ └── doku_bilder/<software_id>/ Hochgeladene Doku-Screenshots
├── installers/ Standard-Ablageort für Installer-Dateien
│ (Nutzer koennen aber JEDEN Pfad eintragen,
│ dieser Ordner ist nur ein Vorschlag)
├── static/style.css Gesamtes Styling (ein File, keine Build-Pipeline)
├── templates/ Jinja2-HTML-Templates
├── install.bat Einmalige Einrichtung (Python-Abhaengigkeiten)
├── start.bat Startet den Webserver
├── pruefe_updates.bat Manueller Update-Check-Lauf
├── automatisierung_einrichten.bat Richtet taeglichen Update-Check per Windows-Aufgabenplanung ein
├── firewall-freigabe-einrichten.bat Oeffnet Port 5000 in der Windows-Firewall
├── Update-Quellen-Uebersicht.md Nachschlagehilfe fuer winget-IDs/GitHub-Pfade
├── README.md Bedienungsanleitung
├── ARCHITEKTUR.md Diese Datei
└── CHANGELOG.md Entwicklungshistorie
Alle Tabellen werden in init_db() (app.py) angelegt. Migrationen (neue
Spalten) laufen automatisch beim Start via ALTER TABLE ... ADD COLUMN,
bestehende Daten bleiben dabei erhalten.
software – der Tool-Katalog| Spalte | Typ | Bedeutung |
|---|---|---|
| id | INTEGER PK | |
| name | TEXT | Anzeigename, wird auch für Dateinamen-Ableitung sanitisiert |
| kategorie | TEXT | Freitext, für Gruppierung in Checklisten |
| version | TEXT | Bei "direkt"-Update-Quelle: technische Kennung (ETag), keine echte Versionsnummer |
| installer_pfad | TEXT | Ordner oder Datei-Pfad, siehe Abschnitt 4 "Ordner-Konvention" |
| install_parameter | TEXT | Silent-Install-Flags, z. B. /S oder /quiet /norestart |
| dokumentation | TEXT | Freitext-Anleitung |
| letzte_pruefung | TEXT (Datum) | Für die Status-Anzeige (Aktuell/Bitte prüfen/Nie geprüft) |
| erstellt_am | TEXT (Zeitstempel) | |
| auto_update | INTEGER (0/1) | Automatische Aktualisierung aktiv? |
| update_quelle | TEXT | winget | github | direkt | leer |
| update_wert | TEXT | Paket-ID / besitzer/projekt / URL, je nach Quelle |
zuweisungen – einzelne Tool-Zuweisungen (Zeilen eines Protokolls)| Spalte | Bedeutung |
|---|---|
| id, software_id | |
| protokoll_id | FK auf protokolle (siehe unten) |
| mitarbeiter, rechnername | Denormalisiert hier UND im Protokoll gespeichert (Absicht: die Installationsverlauf-Ansicht pro Software bleibt dadurch einfach) |
| installierte_version, installiert_von, installiert_am, notiz |
protokolle – ein Eintrag pro Rechner-Einrichtung| Spalte | Bedeutung |
|---|---|
| id, mitarbeiter, rechnername, datum, erstellt_von, notiz, erstellt_zeitpunkt |
Ein Protokoll fasst mehrere zuweisungen-Zeilen zusammen (1 Protokoll : n
Zuweisungen), damit bei z. B. 40 Mitarbeitern × 40 Tools keine unübersichtliche
flache Liste entsteht, sondern eine Übersicht pro Person/Rechner.
update_log – Protokoll jedes automatischen Update-Checks| Spalte | Bedeutung |
|---|---|
| id, software_id, zeitpunkt, alte_version, neue_version, erfolg (0/1), meldung |
doku_bilder – hochgeladene Screenshots zur Dokumentation| Spalte | Bedeutung |
|---|---|
| id, software_id, dateiname, hochgeladen_am | Datei liegt unter data/doku_bilder/<software_id>/<dateiname> |
updater.py)Das Feld installer_pfad kann zwei Formen haben:
- Datei-Pfad (endet auf .exe/.msi/etc.): ältere/explizite Schreibweise
- Ordner-Pfad (kein Dateiname): empfohlene, aktuelle Schreibweise
Die Funktion updater.effektiver_ablageordner(installer_pfad, name) ist die
zentrale Logik: sie sorgt immer dafür, dass jedes Tool in einem eigenen
Unterordner landet (benannt nach dem sanitisierten Tool-Namen), selbst wenn
im Feld nur ein geteilter Basisordner steht oder ein alter kompletter
Dateipfad. Das verhindert, dass mehrere Tools sich einen Ordner teilen und
Dateien "nackt" nebeneinander landen (siehe CHANGELOG, Runden r6–r8, dort
wurde das mehrfach nachgeschärft, nachdem reale Testfälle Lücken zeigten).
updater.verwaltete_datei_pfad(installer_pfad, name) findet die aktuell
abgelegte Datei (falls vorhanden), inkl. Rückwärtskompatibilität zu Dateien,
die noch am alten, nicht verschachtelten Ort liegen (Übergangslogik).
Wichtig für Weiterentwicklung: Jede neue Stelle im Code, die mit
Installer-Dateien arbeitet, MUSS über diese beiden Funktionen gehen, stattinstaller_pfad direkt zu verwenden – sonst wird die
Unterordner-Garantie umgangen.
updater.pruefe_software(name, quelle, update_wert, aktuelle_version, installer_pfad)
ist der Einstiegspunkt, delegiert an:
pruefe_winget – ruft winget show/winget download auf (nur unterpruefe_github – nutzt die öffentliche GitHub-APIapi.github.com/repos/.../releases/latest), sucht ein .exe/.msi-Assetpruefe_direkt – fester Download-Link, Versionsvergleich überETag/Last-Modified-Header statt echter VersionsnummerAlle drei prüfen zusätzlich, ob die Datei physisch noch existiert – auch
bei gleicher Versionsnummer wird neu heruntergeladen, falls die Datei manuell
gelöscht wurde (Bug wurde in Runde r5 gefunden und behoben).
Vor jedem Ersetzen einer Datei wird über sichern_und_ersetzen() eine
Sicherheitskopie in einen _sicherungen-Unterordner gelegt.
Route /einrichten (app.py) erzeugt bei Bedarf ein individuelles
Installations-Paket (ZIP mit einrichten.ps1 + Rechner-einrichten-starten.bat
+ den echten Installer-Dateien/ZIPs selbst unter tools/<id>.<endung>),
statt vorab für jede Mitarbeiter/Tool-Kombination ein festes Skript zu pflegen.
Wichtige Design-Entscheidung (Runde r16): Die Installer-Dateien werden
bereits beim Erzeugen des Pakets (auf dem PC, der die Checkliste ausfüllt)
eingebettet, nicht erst beim Ausführen auf dem Zielrechner nachgeladen. Ein
früherer Ansatz lud die Dateien per Invoke-WebRequest zur Laufzeit vom
Server nach – das erforderte Netzwerkzugriff des Zielrechners auf den Server
in genau dem Moment der Einrichtung, was in der Praxis nicht immer gegeben
ist (z. B. Rechner noch nicht ans Firmennetz angebunden). Jetzt braucht der
Zielrechner für die eigentliche Installation kein Netzwerk mehr – nur die
abschließende, optionale Meldung ans zentrale Protokoll (/zuweisungen/neu)
versucht noch einen Netzwerkzugriff, scheitert dieser, bleibt trotzdem das
lokale Protokoll (protokoll.log) vollständig.
Ablauf beim Ausführen auf dem Zielrechner:
1. .bat kopiert den kompletten entpackten Ordner (inkl. tools/-
Unterordner mit den echten Installer-Dateien) nach C:\ClientBibliothek
(per xcopy /E /I /Y)
2. Self-Elevation (Admin-Rechte-Anfrage) über Start-Process -Verb RunAs
3. Automatische Windows-Defender-Ausnahme für C:\ClientBibliothek
(Add-MpPreference -ExclusionPath) – ein einziger Pfad statt vieler
Einzelausnahmen
4. Pro ausgewähltem Tool: entweder stille Installation aus der lokal
mitgelieferten Datei unter tools/<id>.<endung> (mit hinterlegtem
Silent-Parameter, .msi läuft über msiexec) oder – bei Tools ohne
einzelne Installer-Datei ("Ordner-Typ", z. B. portable Programme wie
Blender) – die mitgelieferte ZIP-Datei wird nach C:\ClientBibliothek\pakete\
kopiert, bewusst ohne automatisches Entpacken (Entscheidung in Runde
r14: der Zielort für portable Tools variiert, das soll eine Person bewusst
entscheiden)
5. Lokales Protokoll unter C:\ClientBibliothek\protokoll.log
6. Optionaler POST an /zuweisungen/neu auf dem Server, um das zentrale
Protokoll zu befüllen (Rechnername wird dabei über $env:COMPUTERNAME
automatisch erkannt) – best effort, kein Abbruch bei Fehlschlag
Die Ordner-Struktur unter C:\ClientBibliothek:
- \tools – die mitgelieferten Installer-Dateien/ZIPs (Quelle für die
Installation, kommen direkt aus dem heruntergeladenen Paket)
- \pakete – ZIPs von portablen Tools, bleiben bewusst liegen
- \protokoll.log – lokale Mitschrift
Serverseitig teilen sich /einrichten (POST) und /software/<id>/download
die Hilfsfunktion _zippe_ordner_in_bytes() für das ZIP-Packen eines
Ordners, um Code-Duplikation zu vermeiden.
Der Client-Ordner-Pfad ist eine Konstante (CLIENT_ORDNER in app.py,
aktuell C:\ClientBibliothek) – zentral anpassbar, falls die Infrastruktur
einen anderen Standardpfad vorgibt.
msiexec,Add-MpPreference) konnten in der Entwicklungsumgebung (Linux-Sandbox)| Was | Wo |
|---|---|
| Client-Ordner auf Zielrechnern | CLIENT_ORDNER in app.py |
| Port des Webservers | app.run(..., port=5000) am Ende von app.py, sowie in den .bat-Dateien/Firewall-Skript |
| Schwelle "Bitte prüfen"-Warnung | TAGE_BIS_WARNUNG in app.py (aktuell 30 Tage) |
| Erlaubte Bildformate für Doku-Upload | ERLAUBTE_BILD_ENDUNGEN in app.py |
| Max. Uploadgröße | app.config["MAX_CONTENT_LENGTH"] in app.py |
| Versionsmarker (Diagnose, ob neue Version läuft) | APP_VERSION in app.py |