namespace Eis.Infrastructure.Candidate; public sealed record CandidateMigrationOptions(bool NativeEnabled) { public static CandidateMigrationOptions FromEnvironment( bool configuredNativeEnabled, bool authenticationNativeEnabled, bool sharesLegacySessions) { var enabled = ParseBoolean( Environment.GetEnvironmentVariable("CANDIDATE_NATIVE_ENABLED"), configuredNativeEnabled); if (enabled && !authenticationNativeEnabled) { throw new InvalidOperationException( "启用原生考生接口前必须同时设置 AUTH_NATIVE_ENABLED=true,以确保 ASP.NET Core 能识别登录会话"); } var allowMemoryForIsolatedTesting = ParseBoolean( Environment.GetEnvironmentVariable("CANDIDATE_NATIVE_ALLOW_MEMORY"), fallback: false); if (enabled && !sharesLegacySessions && !allowMemoryForIsolatedTesting) { throw new InvalidOperationException( "应用仍有受保护接口需要转发给 Node;启用原生考生接口必须配置共享 Redis 会话"); } return new CandidateMigrationOptions(enabled); } private static bool ParseBoolean(string? value, bool fallback) => value?.Trim().ToLowerInvariant() switch { "1" or "true" or "yes" or "on" => true, "0" or "false" or "no" or "off" => false, _ => fallback }; }