---
title: "Durrani — Payload-Runtime-Verifizierung (Stand 2026-05-24)"
type: project
tags: [durrani, payload, cms, runtime, verification, decision]
date: 2026-05-24
status: aktiv
related: "[[tasks]], [[plan]], [[tech-gates]]"
---

# Payload-Runtime-Verifizierung — Stand & Entscheidung

> Session 0956fb5e. Lokal im Repo `durrani-web` (uncommitted WIP). Kein Push/Deploy. Postgres läuft lokal in Docker (`durrani-pg`, Port 5432).

## ✅ AUFGELÖST (2026-05-24, Entscheidung A umgesetzt) — Runtime GRÜN
Kais wählte **A: Payload als eigene App**. Umgesetzt als **zwei separate lokale Repos**:
- `/root/projekte/durrani-web` (Frontend, Payload-WIP sauber entfernt, `next build` weiter grün) — Commit `e910456`.
- `/root/projekte/durrani-cms` (Payload-3-App, eigenes `/admin` + REST/GraphQL-API) — Commit `5b72336`. **Beide lokal, nicht gepusht.**

**Runtime im CMS vollständig verifiziert:**
- `next build` clean (Config + alle 9 Collections + Settings + Admin-UI + API kompilieren → Config lädt, Collections kompilieren, **keine Zyklen**).
- `/admin` → HTTP 200 (**Admin-UI startet**).
- Live REST: First-Admin-User + Token (**Auth**), Location, MenuItem + Relationships, **i18n DE/EN distinct**, **Location-Scoping-Query**, **Drafts** (status=draft, versions), Media erreichbar (alt/caption/credit/copyright + focalPoint einkompiliert), **Minimal-Seed** via Verify-Skript.

**Kritisches Deploy-Finding:** Postgres MUSS **PostGIS** haben (`Locations.geo` ist `point` → Drizzle `CREATE EXTENSION postgis`). `postgres:17` schlug fehl, `postgis/postgis:17-3.5` löst es. → Netcup-Postgres braucht PostGIS.

**Offen / Caveats:**
- `payload generate:types` (CLI) scheitert am tsx-Worker (strikte ESM-Resolution, kein `.js`→`.ts`, keine tsconfig-Paths). Workaround: `next build` type-checkt alles; payload-types via Script möglich. Nicht-blockierend.
- Draft-vs-Published Read-Filter nur grob geprüft (Draft-Erstellung + Status + Versions bestätigt); feinere Sichtbarkeits-Semantik = Follow-up-Assertion.
- Imports im CMS sind **extensionslos** (webpack-konform); die `.js`-Extensions waren ein Irrweg (revertiert).

**Nächster Schritt (laut Kais):** CMS ist runtime-grün → erst danach Content-Fetching-Vertrag Frontend↔CMS definieren (API-Shape, draft/preview, ISR/Revalidate, Cache, public read model, keine Admin-Secrets im Frontend). NOCH NICHT bauen.

---

## Gebaut
- `payload.config.ts` (root): alle 9 Collections + Settings-Global, `localization {de,en, defaultLocale:de, fallback}`, `lexicalEditor`, `postgresAdapter`, `sharp`, `admin.user=users`, typescript-outputFile.
- `payload/collections/Users.ts` neu — Auth-Collection (`auth:true`, Rollen admin/editor) für Admin-Login.
- `Media.ts` erweitert: `upload.focalPoint:true` + Felder `caption` (localized) + `copyright` (zusätzlich zu `alt` localized + `credit`).
- Import-Fixes: ESM-`.js`-Extensions an allen relativen Payload-Imports (Barrel + Pages→blocks/seo + Events/Catering→seo).
- `scripts/payload-verify.ts`: Local-API-Verifikation (User/Location/Category/localized MenuItem DE+EN/Page-Draft/Scoping-Query/Media-Felder).
- Postgres 17.10 via Docker hochgezogen, `pg_isready` grün.
- Payload `3.84.1` + `@payloadcms/{db-postgres,richtext-lexical,next}` + `sharp` + `graphql` installiert (lockstep, exit 0).

