diff --git a/apps/api/src/controllers/Actions.ts b/apps/api/src/controllers/Actions.ts index 412ba99..3e74349 100644 --- a/apps/api/src/controllers/Actions.ts +++ b/apps/api/src/controllers/Actions.ts @@ -72,12 +72,13 @@ export class Actions { // Create or update contact with persistent data only // ContactService.upsert will filter out non-persistent fields - // Event tracking should subscribe contacts by default + // Event tracking should subscribe new contacts by default (subscribed=true in ContactService) + // but preserve existing subscription state for existing contacts const contact = await ContactService.upsert( auth.projectId, email, data as Record | undefined, - subscribed ?? true, + subscribed, ); // Track the event with ALL data (persistent + non-persistent) @@ -268,7 +269,9 @@ export class Actions { // Create or update contact with metadata // Transactional emails should not subscribe contacts by default - const contact = await ContactService.upsert(auth.projectId, recipient.email, recipientData, subscribed ?? false); + // New contacts default to unsubscribed unless explicitly opted in + // Existing contacts preserve their subscription state unless explicitly changed + const contact = await ContactService.upsert(auth.projectId, recipient.email, recipientData, subscribed, false); // Get merged data including non-persistent fields for template rendering const mergedData = ContactService.getMergedData(contact, data as Record | undefined); diff --git a/apps/api/src/services/ContactService.ts b/apps/api/src/services/ContactService.ts index e7f0b1d..9c032be 100644 --- a/apps/api/src/services/ContactService.ts +++ b/apps/api/src/services/ContactService.ts @@ -199,6 +199,7 @@ export class ContactService { email: string, data?: Record, subscribed?: boolean, + defaultSubscribed: boolean = true, ): Promise { // Find existing contact const existing = await prisma.contact.findFirst({ @@ -292,7 +293,7 @@ export class ContactService { projectId, email, data: Object.keys(mergedData).length > 0 ? toPrismaJson(mergedData) : Prisma.JsonNull, - subscribed: subscribed ?? true, + subscribed: subscribed ?? defaultSubscribed, }, }); }