fix(settings): inject channel_monitor & available_channels into SSR payload

Root cause: GetPublicSettingsForInjection used an inline struct that silently
drifted from dto.PublicSettings and omitted channel_monitor_enabled /
available_channels_enabled. On refresh window.__APP_CONFIG__ lacked these
keys, so cachedPublicSettings.available_channels_enabled resolved to
undefined and the opt-in sidebar entry (=== true) disappeared.

Backend: extract PublicSettingsInjectionPayload as a named type with all
feature-flag fields wired, and add a reflect-based drift test in the dto
package so forgetting a future flag fails CI instead of the browser.

Frontend: introduce utils/featureFlags.ts as the single registry for
public-settings-driven toggles, with explicit opt-in / opt-out modes that
encode the pre-load fallback. AppSidebar switches to makeSidebarFlag() so
adding a new switch only touches the registry.
This commit is contained in:
erio
2026-04-21 21:08:10 +08:00
parent 3cdd5754df
commit 84b03efa0b
4 changed files with 219 additions and 4 deletions

View File

@@ -675,6 +675,8 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
AvailableChannelsEnabled bool `json:"available_channels_enabled"`
}{
RegistrationEnabled: settings.RegistrationEnabled,
EmailVerifyEnabled: settings.EmailVerifyEnabled,
@@ -713,6 +715,8 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
AccountQuotaNotifyEnabled: settings.AccountQuotaNotifyEnabled,
BalanceLowNotifyThreshold: settings.BalanceLowNotifyThreshold,
BalanceLowNotifyRechargeURL: settings.BalanceLowNotifyRechargeURL,
ChannelMonitorEnabled: settings.ChannelMonitorEnabled,
AvailableChannelsEnabled: settings.AvailableChannelsEnabled,
}, nil
}