diff --git a/src/app/(frontend)/api/news/[slug]/route.ts b/src/app/(frontend)/api/news/[slug]/route.ts index 85d8054..aa0a9a9 100644 --- a/src/app/(frontend)/api/news/[slug]/route.ts +++ b/src/app/(frontend)/api/news/[slug]/route.ts @@ -3,8 +3,11 @@ import { NextRequest, NextResponse } from 'next/server' import { getPayload } from 'payload' +import type { Where } from 'payload' import config from '@payload-config' import type { Category, Media, Post } from '@/payload-types' + +type Locale = 'de' | 'en' | 'all' import { searchLimiter, rateLimitHeaders, @@ -49,8 +52,8 @@ export async function GET(request: NextRequest, { params }: RouteParams) { const includeRelated = searchParams.get('includeRelated') !== 'false' // Default true // Validate locale - const validLocales = ['de', 'en'] - const locale = localeParam && validLocales.includes(localeParam) ? localeParam : 'de' + const validLocales: Locale[] = ['de', 'en'] + const locale: Locale = localeParam && validLocales.includes(localeParam as Locale) ? (localeParam as Locale) : 'de' // Parse tenant ID - REQUIRED for tenant isolation const tenantId = tenantParam ? parseInt(tenantParam, 10) : undefined @@ -68,7 +71,7 @@ export async function GET(request: NextRequest, { params }: RouteParams) { const payload = await getPayload({ config }) // Build where clause (tenant is now required) - const where: Record = { + const where: Where = { slug: { equals: slug }, status: { equals: 'published' }, tenant: { equals: tenantId }, diff --git a/src/app/(frontend)/api/news/route.ts b/src/app/(frontend)/api/news/route.ts index 5cafb18..373a144 100644 --- a/src/app/(frontend)/api/news/route.ts +++ b/src/app/(frontend)/api/news/route.ts @@ -3,8 +3,11 @@ import { NextRequest, NextResponse } from 'next/server' import { getPayload } from 'payload' +import type { Where } from 'payload' import config from '@payload-config' import type { Category, Media, Post } from '@/payload-types' + +type Locale = 'de' | 'en' | 'all' import { searchLimiter, rateLimitHeaders, @@ -29,7 +32,7 @@ interface NewsQueryParams { search?: string year?: number month?: number - locale: string + locale: Locale page: number limit: number excludeIds?: number[] @@ -51,7 +54,7 @@ async function getNews(payload: Awaited>, params: } = params // Build where clause - const where: Record = { + const where: Where = { status: { equals: 'published' }, } @@ -131,7 +134,7 @@ async function getNews(payload: Awaited>, params: // Execute query return payload.find({ collection: 'posts', - where, + where: where as Where, sort: '-publishedAt', page, limit, @@ -144,16 +147,16 @@ async function getNews(payload: Awaited>, params: async function getCategories( payload: Awaited>, tenantId?: number, - locale: string = 'de' + locale: Locale = 'de' ) { - const where: Record = {} + const where: Where = {} if (tenantId) { where.tenant = { equals: tenantId } } const result = await payload.find({ collection: 'categories', - where, + where: where as Where, sort: 'name', limit: 100, locale, @@ -172,7 +175,7 @@ async function getArchive( payload: Awaited>, tenantId: number // Now required ) { - const where: Record = { + const where: Where = { status: { equals: 'published' }, publishedAt: { exists: true }, tenant: { equals: tenantId }, @@ -187,7 +190,7 @@ async function getArchive( while (hasMore) { const result = await payload.find({ collection: 'posts', - where, + where: where as Where, sort: '-publishedAt', page, limit: pageSize, @@ -270,8 +273,8 @@ export async function GET(request: NextRequest) { const includeArchive = searchParams.get('includeArchive') === 'true' // Validate locale - const validLocales = ['de', 'en'] - const locale = localeParam && validLocales.includes(localeParam) ? localeParam : 'de' + const validLocales: Locale[] = ['de', 'en'] + const locale: Locale = localeParam && validLocales.includes(localeParam as Locale) ? (localeParam as Locale) : 'de' // Validate and parse types let types: NewsType | NewsType[] | undefined diff --git a/src/app/(frontend)/api/team/[slug]/vcard/route.ts b/src/app/(frontend)/api/team/[slug]/vcard/route.ts index 2be75f9..fdb06a4 100644 --- a/src/app/(frontend)/api/team/[slug]/vcard/route.ts +++ b/src/app/(frontend)/api/team/[slug]/vcard/route.ts @@ -50,7 +50,7 @@ export async function GET( } // Generate vCard 3.0 - const vcard = generateVCard(member) + const vcard = generateVCard(member as TeamMember) // Return as downloadable file const filename = `${member.slug || member.name?.toLowerCase().replace(/\s+/g, '-')}.vcf` diff --git a/src/app/(frontend)/api/team/route.ts b/src/app/(frontend)/api/team/route.ts index 5a7deae..bdd9766 100644 --- a/src/app/(frontend)/api/team/route.ts +++ b/src/app/(frontend)/api/team/route.ts @@ -1,7 +1,10 @@ import { NextRequest, NextResponse } from 'next/server' import { getPayload } from 'payload' +import type { Where } from 'payload' import config from '@payload-config' +type Locale = 'de' | 'en' | 'all' + /** * Team API * @@ -44,10 +47,11 @@ export async function GET(request: NextRequest) { const limit = Math.min(parseInt(searchParams.get('limit') || '50'), 100) const page = parseInt(searchParams.get('page') || '1') const sort = searchParams.get('sort') || 'order' - const locale = (searchParams.get('locale') as 'de' | 'en') || 'de' + const localeParam = searchParams.get('locale') + const locale: Locale = (localeParam === 'de' || localeParam === 'en') ? localeParam : 'de' // Build where clause - const where: Record = { + const where: Where = { tenant: { equals: parseInt(tenantId) }, isActive: { equals: true }, } @@ -94,7 +98,7 @@ export async function GET(request: NextRequest) { // Query team members const result = await payload.find({ collection: 'team', - where, + where: where as Where, sort: sortField, limit, page, diff --git a/src/app/(frontend)/api/timelines/route.ts b/src/app/(frontend)/api/timelines/route.ts index 9297146..985dd90 100644 --- a/src/app/(frontend)/api/timelines/route.ts +++ b/src/app/(frontend)/api/timelines/route.ts @@ -3,8 +3,11 @@ import { NextRequest, NextResponse } from 'next/server' import { getPayload } from 'payload' +import type { Where } from 'payload' import config from '@payload-config' import type { Media } from '@/payload-types' + +type Locale = 'de' | 'en' | 'all' import { searchLimiter, rateLimitHeaders, @@ -127,8 +130,8 @@ export async function GET(request: NextRequest) { } // Validate locale - const validLocales = ['de', 'en'] - const locale = localeParam && validLocales.includes(localeParam) ? localeParam : 'de' + const validLocales: Locale[] = ['de', 'en'] + const locale: Locale = localeParam && validLocales.includes(localeParam as Locale) ? (localeParam as Locale) : 'de' // Validate type if provided if (typeParam && !TIMELINE_TYPES.includes(typeParam as TimelineType)) { @@ -139,7 +142,7 @@ export async function GET(request: NextRequest) { } // Build where clause - const where: Record = { + const where: Where = { status: { equals: 'published' }, tenant: { equals: tenantId }, } @@ -160,7 +163,7 @@ export async function GET(request: NextRequest) { // Execute query const result = await payload.find({ collection: 'timelines', - where, + where: where as Where, sort: '-updatedAt', limit: slugParam ? 1 : 100, // Single or list locale, diff --git a/src/app/(frontend)/api/workflows/route.ts b/src/app/(frontend)/api/workflows/route.ts index aead6db..6f07a5a 100644 --- a/src/app/(frontend)/api/workflows/route.ts +++ b/src/app/(frontend)/api/workflows/route.ts @@ -3,8 +3,11 @@ import { NextRequest, NextResponse } from 'next/server' import { getPayload } from 'payload' +import type { Where } from 'payload' import config from '@payload-config' import type { Media } from '@/payload-types' + +type Locale = 'de' | 'en' | 'all' import { searchLimiter, rateLimitHeaders, @@ -122,8 +125,8 @@ export async function GET(request: NextRequest) { } // Validate locale - const validLocales = ['de', 'en'] - const locale = localeParam && validLocales.includes(localeParam) ? localeParam : 'de' + const validLocales: Locale[] = ['de', 'en'] + const locale: Locale = localeParam && validLocales.includes(localeParam as Locale) ? (localeParam as Locale) : 'de' // Validate type if provided if (typeParam && !WORKFLOW_TYPES.includes(typeParam as WorkflowType)) { @@ -142,7 +145,7 @@ export async function GET(request: NextRequest) { } // Build where clause - const where: Record = { + const where: Where = { status: { equals: 'published' }, tenant: { equals: tenantId }, } @@ -163,7 +166,7 @@ export async function GET(request: NextRequest) { // Execute query const result = await payload.find({ collection: 'workflows', - where, + where: where as Where, sort: '-updatedAt', limit: slugParam ? 1 : 100, // Single or list locale, diff --git a/src/app/(payload)/api/email-logs/stats/route.ts b/src/app/(payload)/api/email-logs/stats/route.ts index ae34093..340edd8 100644 --- a/src/app/(payload)/api/email-logs/stats/route.ts +++ b/src/app/(payload)/api/email-logs/stats/route.ts @@ -12,8 +12,10 @@ */ import { getPayload } from 'payload' +import type { Where } from 'payload' import configPromise from '@payload-config' import { NextRequest, NextResponse } from 'next/server' +import type { EmailLog } from '@/payload-types' import { logAccessDenied } from '@/lib/audit/audit-service' import { maskSmtpError } from '@/lib/security/data-masking' @@ -89,7 +91,7 @@ export async function GET(req: NextRequest): Promise { const periodDate = getPeriodDate(period) // Basis-Where für alle Queries - const baseWhere: Record = { + const baseWhere: Where = { createdAt: { greater_than_equal: periodDate.toISOString() }, } @@ -101,7 +103,7 @@ export async function GET(req: NextRequest): Promise { // Gesamt payload.count({ collection: 'email-logs', - where: baseWhere, + where: baseWhere as Where, }), // Gesendet payload.count({ @@ -161,7 +163,7 @@ export async function GET(req: NextRequest): Promise { successRate, }, bySource: sourceStats, - recentFailures: recentFailed.docs.map((doc: Record) => ({ + recentFailures: recentFailed.docs.map((doc: EmailLog) => ({ id: doc.id, to: doc.to, subject: doc.subject, diff --git a/src/lib/email/newsletter-service.ts b/src/lib/email/newsletter-service.ts index daf7a1f..caad40a 100644 --- a/src/lib/email/newsletter-service.ts +++ b/src/lib/email/newsletter-service.ts @@ -56,7 +56,7 @@ export class NewsletterService { email: string firstName?: string lastName?: string - interests?: string[] + interests?: ('general' | 'blog' | 'products' | 'offers' | 'events')[] source?: string ipAddress?: string userAgent?: string @@ -245,12 +245,14 @@ export class NewsletterService { }) // Tenant-ID ermitteln - const tenantId = typeof subscriber.tenant === 'object' + const tenantId = typeof subscriber.tenant === 'object' && subscriber.tenant ? subscriber.tenant.id : subscriber.tenant // Willkommens-E-Mail senden - await this.sendWelcomeEmail(tenantId as number, subscriber) + if (tenantId) { + await this.sendWelcomeEmail(tenantId as number, subscriber) + } return { success: true, @@ -308,7 +310,7 @@ export class NewsletterService { } // Tenant-ID ermitteln - const tenantId = typeof subscriber.tenant === 'object' + const tenantId = typeof subscriber.tenant === 'object' && subscriber.tenant ? subscriber.tenant.id : subscriber.tenant diff --git a/src/payload.config.ts b/src/payload.config.ts index 5e1f32f..b1c285a 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -308,12 +308,12 @@ export default buildConfig({ // Fix für TypeScript Types Generation - das Plugin braucht explizite relationTo Angaben redirectRelationships: ['pages'], formSubmissionOverrides: { - ...formSubmissionOverrides, + ...(formSubmissionOverrides as Record), hooks: { beforeChange: [formSubmissionBeforeChange], afterChange: [sendFormNotification], }, - }, + } as Parameters[0]['formSubmissionOverrides'], }), redirectsPlugin({ collections: ['pages'], @@ -330,10 +330,6 @@ export default buildConfig({ title: 'Payload CMS API', version: '1.0.0', description: 'Multi-Tenant CMS API für porwoll.de, complexcaresolutions.de, gunshin.de und zweitmein.ng', - contact: { - name: 'C2S GmbH', - url: 'https://complexcaresolutions.de', - }, }, }), // Swagger UI unter /api/docs