package appconfig import ( "errors" "strings" "hyapp-admin-server/internal/appctx" "hyapp-admin-server/internal/model" "gorm.io/gorm" ) const ( roomDiscoveryGroup = "room-discovery" roomDiscoveryScopeKey = "scope" roomDiscoveryScopeViewerRegion = "viewer_region" roomDiscoveryScopeAllActiveRegions = "all_active_regions" roomDiscoveryDescription = "房间发现范围:viewer_region 或 all_active_regions" ) type RoomDiscoveryConfig struct { AppCode string `json:"appCode"` Scope string `json:"scope"` UpdatedAtMS int64 `json:"updatedAtMs"` } func (s *AppConfigService) GetRoomDiscoveryConfig(appCode string) (RoomDiscoveryConfig, error) { appCode = appctx.Normalize(appCode) item, err := s.store.GetOwnedAppConfig(appCode, roomDiscoveryGroup, roomDiscoveryScopeKey) if errors.Is(err, gorm.ErrRecordNotFound) { // 未配置时只允许查看者所属区域;这是跨区域数据暴露的 fail-closed 边界,后台保存后才扩大范围。 return RoomDiscoveryConfig{AppCode: appCode, Scope: roomDiscoveryScopeViewerRegion}, nil } if err != nil { return RoomDiscoveryConfig{}, err } return roomDiscoveryConfigFromModel(item), nil } func (s *AppConfigService) UpdateRoomDiscoveryConfig(appCode string, request roomDiscoveryConfigRequest) (RoomDiscoveryConfig, error) { item, err := roomDiscoveryConfigModel(appCode, request) if err != nil { return RoomDiscoveryConfig{}, err } // App 作用域只来自鉴权上下文;请求体不能指定 app_code,也不能覆盖其他租户的同名配置。 if err := s.store.UpsertScopedAppConfigs(item.AppCode, []model.AppConfig{item}); err != nil { return RoomDiscoveryConfig{}, err } stored, err := s.store.GetOwnedAppConfig(item.AppCode, roomDiscoveryGroup, roomDiscoveryScopeKey) if err != nil { return RoomDiscoveryConfig{}, err } return roomDiscoveryConfigFromModel(stored), nil } func roomDiscoveryConfigModel(appCode string, request roomDiscoveryConfigRequest) (model.AppConfig, error) { scope := strings.ToLower(strings.TrimSpace(request.Scope)) if scope != roomDiscoveryScopeViewerRegion && scope != roomDiscoveryScopeAllActiveRegions { return model.AppConfig{}, errors.New("房间发现范围不正确") } return model.AppConfig{ AppCode: appctx.Normalize(appCode), Group: roomDiscoveryGroup, Key: roomDiscoveryScopeKey, Value: scope, Description: roomDiscoveryDescription, }, nil } func roomDiscoveryConfigFromModel(item model.AppConfig) RoomDiscoveryConfig { scope := strings.ToLower(strings.TrimSpace(item.Value)) if scope != roomDiscoveryScopeViewerRegion && scope != roomDiscoveryScopeAllActiveRegions { // 旧 SQL 或人工写入的非法值不能突破 API 枚举契约;与 gateway 保持一致,统一降级到查看者区域。 scope = roomDiscoveryScopeViewerRegion } return RoomDiscoveryConfig{ AppCode: appctx.Normalize(item.AppCode), Scope: scope, UpdatedAtMS: item.UpdatedAtMS, } }