Zeilenenden der 24 verbliebenen Dateien normalisieren
Ausschliesslich Zeilenenden. Nachgewiesen mit "git diff --cached --ignore-cr-at-eol": Der Diff ist leer, es hat sich kein Zeichen Inhalt geaendert. Deshalb ein eigener Commit: 7448 geaenderte Zeilen in einem Commit mit echten Aenderungen zu verstecken, macht die Historie an dieser Stelle unlesbar. So laesst er sich beim Durchsehen ueberspringen. Refs #26
This commit is contained in:
+187
-187
@@ -1,187 +1,187 @@
|
||||
# Schema-Wünsche aus Etappe 3 „Papier“
|
||||
|
||||
Gesammelt beim Bau der Dokumentenakte. `prisma/schema.prisma` wurde
|
||||
absprachegemäß **nicht** angefasst; alles hier ist umgangen worden und
|
||||
funktioniert, wäre aber sauberer, wenn es im Modell stünde.
|
||||
|
||||
Reihenfolge: was am meisten weh tut, steht oben.
|
||||
|
||||
---
|
||||
|
||||
## 1. `DokumentVerknuepfung`: genau eine Zielspalte — nur in der Anwendung erzwungen
|
||||
|
||||
**Stand:** Zwölf nullbare Fremdschlüsselspalten. Der Kommentar im Schema sagt
|
||||
„Die Anwendung stellt sicher, dass genau eine Ziel-Spalte gesetzt ist“ — genau
|
||||
so ist es umgesetzt (`ZIEL_SPALTE` in `src/lib/validierung/dokumente.ts`,
|
||||
Prüfung in `dokumentVerknuepfen`).
|
||||
|
||||
**Wunsch:** Ein CHECK-Constraint in der Datenbank, damit auch ein Skript, ein
|
||||
Seed oder ein späterer Import das nicht verletzen kann:
|
||||
|
||||
```sql
|
||||
ALTER TABLE dokument_verknuepfung ADD CONSTRAINT genau_ein_ziel CHECK (
|
||||
(("vorgangId" IS NOT NULL)::int + ("fristId" IS NOT NULL)::int
|
||||
+ ("buchungId" IS NOT NULL)::int + ("vermoegenspostenId" IS NOT NULL)::int
|
||||
+ ("immobilieId" IS NOT NULL)::int + ("vertragId" IS NOT NULL)::int
|
||||
+ ("kontaktprotokollId" IS NOT NULL)::int + ("gesundheitsereignisId" IS NOT NULL)::int
|
||||
+ ("genehmigungId" IS NOT NULL)::int + ("nachforderungId" IS NOT NULL)::int
|
||||
+ ("bescheidId" IS NOT NULL)::int + ("kontaktId" IS NOT NULL)::int) = 1
|
||||
);
|
||||
```
|
||||
|
||||
Ließe sich als eigenes SQL-Skript neben `volltextsuche.sql` legen, ohne das
|
||||
Prisma-Schema zu ändern. **Warum wichtig:** Eine Akte, in der eine Verknüpfung
|
||||
auf zwei Dinge gleichzeitig zeigt, ist gegenüber dem Gericht nicht mehr
|
||||
erklärbar.
|
||||
|
||||
**Zusätzlich:** Es fehlt eine Eindeutigkeit je Paar. Doppelte Verknüpfungen
|
||||
werden derzeit vor dem Anlegen abgefragt (`findFirst`) — ein Race zwischen zwei
|
||||
Klicks kann sie trotzdem erzeugen. Ein partieller Unique-Index je Zielspalte,
|
||||
z. B. `CREATE UNIQUE INDEX ... ON dokument_verknuepfung ("dokumentId", "vorgangId")
|
||||
WHERE "vorgangId" IS NOT NULL;`, würde das schließen.
|
||||
|
||||
---
|
||||
|
||||
## 2. `Dokument.ocrStatus` ist ein freier String
|
||||
|
||||
**Stand:** `ocrStatus String?` mit dem Kommentar
|
||||
`"ausstehend" | "laeuft" | "fertig" | "fehlgeschlagen" | "nicht_verfuegbar"`.
|
||||
|
||||
**Wunsch:** Ein Enum `OcrStatus` mit genau diesen fünf Werten. Der Vertrag in
|
||||
`docs/SCHNITTSTELLEN.md` Abschnitt 3 gibt sie ohnehin vor, und die Oberfläche
|
||||
(`OcrAbzeichen`) schaltet darauf. Ein Tippfehler beim Zurückschreiben fällt
|
||||
heute erst auf, wenn das Abzeichen leer bleibt.
|
||||
|
||||
---
|
||||
|
||||
## 3. Kein Index auf `Dokument.objektSchluessel`
|
||||
|
||||
**Stand:** Die Ausliefer-Route `/api/dokumente/datei/[signatur]` sucht das
|
||||
Dokument über `objektSchluessel`, um Anzeigename und Protokolleintrag zu
|
||||
bekommen. Ohne Index ist das ein Seq-Scan bei jedem Dateiabruf.
|
||||
|
||||
**Wunsch:** `@@unique([objektSchluessel])` (der Schlüssel ist eine UUID, also
|
||||
ohnehin eindeutig) oder mindestens `@@index([objektSchluessel])`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Keine Dublettenerkennung über die Prüfsumme
|
||||
|
||||
**Stand:** `pruefsumme String?` (SHA-256, wird beim Ablegen gefüllt). Wer
|
||||
denselben Bescheid zweimal fotografiert, bekommt zwei Datensätze.
|
||||
|
||||
**Wunsch:** `@@index([betreuteId, pruefsumme])`. Dann ließe sich beim Upload
|
||||
sagen „dieses Blatt liegt schon in der Akte, angelegt am 12.03.2026“ — ohne den
|
||||
zweiten Upload zu verbieten (manchmal ist die zweite Kopie gewollt).
|
||||
|
||||
---
|
||||
|
||||
## 5. `Nachforderung` und `Bescheid` tragen keine `betreuteId`
|
||||
|
||||
**Stand:** Beide hängen nur am `SozialhilfeAntrag`. Die Zugriffsprüfung beim
|
||||
Verknüpfen muss deshalb über die Beziehung gehen
|
||||
(`where: { id, antrag: { betreuteId } }`, siehe `zielGehoertZurAkte`).
|
||||
|
||||
**Wunsch:** Eine denormalisierte `betreuteId` wie bei allen anderen
|
||||
Fachentitäten. Die Konvention „jede Abfrage ist auf `betreuteId` eingegrenzt“
|
||||
ist sonst an genau diesen zwei Stellen nicht wörtlich einhaltbar — und
|
||||
Ausnahmen von einer Sicherheitsregel sind die Stellen, an denen später Fehler
|
||||
passieren.
|
||||
|
||||
---
|
||||
|
||||
## 6. Seitenzahl und OCR-Lauf ohne Zeitstempel
|
||||
|
||||
**Stand:** `seitenzahl Int?` wird von der Texterkennung nachgetragen. Wann ein
|
||||
OCR-Lauf zuletzt versucht wurde, steht nirgends.
|
||||
|
||||
**Wunsch:** `ocrVersuchtAm DateTime?`. `ocrNachziehen()` in
|
||||
`src/lib/dokumente/ocr-nachlauf.ts` holt heute alles nach, was auf
|
||||
`ausstehend`/`fehlgeschlagen` steht — mit einem Zeitstempel ließe sich ein
|
||||
dauerhaft kaputtes Dokument nach dem dritten Versuch in Ruhe lassen, statt es
|
||||
bei jedem Nachziehen erneut durch Tesseract zu schicken.
|
||||
|
||||
---
|
||||
|
||||
## 7. Anmerkung zur Verschlüsselung der abgelegten Dateien
|
||||
|
||||
Kein Schema-Wunsch, aber eine Abweichung vom Kommentar im Schema, die
|
||||
festgehalten gehört. Bei `Dokument.ocrText` steht:
|
||||
|
||||
> „die Datei selbst liegt verschlüsselt im Objektspeicher“
|
||||
|
||||
Umgesetzt ist das **nur beim Dateitreiber**: `src/lib/speicher/datei.ts`
|
||||
verschlüsselt jede Datei anwendungsseitig mit AES-256-GCM (eigener Binär-
|
||||
Umschlag `BCD1 | Schlüsselversion | IV | Tag | Geheimtext`, Schlüssel aus
|
||||
`ENC_KEY_V*`). Beim S3-Treiber geht das nicht: Der Vertrag verlangt für
|
||||
`signierteUrl()` eine presigned URL, die der Objektspeicher selbst ausliefert —
|
||||
ein anwendungsseitig verschlüsselter Blob käme dort als Datenmüll an. Dort
|
||||
läuft der Schutz deshalb über `ServerSideEncryption: AES256` plus den
|
||||
AV-Vertrag nach Art. 28 DSGVO mit dem Anbieter.
|
||||
|
||||
Die SHA-256-Prüfsumme wird in **beiden** Fällen über den Klartext gebildet —
|
||||
sonst wäre sie als Nachweis gegenüber dem Gericht wertlos.
|
||||
|
||||
Wer das vereinheitlichen will, müsste den Vertrag ändern: `signierteUrl()`
|
||||
würde auch beim S3-Treiber auf die eigene Route zeigen, die den Blob holt,
|
||||
entschlüsselt und ausliefert. Das kostet Durchsatz bei großen Scans, wäre aber
|
||||
konsequenter. Bewusst offengelassen, weil es Abschnitt 1 der Schnittstellen
|
||||
berührt.
|
||||
|
||||
---
|
||||
|
||||
# Anhang: kein Schema-Wunsch, aber dringend
|
||||
|
||||
## `@react-pdf/renderer` kann ohne Krücke keinen Buchstaben setzen
|
||||
|
||||
Beim Bau der Belegmappe aufgefallen und **betrifft jedes PDF der Anwendung**,
|
||||
also auch die Berichte aus Etappe 5.
|
||||
|
||||
**Befund:** Jeder Aufruf von `renderToBuffer` scheitert mit
|
||||
|
||||
```
|
||||
TypeError: Cannot read properties of undefined (reading 'unitsPerEm')
|
||||
at @react-pdf/textkit/lib/textkit.js:3090
|
||||
```
|
||||
|
||||
— auch bei einem Dokument ganz ohne Stilangaben. Nicht die Testumgebung ist
|
||||
schuld: in reinem Node reproduziert es genauso.
|
||||
|
||||
**Ursache:** In `package.json` ist nur `@react-pdf/renderer` auf `4.1.6`
|
||||
festgelegt. Seine Unterabhängigkeiten stehen als Caret-Bereiche darin und sind
|
||||
inzwischen weitergewandert:
|
||||
|
||||
| Paket | installiert | von renderer 4.1.6 erwartet |
|
||||
|---|---|---|
|
||||
| `@react-pdf/font` | 3.1.0 | `^3.0.1` |
|
||||
| `@react-pdf/layout` | 4.7.1 | `^4.2.0` |
|
||||
| `@react-pdf/textkit` | 6.4.1 | (kommt über `layout`) |
|
||||
|
||||
`@react-pdf/font@3.1.0` gibt für die Standardschriften `null` zurück — früher
|
||||
löste die Schicht darunter den bloßen Namen selbst auf.
|
||||
`@react-pdf/textkit@6.4.1` verlangt dagegen ein echtes Schriftobjekt mit
|
||||
`layout()` und wirft bei einem Namen ausdrücklich `Invalid font`. Zwischen
|
||||
beiden klafft eine Lücke.
|
||||
|
||||
**Was ich getan habe:** `src/lib/pdf/standardschrift.ts` baut das fehlende
|
||||
Schriftobjekt aus den Metriken, die `@react-pdf/pdfkit` ohnehin mitbringt, und
|
||||
hängt sich vor die Schriftauflösung — aber nur, wenn sie kaputt ist. Kein neues
|
||||
Paket, kein Nachladen aus dem Netz. `pdfErzeugen()` ruft das von selbst auf,
|
||||
alle PDF-Wege dieser Anwendung sind damit wieder benutzbar (Test:
|
||||
„Aus einem Bericht und einem Beleg wird eine Mappe" in `tests/dokumente.test.ts`).
|
||||
|
||||
**Was noch zu tun ist** (außerhalb meiner Pfade, deshalb hier):
|
||||
`package.json` um Festlegungen ergänzen, damit die Pakete zueinander passen —
|
||||
|
||||
```jsonc
|
||||
"overrides": {
|
||||
"@react-pdf/layout": "4.2.x",
|
||||
"@react-pdf/textkit": "5.x"
|
||||
}
|
||||
```
|
||||
|
||||
Die genauen Stände bitte gegen `@react-pdf/renderer@4.1.6` prüfen; alternativ
|
||||
`@react-pdf/renderer` auf einen aktuellen Stand heben, dessen
|
||||
Unterabhängigkeiten wieder zusammenpassen. Danach kann
|
||||
`standardschrift.ts` ersatzlos entfallen — `standardschriftenSicherstellen()`
|
||||
merkt von selbst, dass es nicht mehr gebraucht wird, und hält sich heraus.
|
||||
# Schema-Wünsche aus Etappe 3 „Papier“
|
||||
|
||||
Gesammelt beim Bau der Dokumentenakte. `prisma/schema.prisma` wurde
|
||||
absprachegemäß **nicht** angefasst; alles hier ist umgangen worden und
|
||||
funktioniert, wäre aber sauberer, wenn es im Modell stünde.
|
||||
|
||||
Reihenfolge: was am meisten weh tut, steht oben.
|
||||
|
||||
---
|
||||
|
||||
## 1. `DokumentVerknuepfung`: genau eine Zielspalte — nur in der Anwendung erzwungen
|
||||
|
||||
**Stand:** Zwölf nullbare Fremdschlüsselspalten. Der Kommentar im Schema sagt
|
||||
„Die Anwendung stellt sicher, dass genau eine Ziel-Spalte gesetzt ist“ — genau
|
||||
so ist es umgesetzt (`ZIEL_SPALTE` in `src/lib/validierung/dokumente.ts`,
|
||||
Prüfung in `dokumentVerknuepfen`).
|
||||
|
||||
**Wunsch:** Ein CHECK-Constraint in der Datenbank, damit auch ein Skript, ein
|
||||
Seed oder ein späterer Import das nicht verletzen kann:
|
||||
|
||||
```sql
|
||||
ALTER TABLE dokument_verknuepfung ADD CONSTRAINT genau_ein_ziel CHECK (
|
||||
(("vorgangId" IS NOT NULL)::int + ("fristId" IS NOT NULL)::int
|
||||
+ ("buchungId" IS NOT NULL)::int + ("vermoegenspostenId" IS NOT NULL)::int
|
||||
+ ("immobilieId" IS NOT NULL)::int + ("vertragId" IS NOT NULL)::int
|
||||
+ ("kontaktprotokollId" IS NOT NULL)::int + ("gesundheitsereignisId" IS NOT NULL)::int
|
||||
+ ("genehmigungId" IS NOT NULL)::int + ("nachforderungId" IS NOT NULL)::int
|
||||
+ ("bescheidId" IS NOT NULL)::int + ("kontaktId" IS NOT NULL)::int) = 1
|
||||
);
|
||||
```
|
||||
|
||||
Ließe sich als eigenes SQL-Skript neben `volltextsuche.sql` legen, ohne das
|
||||
Prisma-Schema zu ändern. **Warum wichtig:** Eine Akte, in der eine Verknüpfung
|
||||
auf zwei Dinge gleichzeitig zeigt, ist gegenüber dem Gericht nicht mehr
|
||||
erklärbar.
|
||||
|
||||
**Zusätzlich:** Es fehlt eine Eindeutigkeit je Paar. Doppelte Verknüpfungen
|
||||
werden derzeit vor dem Anlegen abgefragt (`findFirst`) — ein Race zwischen zwei
|
||||
Klicks kann sie trotzdem erzeugen. Ein partieller Unique-Index je Zielspalte,
|
||||
z. B. `CREATE UNIQUE INDEX ... ON dokument_verknuepfung ("dokumentId", "vorgangId")
|
||||
WHERE "vorgangId" IS NOT NULL;`, würde das schließen.
|
||||
|
||||
---
|
||||
|
||||
## 2. `Dokument.ocrStatus` ist ein freier String
|
||||
|
||||
**Stand:** `ocrStatus String?` mit dem Kommentar
|
||||
`"ausstehend" | "laeuft" | "fertig" | "fehlgeschlagen" | "nicht_verfuegbar"`.
|
||||
|
||||
**Wunsch:** Ein Enum `OcrStatus` mit genau diesen fünf Werten. Der Vertrag in
|
||||
`docs/SCHNITTSTELLEN.md` Abschnitt 3 gibt sie ohnehin vor, und die Oberfläche
|
||||
(`OcrAbzeichen`) schaltet darauf. Ein Tippfehler beim Zurückschreiben fällt
|
||||
heute erst auf, wenn das Abzeichen leer bleibt.
|
||||
|
||||
---
|
||||
|
||||
## 3. Kein Index auf `Dokument.objektSchluessel`
|
||||
|
||||
**Stand:** Die Ausliefer-Route `/api/dokumente/datei/[signatur]` sucht das
|
||||
Dokument über `objektSchluessel`, um Anzeigename und Protokolleintrag zu
|
||||
bekommen. Ohne Index ist das ein Seq-Scan bei jedem Dateiabruf.
|
||||
|
||||
**Wunsch:** `@@unique([objektSchluessel])` (der Schlüssel ist eine UUID, also
|
||||
ohnehin eindeutig) oder mindestens `@@index([objektSchluessel])`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Keine Dublettenerkennung über die Prüfsumme
|
||||
|
||||
**Stand:** `pruefsumme String?` (SHA-256, wird beim Ablegen gefüllt). Wer
|
||||
denselben Bescheid zweimal fotografiert, bekommt zwei Datensätze.
|
||||
|
||||
**Wunsch:** `@@index([betreuteId, pruefsumme])`. Dann ließe sich beim Upload
|
||||
sagen „dieses Blatt liegt schon in der Akte, angelegt am 12.03.2026“ — ohne den
|
||||
zweiten Upload zu verbieten (manchmal ist die zweite Kopie gewollt).
|
||||
|
||||
---
|
||||
|
||||
## 5. `Nachforderung` und `Bescheid` tragen keine `betreuteId`
|
||||
|
||||
**Stand:** Beide hängen nur am `SozialhilfeAntrag`. Die Zugriffsprüfung beim
|
||||
Verknüpfen muss deshalb über die Beziehung gehen
|
||||
(`where: { id, antrag: { betreuteId } }`, siehe `zielGehoertZurAkte`).
|
||||
|
||||
**Wunsch:** Eine denormalisierte `betreuteId` wie bei allen anderen
|
||||
Fachentitäten. Die Konvention „jede Abfrage ist auf `betreuteId` eingegrenzt“
|
||||
ist sonst an genau diesen zwei Stellen nicht wörtlich einhaltbar — und
|
||||
Ausnahmen von einer Sicherheitsregel sind die Stellen, an denen später Fehler
|
||||
passieren.
|
||||
|
||||
---
|
||||
|
||||
## 6. Seitenzahl und OCR-Lauf ohne Zeitstempel
|
||||
|
||||
**Stand:** `seitenzahl Int?` wird von der Texterkennung nachgetragen. Wann ein
|
||||
OCR-Lauf zuletzt versucht wurde, steht nirgends.
|
||||
|
||||
**Wunsch:** `ocrVersuchtAm DateTime?`. `ocrNachziehen()` in
|
||||
`src/lib/dokumente/ocr-nachlauf.ts` holt heute alles nach, was auf
|
||||
`ausstehend`/`fehlgeschlagen` steht — mit einem Zeitstempel ließe sich ein
|
||||
dauerhaft kaputtes Dokument nach dem dritten Versuch in Ruhe lassen, statt es
|
||||
bei jedem Nachziehen erneut durch Tesseract zu schicken.
|
||||
|
||||
---
|
||||
|
||||
## 7. Anmerkung zur Verschlüsselung der abgelegten Dateien
|
||||
|
||||
Kein Schema-Wunsch, aber eine Abweichung vom Kommentar im Schema, die
|
||||
festgehalten gehört. Bei `Dokument.ocrText` steht:
|
||||
|
||||
> „die Datei selbst liegt verschlüsselt im Objektspeicher“
|
||||
|
||||
Umgesetzt ist das **nur beim Dateitreiber**: `src/lib/speicher/datei.ts`
|
||||
verschlüsselt jede Datei anwendungsseitig mit AES-256-GCM (eigener Binär-
|
||||
Umschlag `BCD1 | Schlüsselversion | IV | Tag | Geheimtext`, Schlüssel aus
|
||||
`ENC_KEY_V*`). Beim S3-Treiber geht das nicht: Der Vertrag verlangt für
|
||||
`signierteUrl()` eine presigned URL, die der Objektspeicher selbst ausliefert —
|
||||
ein anwendungsseitig verschlüsselter Blob käme dort als Datenmüll an. Dort
|
||||
läuft der Schutz deshalb über `ServerSideEncryption: AES256` plus den
|
||||
AV-Vertrag nach Art. 28 DSGVO mit dem Anbieter.
|
||||
|
||||
Die SHA-256-Prüfsumme wird in **beiden** Fällen über den Klartext gebildet —
|
||||
sonst wäre sie als Nachweis gegenüber dem Gericht wertlos.
|
||||
|
||||
Wer das vereinheitlichen will, müsste den Vertrag ändern: `signierteUrl()`
|
||||
würde auch beim S3-Treiber auf die eigene Route zeigen, die den Blob holt,
|
||||
entschlüsselt und ausliefert. Das kostet Durchsatz bei großen Scans, wäre aber
|
||||
konsequenter. Bewusst offengelassen, weil es Abschnitt 1 der Schnittstellen
|
||||
berührt.
|
||||
|
||||
---
|
||||
|
||||
# Anhang: kein Schema-Wunsch, aber dringend
|
||||
|
||||
## `@react-pdf/renderer` kann ohne Krücke keinen Buchstaben setzen
|
||||
|
||||
Beim Bau der Belegmappe aufgefallen und **betrifft jedes PDF der Anwendung**,
|
||||
also auch die Berichte aus Etappe 5.
|
||||
|
||||
**Befund:** Jeder Aufruf von `renderToBuffer` scheitert mit
|
||||
|
||||
```
|
||||
TypeError: Cannot read properties of undefined (reading 'unitsPerEm')
|
||||
at @react-pdf/textkit/lib/textkit.js:3090
|
||||
```
|
||||
|
||||
— auch bei einem Dokument ganz ohne Stilangaben. Nicht die Testumgebung ist
|
||||
schuld: in reinem Node reproduziert es genauso.
|
||||
|
||||
**Ursache:** In `package.json` ist nur `@react-pdf/renderer` auf `4.1.6`
|
||||
festgelegt. Seine Unterabhängigkeiten stehen als Caret-Bereiche darin und sind
|
||||
inzwischen weitergewandert:
|
||||
|
||||
| Paket | installiert | von renderer 4.1.6 erwartet |
|
||||
|---|---|---|
|
||||
| `@react-pdf/font` | 3.1.0 | `^3.0.1` |
|
||||
| `@react-pdf/layout` | 4.7.1 | `^4.2.0` |
|
||||
| `@react-pdf/textkit` | 6.4.1 | (kommt über `layout`) |
|
||||
|
||||
`@react-pdf/font@3.1.0` gibt für die Standardschriften `null` zurück — früher
|
||||
löste die Schicht darunter den bloßen Namen selbst auf.
|
||||
`@react-pdf/textkit@6.4.1` verlangt dagegen ein echtes Schriftobjekt mit
|
||||
`layout()` und wirft bei einem Namen ausdrücklich `Invalid font`. Zwischen
|
||||
beiden klafft eine Lücke.
|
||||
|
||||
**Was ich getan habe:** `src/lib/pdf/standardschrift.ts` baut das fehlende
|
||||
Schriftobjekt aus den Metriken, die `@react-pdf/pdfkit` ohnehin mitbringt, und
|
||||
hängt sich vor die Schriftauflösung — aber nur, wenn sie kaputt ist. Kein neues
|
||||
Paket, kein Nachladen aus dem Netz. `pdfErzeugen()` ruft das von selbst auf,
|
||||
alle PDF-Wege dieser Anwendung sind damit wieder benutzbar (Test:
|
||||
„Aus einem Bericht und einem Beleg wird eine Mappe" in `tests/dokumente.test.ts`).
|
||||
|
||||
**Was noch zu tun ist** (außerhalb meiner Pfade, deshalb hier):
|
||||
`package.json` um Festlegungen ergänzen, damit die Pakete zueinander passen —
|
||||
|
||||
```jsonc
|
||||
"overrides": {
|
||||
"@react-pdf/layout": "4.2.x",
|
||||
"@react-pdf/textkit": "5.x"
|
||||
}
|
||||
```
|
||||
|
||||
Die genauen Stände bitte gegen `@react-pdf/renderer@4.1.6` prüfen; alternativ
|
||||
`@react-pdf/renderer` auf einen aktuellen Stand heben, dessen
|
||||
Unterabhängigkeiten wieder zusammenpassen. Danach kann
|
||||
`standardschrift.ts` ersatzlos entfallen — `standardschriftenSicherstellen()`
|
||||
merkt von selbst, dass es nicht mehr gebraucht wird, und hält sich heraus.
|
||||
|
||||
Reference in New Issue
Block a user