Datenschutzerklärung als unterschreibbare PDF-Vorlage
Neuer Endpoint GET /api/gdpr/customer/:customerId/privacy-pdf generiert eine PDF mit: - Titel - Personalisiertem Kopf (Name / Firma + Kundennummer + Datum) - Voller Datenschutzerklärung (HTML → Text) - Einwilligungsklausel - Unterschriftenblock (Ort/Datum links, Unterschrift rechts, zweite Linie "Name in Druckbuchstaben" mit vorausgefuelltem Kundennamen) Auth: customers:read + canAccessCustomer. Filename: "datenschutzerklaerung-<kundennummer>.pdf". Im Tab "Einwilligungen / Datenschutz" beim Kunden gibt es jetzt direkt neben dem Upload-Feld den Link "Vorlage zum Unterschreiben" – Ausdrucken, unterschreiben lassen, scannen, wieder hochladen. Verifiziert auf dev: Magic-Bytes %PDF-1.3, %%EOF-Marker am Ende, 2 KB Output, pdftotext zeigt korrekten Aufbau inkl. Unterschrift- Linien. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1114,3 +1114,35 @@ export async function getMyAuthorizationStatus(req: AuthRequest, res: Response)
|
||||
res.status(500).json({ success: false, error: 'Fehler beim Laden' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unterschreibbare Datenschutzerklärung (Papierform) als PDF generieren.
|
||||
* Verwendung: Mitarbeiter klickt im Tab "Einwilligungen / Datenschutz"
|
||||
* auf "Vorlage zum Unterschreiben", PDF kommt mit personalisiertem
|
||||
* Kopf + Unterschriftsfeld zum Ausdrucken zurück.
|
||||
*
|
||||
* GET /api/gdpr/customer/:customerId/privacy-pdf
|
||||
*/
|
||||
export async function getSignablePrivacyPdf(req: AuthRequest, res: Response) {
|
||||
try {
|
||||
const customerId = parseInt(req.params.customerId, 10);
|
||||
if (!Number.isFinite(customerId) || customerId < 1) {
|
||||
return res.status(400).json({ success: false, error: 'Ungültige Kunden-ID' });
|
||||
}
|
||||
if (!(await canAccessCustomer(req, res, customerId))) return;
|
||||
|
||||
const pdf = await consentPublicService.generateSignablePrivacyPdf(customerId);
|
||||
const customer = await prisma.customer.findUnique({
|
||||
where: { id: customerId },
|
||||
select: { customerNumber: true },
|
||||
});
|
||||
const filename = `datenschutzerklaerung-${customer?.customerNumber || customerId}.pdf`;
|
||||
|
||||
res.setHeader('Content-Type', 'application/pdf');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||
res.send(pdf);
|
||||
} catch (error) {
|
||||
console.error('Fehler bei Datenschutz-PDF:', error);
|
||||
res.status(500).json({ success: false, error: 'Fehler beim Generieren der PDF' });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user