Skip to content

AVV-Pipeline — Technische Dokumentation

Ueberblick

Prilog generiert bei jeder Neubestellung automatisch einen personalisierten Auftragsverarbeitungsvertrag (AVV nach Art. 28 DSGVO). Der Vertrag wird mit den Kundendaten aus dem Onboarding befuellt, als PDF gerendert, in S3 archiviert, in der Datenbank protokolliert und dem Kunden per Mail zugestellt.

Kein manuelles Ausfuellen, kein Papier, kein Postversand. Der gesamte Prozess dauert unter 3 Sekunden.


Architektur

Onboarding-Frontend (Step 6: Rechtliches)

        │  Kunde sieht AVV-Checkbox + PDF-Download-Link
        │  Checkbox: "Ich schliesse den AVV elektronisch ab"
        │  Klick: "Verbindlich bestellen"


Backend: POST /api/public/orders

        ├─ [1] Order in DB anlegen (Prisma Transaction)

        ├─ [2] avv-service.processAvvConsent() (async, nicht-blockierend)
        │       │
        │       ├─ avv-renderer.renderAvvMarkdown()
        │       │     Template laden → Platzhalter ersetzen
        │       │
        │       ├─ avv-renderer.generateAvvPdf()
        │       │     Markdown → HTML → PDF (md-to-pdf, A4)
        │       │
        │       ├─ s3.uploadToS3()
        │       │     avv/{orderId}/AVV_{subdomain}_{date}.pdf
        │       │
        │       ├─ prisma.avvConsentLog.create()
        │       │     Version, Hash, Zeitstempel, IP, User-Agent
        │       │
        │       └─ avv-mailer.sendAvvEmail()
        │             PDF als Anhang an Kunden-E-Mail

        └─ [3] Response an Frontend (201 Created)


        Success-Page: "AVV herunterladen" Button

Dateien

DateiVerantwortlichkeit
src/services/avv/avv-template.mdAVV-Vorlage mit Platzhaltern (691 Zeilen)
src/services/avv/avv-renderer.tsTemplate-Rendering + PDF-Generierung
src/services/avv/avv-service.tsOrchestrierung: rendern → speichern → protokollieren → mailen
src/services/avv/avv-mailer.tsMailPace-Integration fuer AVV-Versand mit PDF-Anhang
src/services/s3.service.tsGenerischer S3-Upload/Download
src/routes/public.tsTrigger bei Order-Erstellung (Zeile ~390)
src/routes/admin/monitoring.router.tsAdmin-Endpoints fuer Consent-Log + PDF-Download

Template-System

Platzhalter

Das AVV-Template (avv-template.md) enthaelt benannte Platzhalter die zur Laufzeit ersetzt werden:

PlatzhalterQuelleBeispiel
billingCompanyWaldorfschule Weser e.V.
Strasse + PLZ + Ort + LandMusterstr. 1, 28195 Bremen, DE
Vorname + NachnameMax Mustermann
contactTechEmailmax@waldorf-weser.de
hostingType === 'shared'☑ oder ☐
hostingType === 'dedicated'☑ oder ☐
(noch nicht verfuegbar)
Zeitpunkt der Zustimmung22.04.2026
Stadt aus RechnungsadresseBremen

Versionierung

Das Template enthaelt eine Versionszeile:

*Version 1.0 | Stand 22. April 2026*

Bei Aenderungen am AVV:

  1. Neue Version im Template (Version 1.1)
  2. Bestehende Kunden behalten ihre unterzeichnete Version (PDF in S3 unveraendert)
  3. Neue Kunden bekommen die aktuelle Version
  4. avv_consent_log.version ermoeglicht spaetere Zuordnung

PDF-Generierung

Bibliothek

md-to-pdf — konvertiert Markdown ueber einen internen Chromium-Prozess in PDF. Leichtgewichtiger als Puppeteer standalone, da der Chromium nur fuer die Konversion gestartet wird.

