# #041 M25 – PDF-Übergabeprotokoll mit Unterschrift **Status:** offen **Im Tracker:** – **Meilenstein:** v0.3.0 **Labels:** phase-3, backend, frontend **Geschätzt:** 8 h **Tatsächlich:** – ## Ziel Wer ein Notebook übergibt, braucht ein Blatt, das der Empfänger unterschreibt — und das danach auffindbar ist. Heute gibt es die Druckansicht eines Laufs (`/drucken/lauf/[id]`, #015): sie ist hell, vollständig und als Vorstufe genau dafür gebaut. Was fehlt, ist die Datei. Ein Browser-Ausdruck genügt nicht: er hängt am Drucker-Dialog des Betrachters, trägt dessen Kopfzeilen und lässt sich nicht an ein Ticket anhängen. ## Zu entscheiden - [ ] **Wie entsteht das PDF?** Empfehlung: **Chromium aus `@playwright/test`**, wie `scripts/anleitung-pdf.ts` es für die Anleitung tut. Keine neue Abhängigkeit, keine zweite Auslegung des Layouts — gedruckt wird dieselbe Seite, die die Druckansicht zeigt. **Grenze, die genannt gehört:** damit braucht der Server einen Chromium. Im Compose-Stand ist das eine Ergänzung am Image, nativ ein Paket. Die Alternative (`pdf-lib` oder ein Dienst) wäre ein zweites Layout, das auseinanderläuft — der Preis ist höher. - [ ] **Unterschrift auf Papier oder auf dem Gerät?** Empfehlung: **beides, in dieser Reihenfolge.** Zuerst ein Unterschriftsfeld im PDF (eine Linie, Name, Datum) — das löst den Fall heute und kostet fast nichts. Eine Unterschrift mit dem Finger auf dem Handy ist ein eigener Schritt-Typ und gehört zu [#042](042-weitere-schritt-typen.md); sie landet dann als Bild im PDF. Eine digitale **Signatur** im kryptografischen Sinn ist ausdrücklich **nicht** gemeint und wäre eine eigene Phase. - [ ] **Wird das PDF gespeichert oder bei jedem Abruf erzeugt?** Empfehlung: **bei jedem Abruf erzeugt**, nicht gespeichert. Ein gespeichertes PDF ist eine zweite Wahrheit neben dem Lauf; wird eine Notiz später berichtigt, stimmt es nicht mehr. Für den Fall „wir brauchen das Blatt von damals“ gibt es das Archiv, das den Lauf unveränderlich hält. **`{{generiertes_passwort}}` erscheint auch hier nicht** — die Druckansicht zeigt `[Passwort – nicht gespeichert]`, und das PDF übernimmt das. ## Aufgaben - [ ] `GET /api/laeufe/[id]/protokoll.pdf` — Route Handler, prüft sein Recht **selbst** (`tests/zugang.test.ts` erzwingt das seit #038) - [ ] Erzeugung über Chromium, gegen die eigene Druckansicht; eine Seitenvorlage mit Kopf (Kunde, Lauf, Vorlage, Version), Inhalt und Fuß (Bearbeiter, Freigeber aus [#040](040-vier-augen-freigabe.md), Unterschriftsfeld) - [ ] Ein **Chromium-Vorrat** im Prozess: ihn je Anfrage zu starten kostet Sekunden. Eine Instanz, die nach Leerlauf schließt — und eine Obergrenze gleichzeitiger Erzeugungen, wie `SSE_MAX_STROEME` in #033 - [ ] Knopf „Protokoll als PDF“ an Lauf und Archiv - [ ] `Dockerfile` und `deploy/install.sh` um Chromium ergänzen, **mit gemessener Bildgröße** im Changelog — eine Ergänzung am Image, die niemand bemerkt, ist eine böse Überraschung beim nächsten Rollout - [ ] `docs/betrieb/` sagt, was die Erzeugung braucht und was passiert, wenn Chromium fehlt: **eine Meldung, kein stilles leeres PDF** - [ ] Anleitung Kapitel 02 und 10 (Archiv) ## Akzeptanzkriterien - [ ] Test: das PDF enthält Titel, Vorlage mit Version, alle geltenden Schritte mit Zustand, Notizen und Kommentare — geprüft am extrahierten Text, nicht am Vorhandensein der Datei - [ ] Test: es enthält **kein** erzeugtes Passwort, über alle Schritt-Typen - [ ] Test: ein Lauf eines fremden Kunden ist über die Adresse nicht abrufbar (wie #032 nach #036) - [ ] Test: ohne Recht `401`, mit falschem Kunden `404` - [ ] Test: fehlt Chromium, kommt eine Meldung mit Hinweis auf die Betriebsdoku — kein leeres PDF - [ ] Test: zwei gleichzeitige Erzeugungen laufen, die dritte wartet oder wird abgewiesen (die Obergrenze gilt) - [ ] Ein Blatt ist ausgedruckt und gegengesehen worden — das ist eine Abnahme von Hand und steht als solche im Devlog