Skip to content

Commit 5c07e81

Browse files
committed
fix: preserve notification surface disables
1 parent f0c57ac commit 5c07e81

4 files changed

Lines changed: 36 additions & 27 deletions

File tree

backend/internal/daemon/daemon.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ func Run() error {
6161
return err
6262
}
6363

64+
notifier := startNotifier(ctx, cfg, store, log)
65+
6466
// Terminal streaming: the tmux runtime supplies the PTY-attach command and
6567
// liveness; the CDC broadcaster feeds the session-state channel. The manager
6668
// is handed to httpd, which mounts it at /mux. Raw PTY bytes never flow
@@ -71,6 +73,11 @@ func Run() error {
7173

7274
srv, err := httpd.New(cfg, log, termMgr)
7375
if err != nil {
76+
stop()
77+
notifier.Stop()
78+
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
79+
log.Error("cdc pipeline shutdown", "err", cdcErr)
80+
}
7481
return err
7582
}
7683

@@ -79,6 +86,11 @@ func Run() error {
7986
// trigger -> change_log -> poller -> broadcaster.
8087
lcStack, err := startLifecycle(ctx, store, log)
8188
if err != nil {
89+
stop()
90+
notifier.Stop()
91+
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
92+
log.Error("cdc pipeline shutdown", "err", cdcErr)
93+
}
8294
return err
8395
}
8496

@@ -98,6 +110,7 @@ func Run() error {
98110
// the LIFO trap (see comment after srv.Run), hence explicit.
99111
stop()
100112
lcStack.Stop()
113+
notifier.Stop()
101114
if cdcErr := cdcPipe.Stop(); cdcErr != nil {
102115
log.Error("cdc pipeline shutdown", "err", cdcErr)
103116
}
@@ -113,6 +126,7 @@ func Run() error {
113126
// runs before the cancel — which would hang any non-signal exit path.
114127
stop()
115128
lcStack.Stop()
129+
notifier.Stop()
116130
if err := cdcPipe.Stop(); err != nil {
117131
log.Error("cdc pipeline shutdown", "err", err)
118132
}

backend/notifier_wiring.go renamed to backend/internal/daemon/notifier_wiring.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package daemon
22

33
import (
44
"context"

backend/internal/notification/settings.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,9 @@ func NormalizeSettings(in config.NotificationConfig) config.NotificationConfig {
3333
def := config.DefaultNotificationConfig()
3434
out := in
3535

36-
if isZeroDashboardConfig(in.Dashboard) {
37-
out.Dashboard.Enabled = def.Dashboard.Enabled
38-
}
3936
if out.Dashboard.Limit == 0 {
4037
out.Dashboard.Limit = def.Dashboard.Limit
4138
}
42-
if isZeroDesktopConfig(in.Desktop) {
43-
out.Desktop.Enabled = def.Desktop.Enabled
44-
}
4539
if out.Desktop.Priorities == nil {
4640
out.Desktop.Priorities = append([]ports.Priority(nil), def.Desktop.Priorities...)
4741
}
@@ -93,23 +87,3 @@ func cloneRoutes(in map[ports.Priority][]string) map[ports.Priority][]string {
9387
}
9488
return out
9589
}
96-
97-
func isZeroNotificationConfig(c config.NotificationConfig) bool {
98-
return !c.Enabled &&
99-
isZeroDashboardConfig(c.Dashboard) &&
100-
isZeroDesktopConfig(c.Desktop) &&
101-
c.Routing.Priorities == nil &&
102-
c.Retry.MaxAttempts == 0 &&
103-
c.Retry.BaseDelay == 0 &&
104-
c.Retry.MaxDelay == 0 &&
105-
c.Retry.LeaseTTL == 0 &&
106-
c.Retry.BatchSize == 0
107-
}
108-
109-
func isZeroDashboardConfig(c config.DashboardNotificationConfig) bool {
110-
return !c.Enabled && c.Limit == 0
111-
}
112-
113-
func isZeroDesktopConfig(c config.DesktopNotificationConfig) bool {
114-
return !c.Enabled && len(c.Priorities) == 0 && len(c.SoundPriorities) == 0
115-
}

backend/internal/notification/settings_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ func TestSettingsFromConfigPreservesExplicitGlobalDisable(t *testing.T) {
2828
}
2929
}
3030

31+
func TestNormalizeSettingsPreservesExplicitSurfaceDisables(t *testing.T) {
32+
got := StaticSettings(config.NotificationConfig{
33+
Enabled: true,
34+
Dashboard: config.DashboardNotificationConfig{Enabled: false},
35+
Desktop: config.DesktopNotificationConfig{Enabled: false},
36+
}).Settings(context.Background())
37+
38+
if !got.Enabled {
39+
t.Fatalf("global notifications should remain enabled: %+v", got)
40+
}
41+
if got.Dashboard.Enabled {
42+
t.Fatalf("explicit dashboard disable should stay disabled: %+v", got.Dashboard)
43+
}
44+
if got.Desktop.Enabled {
45+
t.Fatalf("explicit desktop disable should stay disabled: %+v", got.Desktop)
46+
}
47+
if got.Dashboard.Limit != 50 || len(got.Desktop.Priorities) == 0 || got.Retry.MaxAttempts != 5 {
48+
t.Fatalf("disabled surfaces should still receive non-bool defaults: %+v", got)
49+
}
50+
}
51+
3152
func TestNormalizeSettingsPreservesExplicitEmptyRoute(t *testing.T) {
3253
cfg := config.DefaultNotificationConfig()
3354
cfg.Routing.Priorities[ports.PriorityUrgent] = []string{}

0 commit comments

Comments
 (0)