---
title: "Durrani — CI-Baseline (Gate-Matrix, am Content-Vertrag verankert)"
type: project
tags: [durrani, ci, gates, tests, contract, quality]
date: 2026-05-24
status: aktiv
related: "[[content-fetching-contract]], [[tech-gates]], [[tasks]], [[payload-runtime-verification]]"
---

# Durrani — CI-Baseline

> Gebaut mit direktem Bezug auf [[content-fetching-contract]]. **Anker = CMS-Contract-Test** (Zod-DTOs): bricht, wenn eine Payload-Änderung das Public-Read-Model / SEO / Media verletzt. Harte Gates statt dekorativ. Beide Repos lokal, nicht gepusht. Workflows laufen bei künftigem Push.

## Gate-Matrix
| # | Gate | Repo | Command | Läuft | Blocking | Status |
|---|---|---|---|---|---|---|
| 1 | Typecheck | web + cms | `pnpm typecheck` | lokal + CI | ✅ ja | grün (beide) |
| 2 | Lint | web + cms | `pnpm lint` | lokal + CI | ✅ ja | grün (0 errors; web 1 pre-existing warning) |
| 3 | **CMS-Contract-Test (Anker)** | web | `pnpm test` | lokal + CI | ✅ ja | grün (DTOs, kadiTenantId-Strip, Drift-Reject, alt-Pflicht) |
| 4 | Mock-Response-Test | web | `pnpm test` | lokal + CI | ✅ ja | grün (DE/EN, missing img/translation, broken relation) |
| 5 | Fallback-Behavior-Test | web | `pnpm test` | lokal + CI | ✅ ja | grün (CMS down/500/skip-bad-doc) |
| 6 | Security-Header/CSP-Test | web | `pnpm test` | lokal + CI | ✅ ja | grün (HSTS/nosniff/DENY/Referrer/Permissions + CSP strict) |
| 7 | Build | web + cms | `pnpm build` | lokal + CI | ✅ ja | grün (web SSG; cms kompiliert Payload+Admin+API) |
| 8 | No-Secrets-im-Client-Bundle | web | `pnpm check:no-secrets` | lokal + CI (post-build) | ✅ ja | grün (18 Assets, 0 Treffer) |
| 9 | Playwright-Smoke (/de,/en,redirect,BFF-Mock,no-console) | web | `pnpm test:e2e` | CI (Browser) | ✅ ja | vorbereitet (Browser-Install in CI) |
| 10 | axe/a11y-Smoke (WCAG2A/AA, keine serious/critical) | web | `pnpm test:e2e` | CI (Browser) | ✅ ja | vorbereitet |
| 11 | Bundle-Budget (First-Load-JS ≤120KB) | web | `next build`-Output | lokal + CI | ⚠ Warnung→Gate | aktuell ~102 KB ✓ (size-limit-Gate als Refinement) |
| 12 | SEO/JSON-LD-Validierung | web | (Builder + Test) | später | ⚠ später | vorbereitet — aktiviert mit JSON-LD-Buildern (Frontend-Anbindung) |
| 13 | Internal-Link/Route-Check | web | Playwright | CI | ⚠ später | Teil von e2e, erweitern bei echten Routen |
| 14 | Lighthouse (Perf≥95, SEO=100, A11y≥95) | web | LHCI | Preview-Gate | ⚠ später | als Preview/Staging-Gate (tech-gates §1) |
| 15 | CMS `generate:types` | cms | `payload generate:types` | — | ⚠ Tech-Debt | KAR-617 (CLI-Worker-Quirk; `next build` type-checkt) |

## Workflows
- `durrani-web/.github/workflows/ci.yml`: Job `quality` (typecheck·lint·test·build·check:no-secrets, hart) + Job `e2e` (Playwright+axe, Browser).
- `durrani-cms/.github/workflows/ci.yml`: Job `quality` (typecheck·lint·build) mit **PostGIS-Service** (`postgis/postgis:17-3.5`, kodiert das Deploy-Finding).

## Was lokal grün ist (verifiziert)
`durrani-web`: typecheck ✓ · lint ✓ (0 err) · test 18/18 ✓ · build ✓ (~102 KB) · check:no-secrets ✓.
`durrani-cms`: typecheck ✓ · lint ✓ (0) · build ✓.

## Was nur vorbereitet ist (läuft in CI / später)
- Playwright-Smoke + axe (Browser-Download → CI-Job, lokal in diesem Lauf nicht ausgeführt).
- SEO/JSON-LD-Validierung (braucht die JSON-LD-Builder = Teil der Frontend-Anbindung, Schritt danach).
- Lighthouse (Preview/Staging-Gate).
- `size-limit` als harter Bundle-Budget-Check (aktuell via Build-Output verifiziert).

## Offene Risiken
- e2e/axe noch nicht lokal gelaufen (nur Build-verifiziert) → erstes CI-Run zeigt echte Browser-Resultate.
- 1 pre-existing Lint-Warning in `lib/kadi/mock-adapter.ts` (unused var) — Warnung, nicht Error.
- Bundle-Budget aktuell soft (Build-Output) — `size-limit` härtet es.

## Verwandt
- [[content-fetching-contract]] (der Anker) · [[tech-gates]] · [[payload-runtime-verification]] · [[tasks]]
