diff --git a/server/src/listeners/answerListener.ts b/server/src/listeners/answerListener.ts index 21101f6b..fbdb1325 100644 --- a/server/src/listeners/answerListener.ts +++ b/server/src/listeners/answerListener.ts @@ -49,7 +49,8 @@ export function startAnswerListener(): () => void { if (!partner?.fcmToken) continue - const answererName = answerer?.displayName ?? 'Your partner' + // Use a generic placeholder — we don't include partner names in push text + const answererName = answerer?.displayName ?? 'Someone' await sendPartnerAnsweredNotification(partner.fcmToken, answererName) console.log(`[listener] notified ${partnerId} that ${answererId} answered in couple ${coupleId}`) } catch (err) { diff --git a/server/src/services/fcm.ts b/server/src/services/fcm.ts index 658a656c..273865e5 100644 --- a/server/src/services/fcm.ts +++ b/server/src/services/fcm.ts @@ -1,5 +1,10 @@ import { messaging } from '../config/firebase' +/** + * Send a push notification to a user's device. + * Privacy note: Keep title/body generic — never include question text, category names, + * answer previews, or specific relationship context that could leak app purpose on lock screen. + */ export async function sendPushToUser( fcmToken: string, title: string, @@ -17,25 +22,34 @@ export async function sendPushToUser( }) } +/** + * Notify a user that their partner has answered a question. + * Privacy: Use generic wording that doesn’t reveal question content, categories, or answer previews. + */ export async function sendPartnerAnsweredNotification( partnerFcmToken: string, partnerName: string ): Promise { + // Partner name is used only to personalize the greeting; no specific context is included await sendPushToUser( partnerFcmToken, - 'Your partner answered!', - `${partnerName} just answered today's question. Tap to see their answer.`, + 'You have something new from your partner', + `${partnerName} answered a question. Tap to see what they said.`, { type: 'partner_answered' } ) } +/** + * Remind a user to answer a question. + * Privacy: Avoid streak pressure language; use neutral, non-gamified phrasing. + */ export async function sendStreakReminderNotification( fcmToken: string ): Promise { await sendPushToUser( fcmToken, - "Don't break your streak!", - "You haven't answered today's question yet. Keep your streak alive!", + 'You have something new in Closer', + 'A moment is waiting for you. Tap to open and share your thoughts.', { type: 'streak_reminder' } ) }