From 139a78c22219a30f109b4af8e7b164582b47f10c Mon Sep 17 00:00:00 2001 From: null Date: Tue, 30 Jun 2026 20:43:18 -0500 Subject: [PATCH] feat(backup): add RESTORE_REQUESTED and RESTORE_SELF_ALERT notification types --- .../PartnerNotificationManager.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt b/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt index 4c39d508..57aa7fed 100644 --- a/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt +++ b/app/src/main/java/app/closer/notifications/PartnerNotificationManager.kt @@ -111,6 +111,10 @@ class PartnerNotificationManager @Inject constructor( return when (type) { PartnerNotificationType.CHAT_MESSAGE -> settings.chatMessageEnabled PartnerNotificationType.OUTCOME_REMINDER -> settings.outcomeReminderEnabled + // Locked-out partner needs help — never gated by the routine partner-activity toggle. + PartnerNotificationType.RESTORE_REQUESTED -> true + // Account-security signal to the real owner — always delivered. + PartnerNotificationType.RESTORE_SELF_ALERT -> true else -> when (type.rateType) { NotificationRateLimiter.Type.PARTNER_TRIGGER -> settings.partnerAnsweredEnabled NotificationRateLimiter.Type.REMINDER -> settings.dailyReminderEnabled @@ -267,6 +271,22 @@ enum class PartnerNotificationType( channelId = NotificationChannelSetup.CHANNEL_PARTNER_ACTIONS, rateType = NotificationRateLimiter.Type.PARTNER_TRIGGER ), + // Partner-assisted restore: the partner is locked out on a new device and needs your help to + // restore their history. High-signal help request — not suppressed by routine activity toggles. + RESTORE_REQUESTED( + title = "Help your partner restore 💜", + body = "They're setting up on a new device. Tap to help.", + channelId = NotificationChannelSetup.CHANNEL_PARTNER_ACTIONS, + rateType = NotificationRateLimiter.Type.PARTNER_TRIGGER + ), + // Security "was this you?" alert sent to the RECIPIENT's own devices when a restore is requested/completed + // on their account — surfaces an account-takeover to the real owner. Never suppressed by activity toggles. + RESTORE_SELF_ALERT( + title = "New device is restoring your history", + body = "If this wasn't you, secure your account now.", + channelId = NotificationChannelSetup.CHANNEL_PARTNER_ACTIONS, + rateType = NotificationRateLimiter.Type.PARTNER_TRIGGER + ), DAILY_QUESTION_REMINDER( title = "Tonight's question is waiting.", body = "Answer together before it expires.", @@ -345,6 +365,9 @@ enum class PartnerNotificationType( THINKING_OF_YOU -> AppRoute.HOME DATE_REFLECTION_PARTNER, DATE_REFLECTION_READY, DATE_LOGGED -> payload.dateId?.let { AppRoute.dateReflection(it) } ?: AppRoute.DATE_MEMORIES + RESTORE_REQUESTED -> AppRoute.RESTORE_CONSENT + // Tapping the "was this you?" alert opens account security so the owner can react. + RESTORE_SELF_ALERT -> AppRoute.SECURITY DAILY_QUESTION_REMINDER -> AppRoute.DAILY_QUESTION // Open the actual conversation so the partner can reply in place. CHAT_MESSAGE -> if (payload.conversationId != null && coupleId.isNotBlank()) { @@ -380,6 +403,8 @@ enum class PartnerNotificationType( "date_reflection_partner" -> DATE_REFLECTION_PARTNER "date_reflection_ready" -> DATE_REFLECTION_READY "date_logged" -> DATE_LOGGED + "restore_requested" -> RESTORE_REQUESTED + "restore_self_alert" -> RESTORE_SELF_ALERT // Server emits both 'daily_question' (assignment) and 'daily_question_reminder' — both open Today. "daily_question", "daily_question_reminder" -> DAILY_QUESTION_REMINDER "chat_message" -> CHAT_MESSAGE