feat(crewing): Phase 4c — sign-off & experience (flagged) #72

Merged
shad0w merged 3 commits from feat/crewing-signoff into feat/crewing-admin 2026-06-22 18:52:57 +00:00
Showing only changes of commit 712e040fc2 - Show all commits

View file

@ -3,7 +3,10 @@ import { db } from "@/lib/db";
import type { PurchaseOrder, User } from "@prisma/client";
const isDev = process.env.NODE_ENV === "development";
const resend = isDev ? null : new Resend(process.env.RESEND_API_KEY);
// Construct the Resend client only when a key is actually present — in dev, CI,
// or any env without RESEND_API_KEY we fall back to console logging (the Resend
// v4 constructor throws on a missing key). `canSend` gates the real send path.
const resend = !isDev && process.env.RESEND_API_KEY ? new Resend(process.env.RESEND_API_KEY) : null;
const FROM = `${process.env.EMAIL_FROM_NAME ?? "PPMS"} <${process.env.EMAIL_FROM ?? "noreply@ppms.pelagiamarine.com"}>`;
const APP_URL = (process.env.NEXTAUTH_URL ?? "https://portal.pelagiamarine.com").replace(/\/$/, "");
@ -84,13 +87,13 @@ export async function notify({ event, po, recipients, note }: NotifyParams) {
const link = buildInAppLink(event, po, recipient);
let status = "sent";
if (isDev) {
if (!resend) {
console.log(
`\n📧 [DEV EMAIL] To: ${recipient.email}\n Subject: ${subject}\n Body: ${buildEmailBody(event, po, note)}\n Link: ${APP_URL}${link}\n`
);
} else {
try {
const { error } = await resend!.emails.send({
const { error } = await resend.emails.send({
from: FROM,
to: recipient.email,
subject,
@ -441,13 +444,13 @@ export async function notifyCrew({ event, recipients, subject, body, link }: Cre
await Promise.allSettled(
recipients.map(async (recipient) => {
let status = "sent";
if (isDev) {
if (!resend) {
console.log(
`\n📧 [DEV EMAIL] To: ${recipient.email}\n Subject: ${subject}\n Body: ${body}\n Link: ${APP_URL}${link ?? ""}\n`
);
} else {
try {
const { error } = await resend!.emails.send({
const { error } = await resend.emails.send({
from: FROM,
to: recipient.email,
subject,