# Transformation ohne Force — Entscheidungslogik
Die zentrale Methode ist `is_up_to_date()` in transform.py:155-180. Sie basiert auf Modifikationszeiten (mtime), nicht auf Hashes.
## Ablauf
Die Prüfung erfolgt an zwei Stellen in der Pipeline:
1. Vor Saxon-Transformation (`transform_saxon()`) — transform.py:192-194
2. Vor PDF-Build (`build_pdf()`) — transform.py:322-324
Beide rufen `is_up_to_date()` auf, die prüft:
- Existiert die New-PDF?
- Ist die XML-Datei neuer als die New-PDF?
- Ist die XSL-Datei neuer als die New-PDF?
Wenn die New-PDF existiert und älter als alle Inputs ist → Transformation wird übersprungen mit `(True, "Übersprungen (aktuell)")`.
## Mermaid-Diagramm
```mermaid
flowchart TD
A["Transformation gestartet
(force=False)"] --> B{"force == True?"}
B -- Ja --> EXEC["Transformation ausführen"]
B -- Nein --> C{"New-PDF existiert?"}
C -- Nein --> EXEC
C -- Ja --> D["mtime der New-PDF ermitteln"]
D --> E{"XML-Datei neuer
als New-PDF?"}
E -- Ja --> EXEC
E -- Nein --> F{"XSL-Datei neuer
als New-PDF?"}
F -- Ja --> EXEC
F -- Nein --> SKIP["Übersprungen (aktuell)
return (True, 'Übersprungen')"]
EXEC --> S1["Schritt 1: Saxon
XML → FO"]
S1 --> S1OK{"Saxon erfolgreich?"}
S1OK -- Nein --> FAIL["Pipeline abgebrochen"]
S1OK -- Ja --> S2CHECK{"force == True?
(erneute Prüfung
für build_pdf)"}
S2CHECK -- Ja --> S2["Schritt 2: FOP
FO → PDF"]
S2CHECK -- Nein --> S2UP{"is_up_to_date()?"}
S2UP -- Ja --> S2SKIP["PDF-Build übersprungen"]
S2UP -- Nein --> S2
S2 --> S3["Schritt 3: diff-pdf
PDF-Vergleich"]
S3 --> DONE["Pipeline abgeschlossen"]
style SKIP fill:#4CAF50,color:#fff
style EXEC fill:#2196F3,color:#fff
style FAIL fill:#f44336,color:#fff
style DONE fill:#4CAF50,color:#fff
style S2SKIP fill:#4CAF50,color:#fff
```
## Wichtige Details
- Keine Hash-basierte Prüfung: Die Skip-Logik nutzt ausschließlich `mtime`-Vergleiche, nicht die blake2b-Hashes (die werden nur für Änderungsverfolgung in der UI verwendet).
- Doppelte Prüfung: `is_up_to_date()` wird sowohl vor Saxon als auch vor FOP aufgerufen — theoretisch könnte Saxon ausgeführt, aber der PDF-Build übersprungen werden.
- Skip = Erfolg: Ein übersprungener Schritt gilt als erfolgreich `(True, ...)`, die Pipeline läuft weiter.
- Force-Aufruf: Über das Kontextmenü gibt es explizite Force-Methoden wie `_transform_all_xml_files_force()` in transformation.py.
## Erweiterung
```mermaid
flowchart TD
LOAD["Projekt geladen"] --> BUILD["XSL-Abhängigkeitsgraph aufbauen
dict[Path, set[Path]]"]
BUILD --> CACHE["Im Speicher halten"]
TRANSFORM["is_up_to_date() aufgerufen"] --> CHECK{"Graph-Eintrag
vorhanden?"}
CHECK -- Nein --> PARSE["XSL parsen, Imports auflösen,
Eintrag erstellen"]
PARSE --> MTIME
CHECK -- Ja --> STALE{"mtime der XSL
geändert seit letztem Parse?"}
STALE -- Ja --> PARSE
STALE -- Nein --> MTIME["mtime aller Abhängigkeiten
gegen New-PDF prüfen"]
MTIME --> RESULT["Ergebnis"]
```