contentpanel - Aushangworkflow um docx Vorlage erweitern #26

Closed
samuelbias wants to merge 0 commits from feature/contentpanel/aushangsvorlage into main
Owner

Auch wenn es ein riesiger PR ist, der neue Feature-Code umfasst nur knapp 2.000 Zeilen. Vieles davon ist ein sauberer Rewrite der bisherigen Contentpanel-Logik/Stylesheet, wo knapp 1.300 Zeilen entfallen. Die neu implementierten Features werden vollständig durch 61 Tests bestätigt. Viele Features sind durch Regressionstests gestützt. 1.600 Zeilen sind eine einzelne package-lock.json, die lediglich die exakt festgeschriebene JavaScript-Abhängigkeitsstruktur für den BetterOffice-Renderer festlegt, wird von npm erzeugt.

Richtig cool und interessant

openooxml/betteroffice, was ich hier für die Manipulation der DOCX-Vorlagendatei verwendet habe, ist ein vollständiger Rewrite der Microsoft Office Engine als eigene OOXML-Engine in Rust und wird über WebAssembly genutzt! Damit ist kein MS-Office/LibreOffice im Hintergrund nötig, der Rust-Kern ist super leichtgewichtig und läuft nativ in WebAssembly. Statt getrennte Implementierungen für Browser und Backend zu pflegen, kann dieselbe Engine für Parsing, Layout und Rendering in unterschiedlichen Umgebungen genutzt werden. Für unseren Anwendungsfall bedeutet das vor allem, dass die DOCX-Vorlage ohne externe Office-Installation verarbeitet und reproduzierbar gerendert werden kann. Und das alles in Rust ;) Das Repo dazu ist gerade mal zwei Monate alt, bin auf Arbeit damit in Berührung gekommen, musste es auch hierfür verwenden!

Projektanpassung

Metrik: Lines of Code (LOC)

Hinzugefügt Entfernt
Tests 1.372 0
Feature 2.017 1.265
package-lock.json und weitere config 1.736 6
Gesamt 5.125 1.271

Einordnung:
„Feature“ umfasst den produktiven Anwendungs-, Worker- und Renderer-Code.
„Weitere“ umfasst insbesondere Docker-/Build-Konfiguration, Ignore-Dateien, Dokumentation und Abhängigkeitskonfiguration.

Zusammenfassung

Der Aushang-Workflow im Contentpanel wurde erweitert und robuster umgesetzt.

PDFs werden seitenweise analysiert. Textarme Seiten können über das konfigurierte bildfähige Ollama-Modell transkribiert werden. Anschließend wird der Inhalt über Ollama in das feste Schema title und paragraphs überführt und mit grundlegenden Prüfungen gegen neu erfundene Zahlen- oder Kontaktdaten abgesichert.

Die erzeugten Inhalte werden in die bestehende DOCX-Formatvorlage eingefügt und über @betteroffice/docx-react in Chromium seitenweise als PNG gerendert. Die benötigten Schriften werden dabei explizit eingebunden.

Die Veröffentlichung erfolgt erst nach erfolgreicher vollständiger Erzeugung. Temporäre Render-Dateien liegen im gleichen Dateisystem wie die später veröffentlichten PNGs und werden über contentpanel-private.conf gegen direkten HTTP-Zugriff geschützt. Das Ersetzen vorhandener Seiten erfolgt mit Sicherung und Rollback.

Falls die Formatüberführung fehlschlägt, wird automatisch die unveränderte Original-PDF über Ghostscript veröffentlicht. Erst wenn auch dieser Fallback fehlschlägt, gilt der Auftrag als fehlgeschlagen.

Nach erfolgreicher Verarbeitung wird die ursprüngliche PDF aus der Queue entfernt. Die Benachrichtigungsmail enthält zuerst den erzeugten Titel und anschließend die Erfolgsmeldung. Der zugehörige Eintrag in admin_messages wird direkt als Log-Eintrag gespeichert.

