From 614b0a5ffd686c0036ab85f686ce8ef871bb3055 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Sat, 27 Jun 2026 08:20:34 +0200 Subject: [PATCH] feat(contact): add klaus@klz-cables.com to recipients and fix pino logging --- .gitea/workflows/deploy.yml | 2 +- app/actions/contact.ts | 97 ++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 39 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b3616393..353a0af1 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -245,7 +245,7 @@ jobs: MAIL_USERNAME: ${{ secrets.SMTP_USER || vars.SMTP_USER }} MAIL_PASSWORD: ${{ secrets.SMTP_PASS || vars.SMTP_PASS }} MAIL_FROM: ${{ secrets.SMTP_FROM || vars.SMTP_FROM || 'noreply@klz-cables.com' }} - MAIL_RECIPIENTS: ${{ secrets.CONTACT_RECIPIENT || vars.CONTACT_RECIPIENT || 'info@klz-cables.com' }} + MAIL_RECIPIENTS: ${{ secrets.CONTACT_RECIPIENT || vars.CONTACT_RECIPIENT || 'info@klz-cables.com,klaus@klz-cables.com' }} # Monitoring SENTRY_DSN: ${{ secrets.SENTRY_DSN || vars.SENTRY_DSN }} diff --git a/app/actions/contact.ts b/app/actions/contact.ts index 54e48321..a62e8b2d 100644 --- a/app/actions/contact.ts +++ b/app/actions/contact.ts @@ -32,18 +32,24 @@ export async function sendContactFormAction(formData: FormData) { const productName = formData.get('productName') as string | null; if (!name || !email || !message) { - logger.warn('Missing required fields in contact form', { - name: !!name, - email: !!email, - message: !!message, - }); + logger.warn( + { + name: !!name, + email: !!email, + message: !!message, + }, + 'Missing required fields in contact form', + ); return { success: false, error: 'Missing required fields' }; } - logger.info('Payload CMS saving skipped because it has been removed', { - type: productName ? 'product_quote' : 'contact', - email, - }); + logger.info( + { + type: productName ? 'product_quote' : 'contact', + email, + }, + 'Payload CMS saving skipped because it has been removed', + ); // 1.5. Simple Fail-Safe Backup to Disk // To ensure leads are never lost if email fails or Gotify is down, we append them to a local JSON Lines file. @@ -61,14 +67,14 @@ export async function sendContactFormAction(formData: FormData) { productName, message, }; - fs.appendFileSync(backupFile, JSON.stringify(leadData) + '\\n'); - logger.info('Successfully saved lead to local backup file', { backupFile }); + fs.appendFileSync(backupFile, JSON.stringify(leadData) + '\n'); + logger.info({ backupFile }, 'Successfully saved lead to local backup file'); } catch (backupError) { - logger.error('Failed to write to local leads backup', { error: String(backupError) }); + logger.error({ error: String(backupError) }, 'Failed to write to local leads backup'); } // 2. Send Emails - logger.info('Sending branded emails', { email, productName }); + logger.info({ email, productName }, 'Sending branded emails'); const notificationSubject = productName ? `Product Inquiry: ${productName}` @@ -88,7 +94,7 @@ export async function sendContactFormAction(formData: FormData) { ); if (!isTestSubmission) { - logger.info('Sending internal notification', { recipients: env.MAIL_RECIPIENTS }); + logger.info({ recipients: env.MAIL_RECIPIENTS }, 'Sending internal notification'); const notificationResult = await sendEmail({ replyTo: email, subject: notificationSubject, @@ -96,15 +102,21 @@ export async function sendContactFormAction(formData: FormData) { }); if (notificationResult.success) { - logger.info('Notification email sent successfully', { - messageId: notificationResult.messageId, - }); + logger.info( + { + messageId: notificationResult.messageId, + }, + 'Notification email sent successfully', + ); } else { - logger.error('Notification email DELIVERY FAILED', { - error: notificationResult.error, - subject: notificationSubject, - recipients: env.MAIL_RECIPIENTS, - }); + logger.error( + { + error: notificationResult.error, + subject: notificationSubject, + recipients: env.MAIL_RECIPIENTS, + }, + 'Notification email DELIVERY FAILED', + ); services.errors.captureException( new Error(`Notification email failed: ${notificationResult.error}`), { @@ -115,7 +127,7 @@ export async function sendContactFormAction(formData: FormData) { ); } } else { - logger.info('Skipping notification email for test submission', { email }); + logger.info({ email }, 'Skipping notification email for test submission'); } // 2b. Send confirmation to Customer (branded as KLZ Cables) @@ -128,7 +140,7 @@ export async function sendContactFormAction(formData: FormData) { ); if (!isTestSubmission) { - logger.info('Sending customer confirmation', { to: email }); + logger.info({ to: email }, 'Sending customer confirmation'); const confirmationResult = await sendEmail({ to: email, subject: confirmationSubject, @@ -136,27 +148,33 @@ export async function sendContactFormAction(formData: FormData) { }); if (confirmationResult.success) { - logger.info('Confirmation email sent successfully', { - messageId: confirmationResult.messageId, - }); + logger.info( + { + messageId: confirmationResult.messageId, + }, + 'Confirmation email sent successfully', + ); } else { - logger.error('Confirmation email DELIVERY FAILED', { - error: confirmationResult.error, - subject: confirmationSubject, - to: email, - }); + logger.error( + { + error: confirmationResult.error, + subject: confirmationSubject, + to: email, + }, + 'Confirmation email DELIVERY FAILED', + ); services.errors.captureException( new Error(`Confirmation email failed: ${confirmationResult.error}`), { action: 'sendContactFormAction_confirmation', email }, ); } } else { - logger.info('Skipping confirmation email for test submission', { email }); + logger.info({ email }, 'Skipping confirmation email for test submission'); } // Notify via Gotify (Internal) await services.notifications.notify({ - title: `📩 ${notificationSubject}`, + title: `📩 [KLZ] ${notificationSubject}`, message: `New message from ${name} (${email}):\n\n${message}`, priority: 5, }); @@ -169,10 +187,13 @@ export async function sendContactFormAction(formData: FormData) { return { success: true }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); - logger.error('Failed to send branded emails', { - error: errorMsg, - stack: error instanceof Error ? error.stack : undefined, - }); + logger.error( + { + error: errorMsg, + stack: error instanceof Error ? error.stack : undefined, + }, + 'Failed to send branded emails', + ); services.errors.captureException(error, { action: 'sendContactFormAction', email });