perf: decouple pdf and mail generation from synchronous checkout flow
This commit is contained in:
@@ -4,6 +4,10 @@ import { createClient } from '@/lib/supabase/server';
|
||||
import { createHash } from 'crypto';
|
||||
import { buildCustomerSnapshot, buildOrderSnapshot } from '@/lib/license-transform';
|
||||
import { getProducts, getCategories } from '@/lib/actions/products';
|
||||
import { sendMail } from '@/utils/mail';
|
||||
import { renderToBuffer } from '@react-pdf/renderer';
|
||||
import React from 'react';
|
||||
import { InvoicePDF } from '@/components/invoice-pdf';
|
||||
|
||||
function generateOrderNumber(prefix: 'BE' | 'AE' = 'AE'): string {
|
||||
const year = new Date().getFullYear();
|
||||
@@ -16,6 +20,55 @@ function hashOrderPayload(endCustomerId: string, items: any[]): string {
|
||||
return createHash('sha256').update(str).digest('hex');
|
||||
}
|
||||
|
||||
// Asynchroner Hintergrund-Worker für Post-Processing (PDF-Erstellung und E-Mail)
|
||||
async function triggerPostProcessing(orderId: string, supabase: any, customerSnapshot: any, orderSnapshot: any, type: string, email: string) {
|
||||
try {
|
||||
const { data: order, error } = await supabase
|
||||
.from('orders')
|
||||
.select('*')
|
||||
.eq('id', orderId)
|
||||
.single();
|
||||
|
||||
if (error || !order) {
|
||||
console.error(`Post-Processing failed: Order ${orderId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
// PDF generieren
|
||||
const buffer = await renderToBuffer(
|
||||
React.createElement(InvoicePDF, {
|
||||
order,
|
||||
customer: customerSnapshot,
|
||||
orderSnapshot,
|
||||
})
|
||||
);
|
||||
|
||||
const fileName = `ab_${order.id}.pdf`;
|
||||
const { error: uploadError } = await supabase
|
||||
.storage
|
||||
.from('invoices')
|
||||
.upload(fileName, buffer, { contentType: 'application/pdf', upsert: true });
|
||||
|
||||
if (!uploadError) {
|
||||
await supabase.from('orders').update({ pdf_url: fileName }).eq('id', order.id);
|
||||
} else {
|
||||
console.error(`PDF Upload failed for order ${orderId}:`, uploadError);
|
||||
}
|
||||
|
||||
// E-Mail versenden
|
||||
if (email) {
|
||||
await sendMail({
|
||||
to: email,
|
||||
subject: `Bestätigung Ihrer CASPOS-Anfrage ${order.order_number}`,
|
||||
text: `Vielen Dank für Ihre Anfrage ${order.order_number}.`,
|
||||
html: `<p>Vielen Dank für Ihre Anfrage <strong>${order.order_number}</strong>.</p>`
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Error in post-processing for order ${orderId}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkoutAction(params: {
|
||||
items: any[];
|
||||
endCustomerId: string;
|
||||
@@ -132,6 +185,13 @@ export async function checkoutAction(params: {
|
||||
|
||||
if (orderError) throw orderError;
|
||||
orderIds.push(order.id);
|
||||
|
||||
// Entkoppeltes Post-Processing (asynchroner Aufruf)
|
||||
if (user.email) {
|
||||
Promise.resolve().then(() => {
|
||||
triggerPostProcessing(order.id, supabase, customerSnapshot, orderSnapshot, type, user.email!);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
await createOrderGroup(purchaseItems, 'purchase', 'invoice');
|
||||
|
||||
Reference in New Issue
Block a user