Layout

  • Format: A4
  • Raender: 25mm oben/unten, 20mm links/rechts
  • Schrift: Segoe UI / -apple-system / sans-serif, 11pt
  • Ueberschriften: Gruen unterstrichen (#22c55e) — Corporate Design
  • Tabellen: Vollstaendige Rahmen, graue Header
  • Seitenumbruch: Vor jeder <h1> (ausser der ersten)

CSS

Das Styling ist direkt im avv-renderer.ts definiert (Variable AVV_CSS), nicht als externe Datei. Das vereinfacht das Deployment — keine zusaetzlichen Assets noetig.


FeldTypZweck
idcuidPrimary Key
order_idVARCHAR(50)Zuordnung zur Bestellung
tenant_idVARCHAR(64)Tenant-Referenz (falls schon vorhanden)
versionVARCHAR(20)AVV-Versionsnummer ("1.0")
content_hashVARCHAR(64)SHA-256 des gerenderten Markdown
signed_atTIMESTAMPZeitpunkt der Zustimmung
signed_byVARCHAR(255)Name der zustimmenden Person
signed_by_emailVARCHAR(255)E-Mail der zustimmenden Person
ip_addressVARCHAR(50)IP-Adresse zum Zeitpunkt der Zustimmung
user_agentTEXTBrowser-Informationen
pdf_storage_keyVARCHAR(500)S3-Pfad zur archivierten PDF
planVARCHAR(20)Gewaehltes Leistungsmodell (light/pro)
company_nameVARCHAR(255)Name der Einrichtung
subdomainVARCHAR(100)Gewaehlte Subdomain
created_atTIMESTAMPErstellungszeitpunkt des Log-Eintrags

Content-Hash

Der SHA-256 Hash wird ueber das gerenderte Markdown berechnet (nach Platzhalter-Ersetzung, vor PDF-Konversion). Das beweist:

  • Welche Version des Templates verwendet wurde
  • Welche Kundendaten eingesetzt wurden
  • Dass das Dokument nach der Unterschrift nicht veraendert wurde
typescript
import * as crypto from 'crypto';
const hash = crypto.createHash('sha256').update(markdown, 'utf-8').digest('hex');

S3-Speicherung

Pfad-Schema

s3://prilog-files/avv/{orderId}/AVV_{subdomain}_{YYYY-MM-DD}.pdf

Beispiel: avv/ORD-20260422-abc123/AVV_waldorf-weser_2026-04-22.pdf

Fail-Open

Wenn S3 nicht erreichbar ist (Netzwerk-Problem, Credentials falsch), wird der Prozess nicht abgebrochen. Das PDF wird trotzdem generiert und per Mail versendet. Der S3-Upload-Fehler wird geloggt. Beim naechsten Admin-Download wird das PDF on-demand neu generiert.


E-Mail-Versand

MailPace-Integration

Die AVV-Mail wird ueber MailPace (transactional email service) versendet:

  • Von: noreply@prilog.chat
  • An: Ansprechpartner aus dem Onboarding
  • Betreff: Auftragsverarbeitungsvertrag (AVV) — {Firmenname}
  • Anhang: AVV_{subdomain}.pdf (Base64-kodiert im API-Call)
  • Fallback: Wenn MailPace fehlschlaegt, wird der Fehler geloggt aber der Onboarding-Prozess nicht blockiert

E-Mail-Inhalt

HTML-formatierte Mail mit:

  • Begruessung mit Namen
  • Hinweis auf die Prilog-Instanz (Subdomain)
  • Verweis auf das Portal fuer erneuten Download
  • Corporate Footer

API-Endpoints

Oeffentlich (Onboarding)

EndpointMethodeZweck
POST /api/public/ordersPOSTOrder anlegen → AVV automatisch generiert

Der AVV-Prozess wird async nach der Order-Erstellung angestossen. Die Response wartet nicht auf die PDF-Generierung — der Kunde sieht sofort die Success-Page.

Admin (admin.prilog.chat)

EndpointMethodeZweck
GET /api/admin/avv-consentsGETAlle AVV-Consent-Logs (letzte 50)
GET /api/admin/orders/{orderId}/avvGETAVV-PDF fuer eine Order herunterladen

Der PDF-Download versucht zuerst aus S3 zu laden. Wenn das fehlschlaegt (S3 down, Datei geloescht), wird das PDF on-demand aus den gespeicherten Consent-Daten + Order-Daten neu generiert.


Sicherheit und Compliance

DSGVO Art. 28 Abs. 9

"Der Vertrag wird schriftlich abgefasst, was auch in einem elektronischen Format erfolgen kann."

Die Umsetzung erfuellt alle Anforderungen:

AnforderungUmsetzung
Vollstaendiger Text vor Abschluss einsehbarPDF-Download-Link im Legal-Step
Herunterladen moeglichDownload-Button vor und nach Abschluss
Aktive BestaetigungCheckbox + "Verbindlich bestellen" Button
VertretungsberechtigungCheckbox-Text bestaetigt Vertretung
Nachweis gespeichertavv_consent_log mit Hash, IP, Zeitstempel
Kopie jederzeit verfuegbarAdmin-Download + Portal-Download + E-Mail

Audit-Trail

Fuer jede AVV-Zustimmung ist nachweisbar:

  1. Wer hat zugestimmt (Name, E-Mail)
  2. Wann (sekundengenauer Zeitstempel)
  3. Was wurde akzeptiert (Version + Content-Hash)
  4. Wie (IP-Adresse, Browser User-Agent)
  5. Wo ist das Dokument archiviert (S3-Pfad)

Erweiterungen (geplant)

FeatureBeschreibungPrioritaet
Portal-DownloadAVV unter "Rechtliches" im Kunden-Portal downloadbarMittel
AVV-AktualisierungBestehende Kunden per Mail bei AVV-Aenderung informierenNiedrig
Digitale SignaturQualifizierte elektronische Signatur (eIDAS)Niedrig
PDF/ALangzeitarchivierungs-Format fuer rechtliche DokumenteNiedrig