fix(invoice): Rechnung ohne PDF/A statt Fehler, wenn Schriften fehlen
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 0s

Fehlt assets/fonts im Container, entsteht das PDF mit Standardschriften
und eingebettetem XML, nur nicht als PDF/A; der Fehler steht laut im Log.
Eine Rechnung darf nie an den Schriften scheitern.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-12 06:24:25 +02:00
1 parent 051eedaf7f
commit 4b15ca0b8d
1 file changed
+18 -7
+18 -7
View File
@@ -24,12 +24,21 @@ const FONT_FILES = {
type FontName = keyof typeof FONT_FILES; type FontName = keyof typeof FONT_FILES;
let fontCache: Record<FontName, Buffer> | null = null; /** undefined: noch nicht gelesen; null: Schriften fehlen (Rueckfall auf Standardschriften). */
let fontCache: Record<FontName, Buffer> | null | undefined;
function fonts(): Record<FontName, Buffer> { function fonts(): Record<FontName, Buffer> | null {
if (!fontCache) { if (fontCache === undefined) {
const entries = Object.entries(FONT_FILES).map(([name, file]) => [name, readFileSync(path.join(FONT_DIR, file))]); try {
fontCache = Object.fromEntries(entries) as Record<FontName, Buffer>; const entries = Object.entries(FONT_FILES).map(([name, file]) => [name, readFileSync(path.join(FONT_DIR, file))]);
fontCache = Object.fromEntries(entries) as Record<FontName, Buffer>;
} catch (error: unknown) {
// Eine Rechnung darf nie an den Schriften scheitern: ohne sie entsteht
// das PDF mit Standardschriften und eingebettetem XML, nur nicht als
// PDF/A. Laut melden, damit das fehlende Verzeichnis auffaellt.
console.error(`[invoice-pdf] Schriften fuer PDF/A fehlen unter ${FONT_DIR} — Rechnungen ohne PDF/A:`, error);
fontCache = null;
}
} }
return fontCache; return fontCache;
} }
@@ -37,15 +46,17 @@ function fonts(): Record<FontName, Buffer> {
/** /**
* Optionen fuer new PDFDocument(): PDF/A-3b und eine eingebettete Grundschrift. * Optionen fuer new PDFDocument(): PDF/A-3b und eine eingebettete Grundschrift.
* Ohne "font" laedt pdfkit beim Anlegen die Standard-Helvetica, die dann * Ohne "font" laedt pdfkit beim Anlegen die Standard-Helvetica, die dann
* nicht eingebettet im Dokument stuende. * nicht eingebettet im Dokument stuende. PDF 1.7 auch im Rueckfall, sonst
* schreibt pdfkit keine XMP-Metadaten (Factur-X-Angaben).
*/ */
export function pdfaOptions(): PDFKit.PDFDocumentOptions { export function pdfaOptions(): PDFKit.PDFDocumentOptions {
if (!fonts()) return { pdfVersion: "1.7" };
return { pdfVersion: "1.7", subset: "PDF/A-3b", font: path.join(FONT_DIR, FONT_FILES.Helvetica) }; return { pdfVersion: "1.7", subset: "PDF/A-3b", font: path.join(FONT_DIR, FONT_FILES.Helvetica) };
} }
/** Registriert die eingebetteten Schriften unter den Namen der Standardschriften. */ /** Registriert die eingebetteten Schriften unter den Namen der Standardschriften. */
export function registerEmbeddedFonts(doc: PDFKit.PDFDocument): void { export function registerEmbeddedFonts(doc: PDFKit.PDFDocument): void {
for (const [name, data] of Object.entries(fonts())) { for (const [name, data] of Object.entries(fonts() ?? {})) {
doc.registerFont(name, data); doc.registerFont(name, data);
} }
} }