Auch wenn es ein riesiger PR ist, der neue Feature-Code umfasst nur knapp 2.000 Zeilen. Vieles davon ist ein sauberer Rewrite der bisherigen Contentpanel-Logik/Stylesheet, wo knapp 1.300 Zeilen entfallen. Die neu implementierten Features werden vollständig durch 61 Tests bestätigt. Viele Features sind durch Regressionstests gestützt. 1.600 Zeilen sind eine einzelne `package-lock.json`, die lediglich die exakt festgeschriebene JavaScript-Abhängigkeitsstruktur für den BetterOffice-Renderer festlegt, wird von `npm` erzeugt. ### Richtig cool und interessant [openooxml/betteroffice](https://github.com/openooxml/betteroffice), was ich hier für die Manipulation der DOCX-Vorlagendatei verwendet habe, ist ein **vollständiger Rewrite der Microsoft Office Engine als eigene `OOXML`-Engine in `Rust`** und wird über `WebAssembly` genutzt! Damit ist **kein MS-Office/LibreOffice im Hintergrund nötig**, der Rust-Kern ist super leichtgewichtig und läuft nativ in `WebAssembly`. Statt getrennte Implementierungen für Browser und Backend zu pflegen, kann **dieselbe Engine** für Parsing, Layout und Rendering in unterschiedlichen Umgebungen genutzt werden. Für unseren Anwendungsfall bedeutet das vor allem, dass die DOCX-Vorlage **ohne externe Office-Installation verarbeitet und reproduzierbar gerendert** werden kann. Und das alles in Rust ;) Das Repo dazu ist gerade mal zwei Monate alt, bin auf Arbeit damit in Berührung gekommen, musste es auch hierfür verwenden! ### Projektanpassung **Metrik**: Lines of Code (LOC) | | Hinzugefügt | Entfernt | | --- | ---: | ---: | | Tests | 1.372 | 0 | | Feature | 2.017 | 1.265 | | `package-lock.json` und weitere config | 1.736 | 6 | | **Gesamt** | **5.125** | **1.271** | **Einordnung:** „Feature“ umfasst den produktiven Anwendungs-, Worker- und Renderer-Code. „Weitere“ umfasst insbesondere Docker-/Build-Konfiguration, Ignore-Dateien, Dokumentation und Abhängigkeitskonfiguration. ### Zusammenfassung Der Aushang-Workflow im Contentpanel wurde erweitert und robuster umgesetzt. PDFs werden seitenweise analysiert. Textarme Seiten können über das konfigurierte bildfähige Ollama-Modell transkribiert werden. Anschließend wird der Inhalt über Ollama in das feste Schema `title` und `paragraphs` überführt und mit grundlegenden Prüfungen gegen neu erfundene Zahlen- oder Kontaktdaten abgesichert. Die erzeugten Inhalte werden in die bestehende DOCX-Formatvorlage eingefügt und über `@betteroffice/docx-react` in Chromium seitenweise als PNG gerendert. Die benötigten Schriften werden dabei explizit eingebunden. Die Veröffentlichung erfolgt erst nach erfolgreicher vollständiger Erzeugung. Temporäre Render-Dateien liegen im gleichen Dateisystem wie die später veröffentlichten PNGs und werden über `contentpanel-private.conf` gegen direkten HTTP-Zugriff geschützt. Das Ersetzen vorhandener Seiten erfolgt mit Sicherung und Rollback. Falls die Formatüberführung fehlschlägt, wird automatisch die unveränderte Original-PDF über Ghostscript veröffentlicht. Erst wenn auch dieser Fallback fehlschlägt, gilt der Auftrag als fehlgeschlagen. Nach erfolgreicher Verarbeitung wird die ursprüngliche PDF aus der Queue entfernt. Die Benachrichtigungsmail enthält zuerst den erzeugten Titel und anschließend die Erfolgsmeldung. Der zugehörige Eintrag in `admin_messages` wird direkt als Log-Eintrag gespeichert.
samuelbias added the Feature label 2026-09-02 21:15:22 +02:00
samuelbias self-assigned this 2026-09-02 21:15:22 +02:00
samuelbias added 1 commit 2026-09-02 21:15:23 +02:00
samuelbias requested review from Ghost 2026-09-02 21:15:23 +02:00
samuelbias closed this pull request 2026-09-04 13:29:52 +02:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.