import Foundation /// One evaluated flag, as returned inside `EvaluateResponse.result.flags[key]`. public struct FeatureControlFlag: Decodable, Sendable, Equatable { public let enabled: Bool public let variant: String? public let payload: FeatureControlJSON? public let reason: String? public init(enabled: Bool, variant: String?, payload: FeatureControlJSON?, reason: String?) { self.enabled = enabled self.variant = variant self.payload = payload self.reason = reason } } /// `EvaluateResponse.result` — the batch evaluation result for a set of keys. public struct FeatureControlSnapshot: Sendable, Equatable { public let evaluatedAt: Date public let configVersion: Int public let flags: [String: FeatureControlFlag] public init(evaluatedAt: Date, configVersion: Int, flags: [String: FeatureControlFlag]) { self.evaluatedAt = evaluatedAt self.configVersion = configVersion self.flags = flags } } extension FeatureControlSnapshot: Decodable { private enum CodingKeys: String, CodingKey { case evaluatedAt, configVersion, flags } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let rawDate = try container.decode(String.self, forKey: .evaluatedAt) guard let date = FeatureControlDateParsing.parse(rawDate) else { throw DecodingError.dataCorruptedError(forKey: .evaluatedAt, in: container, debugDescription: "Unrecognized date format: \(rawDate)") } self.evaluatedAt = date self.configVersion = try container.decode(Int.self, forKey: .configVersion) self.flags = try container.decode([String: FeatureControlFlag].self, forKey: .flags) } } /// Wire envelope for `POST /api/feature-control/evaluate` — `{error, code, result}`. struct FeatureControlEvaluateEnvelope: Decodable, Sendable { let error: Bool let code: String? let result: FeatureControlSnapshot } /// Request body for `POST /api/feature-control/evaluate`. struct FeatureControlEvaluateRequestBody: Encodable, Sendable { let environment: String let keys: [String] let context: FeatureControlContext }