controller (unreleased): R-921 check-first pre-check (no stop while another tier's job is in flight); R-922 email_cleared on a household's deliberate clear
gates / gates (push) Successful in 1m0s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-09 12:57:34 +02:00
parent 13eeb484ab
commit ec9b997151
16 changed files with 798 additions and 18 deletions
+7 -2
View File
@@ -2957,10 +2957,15 @@ func (s *Server) settingsNotificationsHandler(w http.ResponseWriter, r *http.Req
return
}
// R-922 (operator ruling 2026-10-09, option A): an empty address where one was stored is the household's
// deliberate clear — persisted, so this push AND every later one carry `email_cleared` while the address
// stays empty, and the hub deletes the address it holds. A box that never had one does not set it.
emailCleared := s.settings.GetNotificationPrefs().ClearedBy(email)
prefs := &settings.NotificationPrefs{
Email: email,
EnabledEvents: enabledEvents,
CooldownHours: cooldownHours,
EmailCleared: emailCleared,
}
if err := s.settings.SetNotificationPrefs(prefs); err != nil {
@@ -2971,13 +2976,13 @@ func (s *Server) settingsNotificationsHandler(w http.ResponseWriter, r *http.Req
return
}
s.logger.Printf("[INFO] [web] Notification preferences updated: email=%s, events=%v", email, enabledEvents)
s.logger.Printf("[INFO] [web] Notification preferences updated: email=%s, events=%v, email_cleared=%t", email, enabledEvents, emailCleared)
s.reportTriggerNow() // v0.139.0: hub reflects the saved prefs in seconds, not next cycle
// Sync preferences to hub
data := s.notificationsPageData()
if s.notifier != nil && s.notifier.IsEnabled() {
if err := s.notifier.SyncPreferences(email, enabledEvents, cooldownHours); err != nil {
if err := s.notifier.SyncPreferences(email, enabledEvents, cooldownHours, emailCleared); err != nil {
s.logger.Printf("[WARN] [web] Failed to sync preferences to hub: %v", err)
data["NotificationSuccess"] = s.msg(r, "settings.notify_saved_sync_failed", err)
} else {