feat: migrate Payload CMS to MDX and harden static infrastructure
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getPayload } from 'payload';
|
||||
import configPromise from '@payload-config';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
/**
|
||||
* Deep CMS Health Check
|
||||
* Validates that Payload CMS can actually query the database.
|
||||
* Used by post-deploy smoke tests to catch migration/schema issues.
|
||||
*/
|
||||
export async function GET() {
|
||||
const checks: Record<string, string> = {};
|
||||
|
||||
try {
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
checks.init = 'ok';
|
||||
|
||||
// Verify each collection can be queried (catches missing locale tables, broken migrations)
|
||||
const collections = ['posts', 'products', 'pages', 'media'] as const;
|
||||
for (const collection of collections) {
|
||||
try {
|
||||
await payload.find({ collection, limit: 1, locale: 'en' });
|
||||
checks[collection] = 'ok';
|
||||
} catch (e: any) {
|
||||
checks[collection] = `error: ${e.message?.substring(0, 100)}`;
|
||||
}
|
||||
}
|
||||
|
||||
const hasErrors = Object.values(checks).some(v => v.startsWith('error'));
|
||||
return NextResponse.json(
|
||||
{ status: hasErrors ? 'degraded' : 'ok', checks },
|
||||
{ status: hasErrors ? 503 : 200 },
|
||||
);
|
||||
} catch (e: any) {
|
||||
return NextResponse.json(
|
||||
{ status: 'error', message: e.message?.substring(0, 200), checks },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { getPayload } from 'payload';
|
||||
import config from '@/payload.config';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const payload = await getPayload({ config });
|
||||
|
||||
// Clear the excerpt for page ID 6
|
||||
await payload.update({
|
||||
collection: 'pages',
|
||||
id: 6,
|
||||
data: {
|
||||
excerpt: '',
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true, message: 'AVB excerpt cleared successfully on production!' });
|
||||
} catch (error: any) {
|
||||
console.error('Error fixing AVB:', error);
|
||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getPayload } from 'payload';
|
||||
import configPromise from '@payload-config';
|
||||
import { renderToStream } from '@react-pdf/renderer';
|
||||
import React from 'react';
|
||||
import { PDFPage } from '@/lib/pdf-page';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export async function GET(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
|
||||
try {
|
||||
const { slug } = await params;
|
||||
|
||||
// Handle AGBs specifically - either fetch from collection or use fallback file
|
||||
if (slug === 'agbs') {
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
const currentAgbs = await payload.find({
|
||||
collection: 'agbs-collection',
|
||||
where: {
|
||||
isCurrent: { equals: true },
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
|
||||
if (currentAgbs.totalDocs > 0) {
|
||||
const agb = currentAgbs.docs[0];
|
||||
const media = agb.file as any;
|
||||
if (media && media.url) {
|
||||
// If it's a remote URL or absolute path, we might need to fetch it
|
||||
// For now assume it's a local file in public/media
|
||||
const filePath = path.join(process.cwd(), 'public', media.url);
|
||||
if (fs.existsSync(filePath)) {
|
||||
const fileBuffer = fs.readFileSync(filePath);
|
||||
return new NextResponse(fileBuffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition': `attachment; filename="${media.filename}"`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for hardcoded legacy AGB
|
||||
const filePath = path.join(process.cwd(), 'public', 'AVB-KLZ-4-2026.pdf');
|
||||
if (fs.existsSync(filePath)) {
|
||||
const fileBuffer = fs.readFileSync(filePath);
|
||||
return new NextResponse(fileBuffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition': `attachment; filename="AVB-KLZ-4-2026.pdf"`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get Payload App
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
|
||||
// Fetch the page
|
||||
const pages = await payload.find({
|
||||
collection: 'pages',
|
||||
where: {
|
||||
slug: { equals: slug },
|
||||
_status: { equals: 'published' },
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
|
||||
if (pages.totalDocs === 0) {
|
||||
return new NextResponse('Page not found', { status: 404 });
|
||||
}
|
||||
|
||||
const page = pages.docs[0];
|
||||
|
||||
// Determine locale from searchParams or default to 'de'
|
||||
const searchParams = req.nextUrl.searchParams;
|
||||
const locale = (searchParams.get('locale') as 'en' | 'de') || 'de';
|
||||
|
||||
// Render the React-PDF document into a stream
|
||||
const stream = await renderToStream(<PDFPage page={page} locale={locale} />);
|
||||
|
||||
// Pipe the Node.js Readable stream into a valid fetch/Web Response stream
|
||||
const body = new ReadableStream({
|
||||
start(controller) {
|
||||
stream.on('data', (chunk) => controller.enqueue(chunk));
|
||||
stream.on('end', () => controller.close());
|
||||
stream.on('error', (err) => controller.error(err));
|
||||
},
|
||||
cancel() {
|
||||
(stream as any).destroy?.();
|
||||
},
|
||||
});
|
||||
|
||||
const filename = `${slug}.pdf`;
|
||||
|
||||
return new NextResponse(body, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||
// Cache control if needed, skip for now.
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error generating PDF:', error);
|
||||
return new NextResponse('Internal Server Error', { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user