feat: enhance validation rules and improve content structure across collections

This commit is contained in:
2026-05-17 12:25:28 +00:00
parent 4020ad62c5
commit 819147f518
8 changed files with 184 additions and 26 deletions
+64
View File
@@ -429,6 +429,70 @@ If the collection feeds public pages or admin block previews, also verify that t
---
## Collection Validators
Validatoren definieren Sicherheitsregeln und Typ-Constraints, indem sie als `validator`-Key innerhalb der `fields`-Definitionen einer Collection-YAML (`api/collections/*.yml`) konfiguriert werden.
**Unterschied Client- vs. Serverseitige Validatoren:**
- **Serverseite (`tibi-server`)**: Validatoren werden zentral im Go-Backend bei jedem Datensatz-Schreibvorgang (`POST` / `PUT`) ausgeführt (nach den `validate`-Hooks). Wenn Daten nicht den Constraints entsprechen, erfolgt ein Abbruch (`400 Bad Request`).
- **Clientseite (`tibi-admin-nova`)**: Das CMS-Admin-Interface liest diese Validator-Regeln automatisch über das OpenAPI-Schema ein und wendet sie instant als Client-Side-Validierung in den Formularen an (Rote Markierungen und Check vor dem eigentlichen API-Call). **Validatoren müssen daher nur 1x zentral in der YAML definiert werden.**
**Häufige Validator-Optionen je Feldtyp:**
- **Generell**:
- `required: true` (Zwingendes Pflichtfeld)
- `allowZero: true` (Erlaubt die explizite Eingabe von `""` oder `0`, selbst wenn `required: true` aktiv ist)
- `in: ["wert1", "wert2"]` (Nur dieser exakte Pool an primitiven Werten ist erlaubt)
- `eval: "$this.length >= 3 && $this.length <= 100"` (Serverseitige Javascript-Evaluation für Custom-Logik)
- **Einfache Texte (`string`)**:
- `minLength: X` und `maxLength: Y`
- `pattern: "^[a-zA-Z0-9]+$"` (Prüft Regex-Match des kompletten Werts)
- `format: email` (oder `url`, `uuid`, `slug` für eingebaute Regex-Prüfungen)
- **Zahlen (`number`, `float`)**:
- `min: X` und `max: Y`
- **Datum/Zeit (`date`, `datetime`, `time`)**:
- `minDate: "YYYY-MM-DD"` und `maxDate: "YYYY-MM-DD"` (Zulässige Zeitgrenzen)
- **Listen/Arrays (`string[]`, `object[]`)**:
- `minItems: X` und `maxItems: Y`
- **Dateien/Bilder (`file`, `file[]`)**:
- `maxFileSize: "50MB"` (und `minFileSize`)
- `accept: ["image/png", "image/webp"]` (Erlaubte MIME-Types)
- Constraints für Bildabmessungen konfigurierbar via Sub-Objekt:
```yaml
image:
minWidth: 800
maxWidth: 2400
minHeight: 600
maxHeight: 1800
```
**Beispiel für die Einbindung in einer Collection:**
```yaml
fields:
- name: internalName
type: string
validator:
required: true
maxLength: 100
meta:
label: { de: "Interner Name", en: "Internal Name" }
- name: externalLink
type: string
validator:
format: url
meta:
label: Externe URL
- name: document
type: file
validator:
maxFileSize: "20MB"
accept: ["application/pdf"]
```
## Seed data pattern (Playwright)
Test seed data uses `_testdata: true` as a hidden marker field. **Real content must NEVER use this flag** — otherwise test teardown will delete it.