## Verifiziert
- **Postgres-Anbindung:** Container läuft, erreichbar.
- **Datenmodell strukturell:** alle Collections + Globals + Blocks + seo-Field lesen/auflösen; **keine zyklischen Relationships** (alle zeigen einseitig auf `locations`/`media`/`menu-categories`/`faqs`).
- **Drafts:** `versions:{drafts:true}` auf Pages/Events/Catering (im Seed bereits vorhanden) — config-seitig korrekt.
- **i18n:** `localized:true`-Felder + config-Localization DE/EN konsistent.
- **Import-Auflösung:** via direktem `tsx` lösen sich alle Config-/Collection-Imports auf (`.js`→`.ts`-Mapping greift).

## Noch nicht verifiziert (Runtime-Boot offen)
- Admin-UI-Start, Local-API-CRUD (i18n/Drafts/Scoping live), Seed-Daten, `generate:types`-Output.
- **Grund:** Payload 3 ist an die Next-Runtime gekoppelt. Bare-headless schlägt fehl:
  1. `payload generate:types` / `payload run` nutzen einen tsx-**Worker mit strikter ESM-Resolution** — kein `.js`→`.ts`-Mapping, keine tsconfig-Paths (`@payload-config` → `ERR_INVALID_MODULE_SPECIFIER`).
  2. Direktes `tsx scripts/payload-verify.ts` löst Imports, crasht aber in Payloads `bin/loadEnv.js` an einem `@next/env`-Default-Interop (`loadEnvConfig` undefined) — Next-Kopplung außerhalb von Next.

## Produktionsnah vs. Mock
- **Produktionsnah:** Datenmodell, Localization-Config, Drafts-Config, Postgres-Adapter — alles real, kein Mock.
- **Noch offen/Mock:** Reservierung läuft weiter über `lib/kadi` Mock (unverändert). Payload-Admin/Runtime noch nicht gebootet.

## Risiken
- **Same-App-Integration kollidiert:** Payloads `(payload)`-Route-Group will `/admin` + `/api/[...slug]`. Das überschneidet sich mit (a) meinen `/api/reservation*`-BFF-Routen und (b) dem `app/[locale]`-Root-Layout (zwei `<html>`-Roots). Saubere Integration in dieselbe App erfordert Restruktur (`app/(frontend)/[locale]` + `(payload)`, `/api`-Overlap auflösen) + `/admin` aus der i18n-Middleware ausnehmen.
- Bare-headless Payload ist nicht der unterstützte Pfad → unnötiger Kampf.

## Nächste Entscheidung (für Kais)
Plan `tasks.md` T003 sagt bereits **„Payload-3-Projekt scaffold (separates Deployment-Target Netcup-VPS)"**. Die Runtime-Befunde bestätigen das:
- **Option A (empfohlen, plan-konform):** Payload als **eigene minimale Next-App** (eigenes `package.json`, eigener Root-Layout + `/admin` + `/api`), gleiche Collections + dieselbe Postgres. Saubere Trennung, keine Route-/Layout-Konflikte, separates Deploy (Netcup). → dort `next build` + Admin-Boot + Local-API-Seed = vollständiger Runtime-Beweis.
- **Option B:** Integration in die bestehende `durrani-web`-App via `(frontend)`/`(payload)`-Route-Groups + `/api`-Overlap-Auflösung. Ein Deploy, aber CMS-Admin im Public-App-Bundle, mehr Kopplung.

Sobald A oder B gewählt: Runtime-Boot + die offenen Verifikations-Punkte sind dann direkt im Next-Host beweisbar (das `scripts/payload-verify.ts` läuft 1:1 im Next-Kontext).

## Verwandt
- [[tasks]] (T003/T010) · [[plan]] · [[tech-gates]]
