fix(access): allow tenant resolution from query parameter in tenantScopedPublicRead

Previously, tenantScopedPublicRead only resolved the tenant from the Host
header, which fails when frontend API clients call cms.c2sgmbh.de (the CMS
hostname doesn't match any tenant domain). Now falls back to extracting the
tenant ID from the where[tenant][equals] query parameter. The returned access
filter still enforces tenant isolation.

Also adds seed script for zweitmeinung (tenant 12) with all content:
site settings, 2 service categories, 6 services, 24 FAQs, navigation,
4 social links, and contact form.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-21 00:44:42 +00:00
parent 101ee0abed
commit ab4ee4bb70
2 changed files with 858 additions and 4 deletions

View file

@ -0,0 +1,828 @@
/**
* Zweitmeinung (Tenant 12) Seed Script
*
* Populates tenant 12 with all content for zweitmeinu.ng:
* - Site Settings
* - Service Categories (2)
* - Services (6)
* - FAQs (24)
* - Navigation
* - Social Links (4)
* - Contact Form
*
* Run with: npx tsx scripts/seed-zweitmeinung.ts
*/
import { getPayload } from 'payload'
import config from '../src/payload.config'
const TENANT_ID = 12
// ── Rich Text Helpers (Lexical format) ──────────────────────
function createRichText(content: string | string[]): object {
const paragraphs = Array.isArray(content) ? content : [content]
return {
root: {
type: 'root',
children: paragraphs.map((text) => ({
type: 'paragraph',
children: [{ type: 'text', text }],
})),
direction: 'ltr',
format: '',
indent: 0,
version: 1,
},
}
}
function createRichTextComplex(
blocks: Array<
| { type: 'heading'; tag: string; text: string }
| { type: 'paragraph'; text: string }
| { type: 'paragraph-bold'; text: string }
| { type: 'bullets'; items: string[] }
>,
): object {
return {
root: {
type: 'root',
children: blocks.map((block) => {
if (block.type === 'heading') {
return {
type: 'heading',
tag: block.tag,
children: [{ type: 'text', text: block.text }],
}
}
if (block.type === 'paragraph-bold') {
return {
type: 'paragraph',
children: [{ type: 'text', text: block.text, format: 1 }],
}
}
if (block.type === 'bullets') {
return {
type: 'list',
listType: 'bullet',
children: block.items.map((item) => ({
type: 'listitem',
children: [{ type: 'text', text: item }],
})),
}
}
return {
type: 'paragraph',
children: [{ type: 'text', text: block.text }],
}
}),
direction: 'ltr',
format: '',
indent: 0,
version: 1,
},
}
}
// ── Helper: Upsert ──────────────────────────────────────────
async function upsert(
payload: any,
collection: string,
where: Record<string, any>,
data: Record<string, any>,
): Promise<number> {
const existing = await payload.find({
collection,
where: { ...where, tenant: { equals: TENANT_ID } },
limit: 1,
})
if (existing.docs.length > 0) {
const doc = await payload.update({
collection,
id: existing.docs[0].id,
data: { ...data, tenant: TENANT_ID },
})
return doc.id as number
}
const doc = await payload.create({
collection,
data: { ...data, tenant: TENANT_ID },
})
return doc.id as number
}
// ── Main Seed Function ──────────────────────────────────────
async function seed() {
console.log('🚀 Starting zweitmeinung (Tenant 12) Seed...\n')
const payload = await getPayload({ config })
// Verify tenant exists
const tenant = await payload.findByID({ collection: 'tenants', id: TENANT_ID })
if (!tenant) {
console.error(`❌ Tenant ${TENANT_ID} not found!`)
process.exit(1)
}
console.log(`✓ Tenant "${tenant.name}" (ID: ${TENANT_ID}) found\n`)
// ════════════════════════════════════════════
// 1. SITE SETTINGS
// ════════════════════════════════════════════
console.log('--- 1. Site Settings ---')
await upsert(payload, 'site-settings', {}, {
siteName: 'zweitmeinu.ng',
siteTagline: 'Beratung wenn sie wirklich wichtig ist',
contact: {
email: 'kontakt@zweitmeinu.ng',
phone: '0800 80 44 100',
fax: '0800 80 44 190',
},
address: {
street: 'Hans-Böckler-Str. 19',
zip: '46236',
city: 'Bottrop',
state: 'Nordrhein-Westfalen',
country: 'Deutschland',
},
footer: {
copyrightText: '© 2026 complex care solutions GmbH. Alle Rechte vorbehalten.',
showSocialLinks: true,
},
seo: {
defaultMetaTitle: 'Zweitmeinung Portal Medizinische Zweitmeinung',
defaultMetaDescription:
'Ihr zentrales Portal für qualifizierte medizinische Zweitmeinungen. Zugang zu erfahrenen Fachärzt:innen. Schnell, sicher, kompetent.',
},
})
console.log('✓ Site Settings created/updated')
// ════════════════════════════════════════════
// 2. SERVICE CATEGORIES
// ════════════════════════════════════════════
console.log('\n--- 2. Service Categories ---')
const categoryData = [
{
name: 'Notfall',
slug: 'emergency',
description: 'Dringende medizinische Zweitmeinungen in kritischen Situationen',
icon: 'alert-triangle',
color: '#EF4444',
order: 1,
},
{
name: 'Beratung',
slug: 'consultation',
description: 'Geplante medizinische Zweitmeinungen für elektive Eingriffe',
icon: 'stethoscope',
color: '#1278B3',
order: 2,
},
]
const categoryIds: Record<string, number> = {}
for (const cat of categoryData) {
const id = await upsert(payload, 'service-categories', { slug: { equals: cat.slug } }, {
...cat,
isActive: true,
})
categoryIds[cat.slug] = id
console.log(`✓ Category "${cat.name}" (ID: ${id})`)
}
// ════════════════════════════════════════════
// 3. SERVICES
// ════════════════════════════════════════════
console.log('\n--- 3. Services ---')
const services = [
{
title: 'Zweitmeinung Intensivmedizin',
slug: 'zweitmeinung-intensivmedizin',
categorySlug: 'emergency',
order: 1,
isFeatured: true,
shortDescription:
'Unabhängige ärztliche Zweitmeinung bei laufender oder geplanter Intensivbehandlung. Wir prüfen medizinische Indikation, Patientenwille und Behandlungsalternativen empathisch, neutral und fachlich fundiert.',
description: createRichTextComplex([
{ type: 'heading', tag: 'h2', text: 'Zweitmeinung Intensiv fundierte Beratung in kritischen Situationen' },
{
type: 'paragraph',
text: 'Wenn intensivmedizinische Entscheidungen anstehen, brauchen Patient:innen und ihre Angehörigen mehr als nur medizinische Information sie brauchen Orientierung, Sicherheit und eine unabhängige fachliche Einschätzung.',
},
{
type: 'paragraph-bold',
text: 'Unsere Dienstleistung „Zweitmeinung Intensiv" richtet sich an Menschen in sehr schwerer gesundheitlicher Lage, etwa bei Langzeitbeatmung, Wachkoma oder im palliativen Kontext.',
},
{ type: 'heading', tag: 'h3', text: 'Was wir leisten:' },
{
type: 'bullets',
items: [
'Strukturierte Beratung durch erfahrene Case Manager:innen',
'Unabhängige ärztliche Zweitmeinung inkl. schriftlichem Gutachten',
'Bewertung von Therapiezielen, Indikationen, Patientenverfügung & Prognose',
'Unterstützung bei der Umsetzung: von palliativer Umsteuerung bis Pflegeüberleitung',
],
},
{ type: 'heading', tag: 'h3', text: 'Für wen ist das Angebot gedacht?' },
{
type: 'paragraph',
text: 'Die Zweitmeinung kann von Betroffenen selbst oder ihren rechtlichen Vertreter:innen beauftragt werden.',
},
{ type: 'heading', tag: 'h3', text: 'Ihr Nutzen:' },
{
type: 'bullets',
items: [
'Vermeidung nicht indizierter Eingriffe oder fortgesetzter Maximaltherapie',
'Sicherung des Patientenwillens in ethisch sensiblen Situationen',
'Medizinisch und rechtlich belastbare Entscheidungsgrundlage',
'Transparente Kommunikation und datenschutzkonformer Ablauf',
],
},
]),
metaTitle: 'Zweitmeinung Intensivmedizin',
metaDescription:
'Unabhängige ärztliche Zweitmeinung bei intensivmedizinischer Behandlung. Jetzt fundierte Empfehlung einholen mit CCS sicher entscheiden.',
},
{
title: 'Zweitmeinung Kardiologie',
slug: 'zweitmeinung-kardiologie',
categorySlug: 'consultation',
order: 2,
isFeatured: true,
shortDescription:
'Unabhängige ärztliche Zweitmeinung vor Herzkatheter, Stent oder OP. Fundierte Empfehlung durch erfahrene Kardiolog:innen verständlich, sicher, neutral.',
description: createRichTextComplex([
{ type: 'heading', tag: 'h2', text: 'Zweitmeinung Kardiologie klare Empfehlungen bei Herzentscheidungen' },
{
type: 'paragraph',
text: 'Herzbeschwerden verunsichern und geplante Eingriffe wie eine Stent-Implantation werfen viele Fragen auf.',
},
{ type: 'heading', tag: 'h3', text: 'Was wir für Sie tun:' },
{
type: 'bullets',
items: [
'Bewertung Ihrer Diagnosen und EKG-/Katheterbefunde durch Fachärzt:innen',
'Zweitmeinung bei geplanter PCI, Bypass-OP oder medikamentöser Umstellung',
'Schriftliches ärztliches Gutachten mit klarer Empfehlung',
'Persönliche Erläuterung telefonisch oder per Video',
],
},
{ type: 'heading', tag: 'h3', text: 'Wann ist eine Zweitmeinung sinnvoll?' },
{
type: 'paragraph',
text: 'Vor planbaren Eingriffen wie Stent-Implantation, Herzoperation oder interventioneller Ablation.',
},
]),
metaTitle: 'Zweitmeinung Kardiologie Einschätzung vor Eingriffen',
metaDescription: 'Unabhängige Zweitmeinung bei geplanter PCI oder Herzoperation.',
},
{
title: 'Zweitmeinung Onkologie',
slug: 'zweitmeinung-onkologie',
categorySlug: 'consultation',
order: 3,
isFeatured: true,
shortDescription:
'Unabhängige ärztliche Zweitmeinung bei Krebs. Fundierte Einschätzung von Therapieoptionen durch erfahrene Onkolog:innen empathisch, verständlich, individuell.',
description: createRichTextComplex([
{
type: 'heading',
tag: 'h2',
text: 'Zweitmeinung Onkologie fundierte Entscheidungshilfe bei Krebsdiagnosen',
},
{
type: 'paragraph',
text: 'Eine Krebsdiagnose ist ein Einschnitt. Neben der seelischen Belastung stellt sich oft die Frage: Ist die empfohlene Behandlung wirklich die beste Wahl?',
},
{ type: 'heading', tag: 'h3', text: 'Was wir für Sie tun:' },
{
type: 'bullets',
items: [
'Auswertung Ihrer Diagnose und Befunde durch erfahrene Fachärzt:innen',
'Bewertung der geplanten Therapie (Wirksamkeit, Nebenwirkungen, Lebensqualität)',
'Schriftliches Zweitmeinungsgutachten',
'Optionales Gespräch per Telefon oder Video',
'Einbindung von Case Management und Palliativberatung',
],
},
{ type: 'heading', tag: 'h3', text: 'Wann ist eine Zweitmeinung sinnvoll?' },
{
type: 'paragraph',
text: 'Bei neu gestellter oder fortgeschrittener Krebsdiagnose, z. B. bei Empfehlung einer Chemotherapie, Operation, Immun- oder Strahlentherapie.',
},
]),
metaTitle: 'Zweitmeinung Onkologie fundierte Einschätzung bei Krebs',
metaDescription: 'Unabhängige ärztliche Zweitmeinung bei Krebs. Behandlungsalternativen prüfen.',
},
{
title: 'Zweitmeinung Nephrologie',
slug: 'zweitmeinung-nephrologie',
categorySlug: 'consultation',
order: 4,
isFeatured: false,
shortDescription:
'Unabhängige ärztliche Einschätzung bei Nierenerkrankungen, Dialyseempfehlung oder Transplantationsvorbereitung. Klar, neutral und verständlich erklärt.',
description: createRichTextComplex([
{ type: 'heading', tag: 'h2', text: 'Zweitmeinung Nephrologie Klarheit bei Nierenentscheidungen' },
{
type: 'paragraph',
text: 'Die Diagnose einer chronischen Nierenerkrankung oder die Empfehlung zur Dialyse ist ein gravierender Einschnitt.',
},
{ type: 'heading', tag: 'h3', text: 'Was wir für Sie tun:' },
{
type: 'bullets',
items: [
'Prüfung der nephrologischen Diagnostik, Laborwerte, Nierenfunktion',
'Zweitmeinung durch Fachärzt:innen für Innere Medizin und Nephrologie',
'Gutachten zur Notwendigkeit oder zum Zeitpunkt einer Dialyse',
'Bewertung konservativer Behandlungsoptionen',
],
},
]),
metaTitle: 'Zweitmeinung Nephrologie Entscheidung vor Dialyse',
metaDescription:
'Unabhängige ärztliche Zweitmeinung bei chronischer Niereninsuffizienz oder Dialyseempfehlung.',
},
{
title: 'Zweitmeinung Gallenblase',
slug: 'zweitmeinung-gallenblase',
categorySlug: 'consultation',
order: 5,
isFeatured: false,
shortDescription:
'Unabhängige ärztliche Zweitmeinung vor einer geplanten Gallenblasen-OP. Wir prüfen, ob der Eingriff medizinisch notwendig ist verständlich, neutral und leitlinienbasiert.',
description: createRichTextComplex([
{ type: 'heading', tag: 'h2', text: 'Zweitmeinung Gallenblase unnötige Operationen vermeiden' },
{
type: 'paragraph',
text: 'Viele Menschen erhalten bei Gallensteinen die Empfehlung, die Gallenblase entfernen zu lassen. Doch nicht in jedem Fall ist eine Operation notwendig.',
},
{ type: 'heading', tag: 'h3', text: 'Was wir für Sie tun:' },
{
type: 'bullets',
items: [
'Bewertung Ihrer Beschwerden und Untersuchungsergebnisse',
'Prüfung der OP-Indikation nach medizinischen Leitlinien',
'Zweitmeinung durch Fachärzt:innen für Viszeralchirurgie oder Gastroenterologie',
'Verständliches Zweitmeinungsgutachten mit klarer Empfehlung',
],
},
{ type: 'heading', tag: 'h3', text: 'Ihr Nutzen:' },
{
type: 'bullets',
items: [
'Vermeidung unnötiger Operationen',
'Aufklärung über konservative Behandlungsoptionen',
'Verständliche Erklärung der Befunde und Risiken',
],
},
]),
metaTitle: 'Zweitmeinung Gallenblase OP kritisch prüfen lassen',
metaDescription:
'Gallenblasen-OP empfohlen? Holen Sie sich eine unabhängige Zweitmeinung von erfahrenen Fachärzt:innen.',
},
{
title: 'Zweitmeinung Schilddrüse',
slug: 'zweitmeinung-schilddruese',
categorySlug: 'consultation',
order: 6,
isFeatured: false,
shortDescription:
'Unabhängige ärztliche Einschätzung vor einer geplanten Schilddrüsen-OP. Fundierte Zweitmeinung durch erfahrene Endokrinolog:innen individuell, neutral, verständlich.',
description: createRichTextComplex([
{
type: 'heading',
tag: 'h2',
text: 'Zweitmeinung Schilddrüse fundierte Einschätzung vor einer Operation',
},
{
type: 'paragraph',
text: 'Die Empfehlung zur Entfernung der Schilddrüse ist für viele Menschen mit Sorgen verbunden. Doch ist eine Operation wirklich notwendig?',
},
{ type: 'heading', tag: 'h3', text: 'Was wir für Sie tun:' },
{
type: 'bullets',
items: [
'Prüfung von Ultraschallbefunden, Szintigrammen, Laborwerten',
'Zweitmeinung durch Fachärzt:innen für Endokrinologie oder Schilddrüsenchirurgie',
'Schriftliches Gutachten mit nachvollziehbarer Empfehlung',
],
},
{ type: 'heading', tag: 'h3', text: 'Wann ist eine Zweitmeinung sinnvoll?' },
{
type: 'paragraph',
text: 'Bei empfohlener OP wegen Knoten, Struma, Autonomie oder unklarer Laborwerte.',
},
]),
metaTitle: 'Zweitmeinung Schilddrüse OP sinnvoll prüfen lassen',
metaDescription:
'Schilddrüsen-OP empfohlen? Lassen Sie die Notwendigkeit von erfahrenen Endokrinolog:innen prüfen.',
},
]
const serviceIds: Record<string, number> = {}
for (const svc of services) {
const { categorySlug, ...rest } = svc
const id = await upsert(payload, 'services', { slug: { equals: svc.slug } }, {
...rest,
category: categoryIds[categorySlug],
isActive: true,
ctaText: 'Jetzt Zweitmeinung anfordern',
ctaLink: '/kontakt',
ctaStyle: 'primary',
})
serviceIds[svc.slug] = id
console.log(`✓ Service "${svc.title}" (ID: ${id})`)
}
// ════════════════════════════════════════════
// 4. FAQS
// ════════════════════════════════════════════
console.log('\n--- 4. FAQs ---')
const faqs = [
// ── Allgemeine Fragen ──
{
question: 'Was bringt mir eine Zweitmeinung bei Krebs?',
answer: createRichText(
'Eine Zweitmeinung kann Ihnen Sicherheit geben vor allem bei schweren Diagnosen oder belastenden Therapien. Sie hilft, Behandlungsoptionen besser zu verstehen, Alternativen zu erkennen und eine informierte Entscheidung zu treffen. Besonders wichtig ist das, wenn mehrere Behandlungswege möglich sind oder Zweifel an der vorgeschlagenen Therapie bestehen.',
),
category: 'allgemein',
order: 1,
},
{
question: 'Muss ich alle meine Unterlagen selbst zusammensuchen?',
answer: createRichText(
'Nein. Unser Case Management unterstützt Sie bei der Beschaffung und Zusammenstellung Ihrer medizinischen Unterlagen. In der Regel genügt eine Schweigepflichtentbindung, damit wir Befunde direkt bei Ihren behandelnden Ärzt:innen anfordern können.',
),
category: 'allgemein',
order: 2,
},
{
question: 'Wie läuft das Zweitmeinungsverfahren ab?',
answer: createRichText(
'Nach einem telefonischen Vorgespräch prüfen unsere Fachärzt:innen Ihre Unterlagen. Anschließend erhalten Sie ein schriftliches Gutachten mit einer klaren, medizinisch fundierten Empfehlung. Wenn gewünscht, besprechen wir das Ergebnis zusätzlich persönlich mit Ihnen telefonisch oder per Videocall.',
),
category: 'allgemein',
order: 3,
},
{
question: 'Kann ich die Zweitmeinung auch einholen, wenn die Therapie schon begonnen hat?',
answer: createRichText(
'Ja, auch bei laufender Behandlung ist eine Zweitmeinung sinnvoll. Unsere Expert:innen bewerten den aktuellen Stand und prüfen, ob Anpassungen empfehlenswert sind etwa bei Therapiewechsel, Nebenwirkungen oder veränderter Prognose.',
),
category: 'allgemein',
order: 4,
},
{
question: 'Beeinflusst die Zweitmeinung meine Behandlung oder meine Ärzt:innen?',
answer: createRichText(
'Nein. Die Zweitmeinung ist eine unabhängige Einschätzung und dient allein Ihrer Information und Entscheidungsfindung. Sie können das Ergebnis mit Ihren behandelnden Ärzt:innen besprechen oder es für sich behalten die Entscheidung liegt bei Ihnen.',
),
category: 'allgemein',
order: 5,
},
// ── Kardiologie ──
{
question: 'Wann ist eine Zweitmeinung vor einem Herzkatheter sinnvoll?',
answer: createRichText(
'Immer dann, wenn ein planbarer Eingriff wie eine PCI (Stent) oder eine OP empfohlen wurde. Auch bei Unsicherheit über Nutzen und Risiken oder wenn Sie Alternativen in Betracht ziehen möchten, ist eine Zweitmeinung sinnvoll.',
),
category: 'kardiologie',
order: 6,
},
{
question: 'Wer erstellt die kardiologische Zweitmeinung?',
answer: createRichText(
'Die Zweitmeinung wird von erfahrenen Fachärzt:innen für Kardiologie erstellt, die unabhängig von der erstbehandelnden Klinik arbeiten. So ist eine neutrale Bewertung gewährleistet.',
),
category: 'kardiologie',
order: 7,
},
{
question: 'Welche Unterlagen brauche ich für die kardiologische Zweitmeinung?',
answer: createRichText(
'In der Regel benötigen wir Arztbriefe, EKG-Befunde, Echokardiografie-Berichte und ggf. Katheterprotokolle. Unser Case Management hilft Ihnen bei der Zusammenstellung.',
),
category: 'kardiologie',
order: 8,
},
{
question: 'Muss ich den Eingriff absagen, wenn ich eine Zweitmeinung einhole?',
answer: createRichText(
'Nein, Sie müssen keinen geplanten Eingriff absagen. Die Zweitmeinung ist ein zusätzliches Informationsangebot und beeinflusst Ihren bestehenden Behandlungsplan nicht automatisch.',
),
category: 'kardiologie',
order: 9,
},
{
question: 'Was passiert, wenn die Einschätzung von der ursprünglichen Empfehlung abweicht?',
answer: createRichText(
'In diesem Fall erhalten Sie eine fundierte Begründung, warum eine alternative Behandlung in Betracht gezogen werden könnte. Sie können die Ergebnisse mit Ihren behandelnden Ärzt:innen besprechen und gemeinsam eine Entscheidung treffen.',
),
category: 'kardiologie',
order: 10,
},
// ── Schilddrüse ──
{
question: 'Wann ist eine Zweitmeinung zur Schilddrüsen-OP sinnvoll?',
answer: createRichText(
'Eine Zweitmeinung ist sinnvoll, wenn Ihnen eine Schilddrüsenoperation empfohlen wurde insbesondere bei Knoten, Struma oder Verdacht auf Schilddrüsenkrebs. Auch bei unklaren Befunden oder wenn Sie konservative Alternativen prüfen möchten.',
),
category: 'schilddruese',
order: 11,
},
{
question: 'Welche Unterlagen werden für die Schilddrüsen-Zweitmeinung benötigt?',
answer: createRichText(
'Wir benötigen in der Regel Ultraschallbefunde, Szintigraphie-Ergebnisse, Laborwerte (TSH, fT3, fT4) und ggf. Feinnadelpunktionsbefunde. Unser Team unterstützt Sie bei der Beschaffung.',
),
category: 'schilddruese',
order: 12,
},
{
question: 'Wer erstellt die Schilddrüsen-Zweitmeinung?',
answer: createRichText(
'Die Zweitmeinung wird von erfahrenen Fachärzt:innen für Endokrinologie oder Schilddrüsenchirurgie erstellt, die unabhängig und neutral arbeiten.',
),
category: 'schilddruese',
order: 13,
},
{
question: 'Ist die Zweitmeinung verbindlich für meine behandelnden Ärzt:innen?',
answer: createRichText(
'Nein. Die Zweitmeinung ist eine unabhängige fachliche Einschätzung. Sie dient Ihrer Information und kann als Grundlage für ein Gespräch mit Ihren behandelnden Ärzt:innen dienen, ist aber nicht bindend.',
),
category: 'schilddruese',
order: 14,
},
{
question: 'Kostet mich die Schilddrüsen-Zweitmeinung etwas?',
answer: createRichText(
'Die Kosten hängen vom Umfang der Beurteilung ab. In vielen Fällen beteiligen sich Krankenkassen an den Kosten einer Zweitmeinung. Wir informieren Sie vorab transparent über anfallende Kosten.',
),
category: 'schilddruese',
order: 15,
},
// ── Gallenblase ──
{
question: 'Wann ist eine Zweitmeinung zur Gallenblasenentfernung sinnvoll?',
answer: createRichText(
'Immer dann, wenn Ihnen eine Cholezystektomie (Gallenblasenentfernung) empfohlen wurde und Sie unsicher sind, ob der Eingriff wirklich notwendig ist besonders bei asymptomatischen Gallensteinen oder leichten Beschwerden.',
),
category: 'gallenblase',
order: 16,
},
{
question: 'Wer erstellt die Gallenblase-Zweitmeinung?',
answer: createRichText(
'Die Zweitmeinung wird von erfahrenen Fachärzt:innen für Viszeralchirurgie oder Gastroenterologie erstellt, die unabhängig von der erstbehandelnden Klinik arbeiten.',
),
category: 'gallenblase',
order: 17,
},
{
question: 'Welche Unterlagen brauche ich für die Gallenblase-Zweitmeinung?',
answer: createRichText(
'Wir benötigen in der Regel Ultraschallbefunde, Laborbefunde und den Arztbrief mit der OP-Empfehlung. Unser Case Management unterstützt Sie bei der Zusammenstellung.',
),
category: 'gallenblase',
order: 18,
},
{
question: 'Gibt es Alternativen zur Gallenblasen-OP?',
answer: createRichText(
'In manchen Fällen ja. Abhängig von der Art und Lage der Gallensteine sowie Ihren Beschwerden können konservative Maßnahmen, Ernährungsumstellung oder eine abwartende Strategie sinnvoll sein. Genau das prüfen wir in unserer Zweitmeinung.',
),
category: 'gallenblase',
order: 19,
},
{
question: 'Was kostet die Gallenblase-Zweitmeinung?',
answer: createRichText(
'Die Kosten hängen vom Umfang der Beurteilung ab. In vielen Fällen beteiligen sich Krankenkassen an den Kosten einer Zweitmeinung. Wir informieren Sie vorab transparent über anfallende Kosten.',
),
category: 'gallenblase',
order: 20,
},
// ── Nephrologie ──
{
question: 'Wann ist eine Zweitmeinung bei Nierenerkrankungen sinnvoll?',
answer: createRichText(
'Eine Zweitmeinung ist sinnvoll bei Empfehlung zur Dialyse, bei fortschreitender Niereninsuffizienz oder vor einer Transplantationsentscheidung. Sie hilft, den optimalen Zeitpunkt und die beste Behandlungsstrategie zu bestimmen.',
),
category: 'nephrologie',
order: 21,
},
{
question: 'Welche Unterlagen sind für die nephrologische Zweitmeinung wichtig?',
answer: createRichText(
'Wir benötigen aktuelle Laborwerte (Kreatinin, GFR, Elektrolyte), nephrologische Befunde, bildgebende Diagnostik und ggf. Biopsie-Ergebnisse. Unser Team hilft bei der Zusammenstellung.',
),
category: 'nephrologie',
order: 22,
},
{
question: 'Kann ich die Zweitmeinung auch einholen, wenn die Dialyse bereits begonnen hat?',
answer: createRichText(
'Ja. Auch bei laufender Dialyse kann eine Zweitmeinung sinnvoll sein etwa zur Bewertung alternativer Dialyseverfahren, zur Prüfung einer Transplantationseignung oder zur Optimierung der Behandlung.',
),
category: 'nephrologie',
order: 23,
},
{
question: 'Kostet mich die nephrologische Zweitmeinung etwas?',
answer: createRichText(
'Die Kosten hängen vom Umfang der Beurteilung ab. In vielen Fällen beteiligen sich Krankenkassen an den Kosten einer Zweitmeinung. Wir informieren Sie vorab transparent über anfallende Kosten.',
),
category: 'nephrologie',
order: 24,
},
]
for (const faq of faqs) {
const id = await upsert(
payload,
'faqs',
{ question: { equals: faq.question } },
{
...faq,
isActive: true,
},
)
console.log(`✓ FAQ #${faq.order}: "${faq.question.substring(0, 50)}..." (ID: ${id})`)
}
// ════════════════════════════════════════════
// 5. SOCIAL LINKS
// ════════════════════════════════════════════
console.log('\n--- 5. Social Links ---')
const socialLinks = [
{ platform: 'linkedin' as const, url: 'https://de.linkedin.com/company/complex-care-solutions-gmbh' },
{ platform: 'facebook' as const, url: 'https://www.facebook.com/complex-care-solutions-GmbH' },
{ platform: 'instagram' as const, url: 'https://www.instagram.com/c2steam' },
{ platform: 'youtube' as const, url: 'https://www.youtube.com/@complexcaresolutionsgmbh2682' },
]
for (const link of socialLinks) {
const id = await upsert(payload, 'social-links', { platform: { equals: link.platform } }, {
...link,
isActive: true,
})
console.log(`✓ Social Link "${link.platform}" (ID: ${id})`)
}
// ════════════════════════════════════════════
// 6. NAVIGATION
// ════════════════════════════════════════════
console.log('\n--- 6. Navigation ---')
await upsert(payload, 'navigations', {}, {
title: 'Hauptnavigation',
mainMenu: [
{
label: 'Fachbereiche',
type: 'submenu',
submenu: [
{ label: 'Intensivmedizin', linkType: 'custom', url: '/fachbereiche/zweitmeinung-intensivmedizin' },
{ label: 'Kardiologie', linkType: 'custom', url: '/fachbereiche/zweitmeinung-kardiologie' },
{ label: 'Onkologie', linkType: 'custom', url: '/fachbereiche/zweitmeinung-onkologie' },
{ label: 'Nephrologie', linkType: 'custom', url: '/fachbereiche/zweitmeinung-nephrologie' },
{ label: 'Gallenblase', linkType: 'custom', url: '/fachbereiche/zweitmeinung-gallenblase' },
{ label: 'Schilddrüse', linkType: 'custom', url: '/fachbereiche/zweitmeinung-schilddruese' },
],
},
{ label: "So funktioniert's", type: 'custom', url: '/so-funktionierts' },
{ label: 'FAQ', type: 'custom', url: '/faq' },
{ label: 'Über uns', type: 'custom', url: '/ueber-uns' },
{ label: 'Motivation', type: 'custom', url: '/motivation' },
{ label: 'Kontakt', type: 'custom', url: '/kontakt' },
],
footerMenu: [
{ label: 'Impressum', linkType: 'custom', url: '/impressum' },
{ label: 'Datenschutz', linkType: 'custom', url: '/datenschutz' },
{ label: 'FAQ', linkType: 'custom', url: '/faq' },
{ label: 'Kontakt', linkType: 'custom', url: '/kontakt' },
],
})
console.log('✓ Navigation created/updated')
// ════════════════════════════════════════════
// 7. CONTACT FORM
// ════════════════════════════════════════════
console.log('\n--- 7. Contact Form ---')
const existingForm = await payload.find({
collection: 'forms',
where: { tenant: { equals: TENANT_ID } },
limit: 1,
})
if (existingForm.docs.length > 0) {
console.log(`✓ Contact form already exists (ID: ${existingForm.docs[0].id})`)
} else {
const form = await payload.create({
collection: 'forms',
data: {
title: 'Kontaktformular',
tenant: TENANT_ID,
fields: [
{
blockType: 'text',
name: 'name',
label: 'Name',
required: true,
width: 50,
},
{
blockType: 'email',
name: 'email',
label: 'E-Mail',
required: true,
width: 50,
},
{
blockType: 'text',
name: 'phone',
label: 'Telefon',
required: false,
width: 50,
},
{
blockType: 'select',
name: 'subject',
label: 'Fachbereich',
required: true,
width: 50,
options: [
{ label: 'Allgemeine Anfrage', value: 'allgemein' },
{ label: 'Zweitmeinung Intensivmedizin', value: 'intensivmedizin' },
{ label: 'Zweitmeinung Kardiologie', value: 'kardiologie' },
{ label: 'Zweitmeinung Onkologie', value: 'onkologie' },
{ label: 'Zweitmeinung Nephrologie', value: 'nephrologie' },
{ label: 'Zweitmeinung Gallenblase', value: 'gallenblase' },
{ label: 'Zweitmeinung Schilddrüse', value: 'schilddruese' },
],
},
{
blockType: 'select',
name: 'urgency',
label: 'Dringlichkeit',
required: false,
width: 100,
options: [
{ label: 'Normal', value: 'normal' },
{ label: 'Dringend', value: 'dringend' },
{ label: 'Notfall', value: 'notfall' },
],
},
{
blockType: 'textarea',
name: 'message',
label: 'Ihre Nachricht',
required: true,
width: 100,
},
],
submitButtonLabel: 'Nachricht senden',
confirmationType: 'message',
confirmationMessage: createRichText(
'Vielen Dank für Ihre Anfrage. Wir melden uns schnellstmöglich bei Ihnen.',
),
} as any,
})
console.log(`✓ Contact form created (ID: ${form.id})`)
}
// ════════════════════════════════════════════
// DONE
// ════════════════════════════════════════════
console.log('\n✅ Seed complete! All content for tenant 12 (zweitmeinung) has been created.')
console.log('\nSummary:')
console.log(` - Site Settings: 1`)
console.log(` - Service Categories: ${Object.keys(categoryIds).length}`)
console.log(` - Services: ${Object.keys(serviceIds).length}`)
console.log(` - FAQs: ${faqs.length}`)
console.log(` - Social Links: ${socialLinks.length}`)
console.log(` - Navigation: 1`)
console.log(` - Contact Form: 1`)
process.exit(0)
}
seed().catch((err) => {
console.error('❌ Seed failed:', err)
process.exit(1)
})

View file

@ -47,11 +47,37 @@ export async function getTenantIdFromHost(req: PayloadRequest): Promise<number |
}
}
/**
* Extracts tenant ID from the where[tenant][equals] query parameter.
* Used as fallback when the Host header doesn't match any tenant domain
* (e.g. when the CMS is accessed via cms.c2sgmbh.de by frontend API clients).
*/
function getTenantIdFromQuery(req: PayloadRequest): number | null {
try {
const url = req.url ? new URL(req.url, 'http://localhost') : null
const param = url?.searchParams.get('where[tenant][equals]')
if (param) {
const id = Number(param)
if (!isNaN(id) && id > 0) return id
}
return null
} catch {
return null
}
}
/**
* Access-Control für öffentlich lesbare, aber tenant-isolierte Collections.
*
* - Authentifizierte Admin-User: Voller Lesezugriff
* - Anonyme Requests: Nur Daten des eigenen Tenants (basierend auf Domain)
* - Anonyme Requests: Nur Daten des eigenen Tenants
*
* Tenant resolution order:
* 1. Host header (matches tenant domain config)
* 2. where[tenant][equals] query parameter (for API clients like contracts)
*
* The returned access filter ensures tenant isolation regardless of which
* method resolved the tenant ID.
*/
export const tenantScopedPublicRead: Access = async ({ req }) => {
// Authentifizierte Admins dürfen alles lesen
@ -59,11 +85,11 @@ export const tenantScopedPublicRead: Access = async ({ req }) => {
return true
}
// Anonyme Requests: Tenant aus Domain ermitteln
const tenantId = await getTenantIdFromHost(req)
// Anonyme Requests: Tenant aus Domain oder Query-Parameter ermitteln
const tenantId = (await getTenantIdFromHost(req)) ?? getTenantIdFromQuery(req)
if (!tenantId) {
// Keine gültige Domain → kein Zugriff
// Weder gültige Domain noch Tenant-Parameter → kein Zugriff
return false
}