# CLAUDE.md
Spreche mit mir auf Deutsch! (Communicate with me in German!)
## Projektübersicht
DocuMentor (ehemals xsl-validator) ist eine PySide6-basierte Desktop-Anwendung zur Verwaltung und Validierung von XSL-Transformationen mit XML-Dateien. Sie bietet eine GUI zur Konfiguration von Transformations-Toolchains (Saxon, Apache FOP, diff-pdf) und zur Verwaltung von PDF-Generierungsprojekten mit PostgreSQL-Datenbankintegration.
## Anvisiertes Nutzungsszenario
Der primäre Einsatz ist die kontinuierliche Weiterentwicklung von PDF-Dokumenten in Flexnow (Software zur Prüfungsverwaltung). Dabei handelt es sich beispielsweise um amtliche Urkunden, Zeugnisse und Bescheide.
Die Basis bilden etwa 100 XSL-Dateien. Die meisten sind mittels `` bzw. `` miteinander verknüpft (ähnlich der Klassen-Vererbung). Daher können sich Änderungen in einer XSL-Datei auf (unerwartet) viele andere auswirken. Um diese Auswirkungen im Auge zu behalten, wird DocuMentor entwickelt.
**Typischer Workflow:**
1. Entwickler führt benötigte Änderungen an den XSL-Dateien durch
2. Entwickler startet die Transformation im DocuMentor und begutachtet die generierte PDF-Diff
3. Prüfung: Wurden die richtigen PDF-Dateien geändert?
4. Prüfung: Hat die Änderung der XSL-Dateien die erhoffte Änderung in den PDF-Dateien ergeben?
Diese Schritte können sich mehrfach wiederholen.
Da der DocuMentor permanent im Hintergrund läuft, ist ein sparsamer Umgang mit RAM wichtig.
## PySide6-GUI
- Beim Erstellen neuer Dialoge und Fenster sollte immer eine entsprechende UI-Datei erstellt werden
- Der Entwickler sollte später in der Lage sein, den neuen Dialog bzw. Fenster über diese UI-Datei zu gestalten
- Aus der UI-Datei wird in Visual Studio Code über eine Erweiterung automatisch eine .py-Datei erzeugt
- Die automatisch generierte .py-Datei muss in den Code eingebunden und verwendet werden
## Entwicklungskommandos
### Paketverwaltung
Dieses Projekt verwendet den `uv` Paketmanager (nicht pip oder poetry):
```bash
uv sync # Abhängigkeiten installieren
uv run python src/main.py # Anwendung starten
uv run python test_hash_implementation.py # Hash-Tests ausführen
```
### Linting
```bash
uv run ruff check # Code-Style prüfen (Zeilenlänge: 120)
uv run ruff format # Code formatieren
```
## Architektur
### Konfigurationssystem (src/conf.py)
Die Anwendung verwendet ein zentralisiertes Konfigurationsmodell mit Pydantic:
- **AppSettings**: Globales Singleton (`app_settings`), das die gesamte Anwendungskonfiguration speichert
- Wird an plattformspezifischen Orten gespeichert:
- Linux: `~/.config/DocuMentor/config.json`
- Windows: `%APPDATA%\DocuMentor\config.json`
- macOS: `~/Library/Application Support/DocuMentor/config.json`
- Enthält Listen von Tools: `java_vms`, `saxon_jars`, `apache_fops`, `diff_pdfs`, `xsl_dirs`, `postgresql_dbs`
- **ProjectData**: Projektspezifische Einstellungen, die in `project.yaml` im jeweiligen Projektverzeichnis gespeichert werden
- Enthält hierarchische Baumstruktur von Transformationsknoten
- Verwendet `TreeNode` und `XslFile` zur Organisation
- Jede `XmlFile` hat eine optionale `hashsum` (blake2b) zur Änderungsverfolgung
### Wichtige Datenmodelle
1. **Tool-Konfigurationsmodelle** (JavaVm, SaxonJar, ApacheFop, DiffPdf, XslDir, PostgreSqlDb):
- Jedes hat eine `id` und `version`
- Speichert Pfade zu Binärdateien/Verzeichnissen
2. **Project-Modell**:
- Referenziert Tool-Konfigurationen über ID
- Verlinkt zu einem Projektverzeichnis mit `project.yaml`
- Hat Hilfsmethoden wie `getXsl()`, `getJavaVm()` um IDs in Namen/Versionen aufzulösen
3. **Baumstruktur** (TreeNode → XslFile → XmlFile):
- Hierarchische Organisation von Transformations-Workflows
- `TreeNode`: Organisationseinheit mit `xslt_params` und Kindknoten/-dateien
- `XslFile`: XSL-Stylesheet mit zugehörigen XML-Dateien und XSLT-Parametern
- `XmlFile`: XML-Eingabedatei mit optionalem blake2b-Hash
### UI-Architektur (src/ui/)
Die Anwendung folgt einem spezifischen PySide6-Muster:
1. **UI-Definitionsdateien** (`*_ui.py`): Automatisch generiert aus UI-Designer-Dateien
- Diese Dateien definieren die UI-Struktur als Klassen (z.B. `Ui_MainWindow`)
- Sollten NICHT manuell bearbeitet werden
2. **Implementierungsdateien** (ohne `_ui` Suffix): Tatsächliche Dialog-/Fenster-Implementierungen
- Importieren und verwenden die entsprechende `*_ui.py` Datei
- Enthalten Business-Logik und Signal/Slot-Verbindungen
- Beispiel: `MainWindow.py` verwendet `Ui_MainWindow` aus `MainWinddow_ui.py`
Beim Erstellen neuer Dialoge:
- Immer zuerst eine entsprechende UI-Datei erstellen
- Die UI-Datei wird automatisch als `.py`-Datei von einer VS Code Extension generiert
- Die generierte UI-Klasse in der Implementierungsdatei importieren und verwenden
### Hauptfenster (src/ui/MainWindow.py)
Zentrale Schaltstelle der Anwendung mit mehreren wichtigen Verantwortlichkeiten:
1. **Projektverwaltung**:
- Öffnet und verwaltet PDF-Transformationsprojekte
- Lädt/speichert `ProjectData` aus `project.yaml` Dateien
2. **Tree Widget**: Zeigt hierarchische Struktur von Transformationsknoten an
- Kontextmenüs zum Hinzufügen/Bearbeiten/Löschen von Knoten, XSL-Dateien und XML-Dateien
- Drag-and-Drop-Unterstützung für XML-Dateien
3. **PDF-Vergleichsansicht**:
- Drei-Panel-Ansicht (Referenz, Diff, Neu)
- Alpha-Blending für visuellen Vergleich
- Zoom- und Pan-Funktionalität
4. **Asynchrone Operationen**:
- `XmlHashCalculatorThread`: Hintergrund-blake2b-Hash-Berechnung für XML-Dateien
- `DatabaseTestThread` (in PostgreSqlConfigDialog): Asynchrones Testen von Datenbankverbindungen
### Hash-Berechnungssystem
Die Anwendung verwendet blake2b-Hashing zur Verfolgung von XML-Dateiänderungen:
- **Automatisch**: Hashes werden berechnet, wenn Projekte geladen werden (nur für Dateien ohne existierenden Hash)
- **Asynchron**: Hintergrund-Thread (`XmlHashCalculatorThread`) um die UI reaktionsfähig zu halten
- **Format**: `blake2b:<64-Zeichen-Hexdigest>`
- **Speicherung**: Persistiert in `project.yaml` innerhalb jedes `XmlFile`-Objekts
- **Details**: Siehe `docs/blake2b_hash_implementation.md`
### Theme-System
Die Anwendung unterstützt mehrere Qt-Themes:
- Theme-Auswahlmenü wird dynamisch aus `QStyleFactory.keys()` befüllt
- Theme-Präferenz wird in `AppSettings.theme` gespeichert
- Dark-Theme-Unterstützung via `qdarktheme` Paket (aktuell in main.py auskommentiert)
### Datenbankintegration
PostgreSQL-Integration mit Polars und ConnectorX:
- Konfiguration wird im `PostgreSqlDb`-Modell mit SSL-Modus-Unterstützung gespeichert
- SQL-Abfragen werden via `_execute_sql_query()` im MainWindow ausgeführt
- Ergebnisse werden in Polars DataFrames geladen
## Wichtige Konventionen
### Deutsche Sprache
Die Codebasis verwendet Deutsch für:
- UI-Texte und Labels
- Kommentare und Dokumentation
- Variablennamen wo kontextuell passend
- Log-Meldungen
### Pfadbehandlung
- Immer `pathlib.Path`-Objekte verwenden, keine Strings
- `expanduser()` und `expandvars()` für Benutzer-/Umgebungspfade verwenden
- Projektrelative Pfade werden als relativ gespeichert, zur Laufzeit gegen `project_dir` aufgelöst
### ID-basierte Lookups
Konfigurationsentitäten (Tools, Datenbanken) werden in Projekten über ID referenziert. Die Hilfsmethoden des `Project`-Modells (`getXsl()`, `getJavaVm()`, etc.) verwenden, um IDs in Anzeigewerte aufzulösen.
### Einstellungspersistenz
- Globale Einstellungen: `app_settings.save()` nach Änderungen aufrufen
- Projekteinstellungen: `project_data.writeSettings(project_dir)` nach Änderungen aufrufen
## Arbeiten mit der Codebasis
### Neue Tool-Konfigurationen hinzufügen
1. Modell zu `conf.py` hinzufügen (ähnlich wie `JavaVm`, `SaxonJar`)
2. Listenfeld zu `AppSettings` hinzufügen
3. Konfigurationsdialog in `src/ui/` erstellen (UI-Datei + Implementierung)
4. Zu `AppSettings.py` Tabs hinzufügen
5. `Project`-Modell aktualisieren, falls das Tool projektspezifisch sein soll
### Neue Baumoperationen hinzufügen
1. Aktion zum Kontextmenü in `_create_context_menu_for_type()` hinzufügen
2. Handler-Methode implementieren nach Namensschema `_action_tree_node()`, `_action_xsl_file()`, etc.
3. Baum nach Änderungen mit `_load_nodes_to_tree()` aktualisieren
4. `self.project_data.writeSettings(self.project.project_dir)` aufrufen um Änderungen zu persistieren
### Projektstruktur modifizieren
Das `ProjectData`-Modell ist die Quelle der Wahrheit. Alle Änderungen an der Baumstruktur müssen:
1. Die `project_data.nodes` Liste modifizieren
2. `project_data.writeSettings()` aufrufen um zu persistieren
3. Baum mit `_load_nodes_to_tree()` neu laden um Änderungen in der UI zu reflektieren