feat(channels): gate available channels behind feature switch (backend)
Add a DB-backed soft switch "available_channels_enabled" controlling the user-facing /channels/available endpoint and sidebar entry. Default to false (opt-in) — the feature stays invisible until an admin enables it under Admin Settings > Features. - domain_constants: SettingKeyAvailableChannelsEnabled - settings_view: AllSettings/PublicSettings + AvailableChannelsEnabled - setting_service: public+all read/write, seed default "false", GetAvailableChannelsRuntime helper (fail-closed on read error) - admin setting_handler: UpdateSettingsRequest *bool + update branch + audit diff entry - public setting_handler: expose via GET /api/v1/settings - available_channel_handler: featureEnabled() guard — returns empty list after auth when disabled (401 precedes the feature check to preserve existing behavior)
This commit is contained in:
@@ -238,6 +238,8 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
|
||||
|
||||
ChannelMonitorEnabled: settings.ChannelMonitorEnabled,
|
||||
ChannelMonitorDefaultIntervalSeconds: settings.ChannelMonitorDefaultIntervalSeconds,
|
||||
|
||||
AvailableChannelsEnabled: settings.AvailableChannelsEnabled,
|
||||
}
|
||||
response.Success(c, systemSettingsResponseData(payload, authSourceDefaults))
|
||||
}
|
||||
@@ -432,6 +434,9 @@ type UpdateSettingsRequest struct {
|
||||
// Channel Monitor feature switch
|
||||
ChannelMonitorEnabled *bool `json:"channel_monitor_enabled"`
|
||||
ChannelMonitorDefaultIntervalSeconds *int `json:"channel_monitor_default_interval_seconds"`
|
||||
|
||||
// Available Channels feature switch (user-facing)
|
||||
AvailableChannelsEnabled *bool `json:"available_channels_enabled"`
|
||||
}
|
||||
|
||||
// UpdateSettings 更新系统设置
|
||||
@@ -1238,6 +1243,12 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
}
|
||||
return previousSettings.ChannelMonitorDefaultIntervalSeconds
|
||||
}(),
|
||||
AvailableChannelsEnabled: func() bool {
|
||||
if req.AvailableChannelsEnabled != nil {
|
||||
return *req.AvailableChannelsEnabled
|
||||
}
|
||||
return previousSettings.AvailableChannelsEnabled
|
||||
}(),
|
||||
}
|
||||
|
||||
authSourceDefaults := &service.AuthSourceDefaultSettings{
|
||||
@@ -1471,6 +1482,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
||||
|
||||
ChannelMonitorEnabled: updatedSettings.ChannelMonitorEnabled,
|
||||
ChannelMonitorDefaultIntervalSeconds: updatedSettings.ChannelMonitorDefaultIntervalSeconds,
|
||||
|
||||
AvailableChannelsEnabled: updatedSettings.AvailableChannelsEnabled,
|
||||
}
|
||||
response.Success(c, systemSettingsResponseData(payload, updatedAuthSourceDefaults))
|
||||
}
|
||||
@@ -1833,6 +1846,9 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
|
||||
if before.ChannelMonitorDefaultIntervalSeconds != after.ChannelMonitorDefaultIntervalSeconds {
|
||||
changed = append(changed, "channel_monitor_default_interval_seconds")
|
||||
}
|
||||
if before.AvailableChannelsEnabled != after.AvailableChannelsEnabled {
|
||||
changed = append(changed, "available_channels_enabled")
|
||||
}
|
||||
changed = appendAuthSourceDefaultChanges(changed, beforeAuthSourceDefaults, afterAuthSourceDefaults)
|
||||
return changed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user