feat(app): integrate Atomenta Feature Control bootstrap, cache and resume refresh

This commit is contained in:
Daniel Arantes Loverde
2026-04-16 14:48:39 -03:00
parent f8d2fb8eb7
commit 7f7d414e6c
6 changed files with 433 additions and 1 deletions

View File

@@ -6,10 +6,64 @@ struct AppState {
var cart = CartState()
var address = AddressState()
var favorites = FavoritesState()
var featureFlags = FeatureFlagsState()
var homeFilters = HomeFiltersState()
var activeModal: AppModal? = nil
}
enum FeatureFlagValue: Codable, Equatable {
case boolean(Bool)
case text(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let boolValue = try? container.decode(Bool.self) {
self = .boolean(boolValue)
return
}
if let stringValue = try? container.decode(String.self) {
self = .text(stringValue)
return
}
if let intValue = try? container.decode(Int.self) {
self = .text(String(intValue))
return
}
if let doubleValue = try? container.decode(Double.self) {
self = .text(String(doubleValue))
return
}
self = .text("off")
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .boolean(let value):
try container.encode(value)
case .text(let value):
try container.encode(value)
}
}
var boolValue: Bool {
switch self {
case .boolean(let value):
return value
case .text(let value):
return value.lowercased() == "on" || value.lowercased() == "true"
}
}
}
struct FeatureFlagsState: Codable, Equatable {
var configVersion: Int = 0
var evaluatedAt: String? = nil
var source: String = "default"
var values: [String: FeatureFlagValue] = [:]
var raw: [String: FeatureControlRawFlag] = [:]
}
enum AppModal: String, Identifiable {
case addressPicker
case filters