diff --git a/API_Mobile_App.md b/API_Mobile_App.md index f721402..83980fc 100644 --- a/API_Mobile_App.md +++ b/API_Mobile_App.md @@ -985,11 +985,10 @@ Authorization: Bearer ← opcional, mas recomendado { "environment": "production", "keys": [ - "fc.ios", - "fc.android", - "fc.promo", - "fc.promo-codes", - "fc.city-aguai" + "at.ios.only", + "at.android.only", + "at.promo", + "at.city.aguai" ], "context": { "subjectType": "customer", @@ -1022,20 +1021,31 @@ Authorization: Bearer ← opcional, mas recomendado "configVersion": 7, "evaluatedAt": "2026-06-05T12:00:00.000Z", "flags": { - "ios": true, - "android": true, - "promo": true, - "promoCodes": false, - "cityAguai": true + "atiosonly": true, + "atandroidonly": false, + "atpromo": true, + "atcityaguai": true }, "raw": { - "fc.ios": { + "at.ios.only": { "enabled": true, "variant": "on", "payload": null, "reason": "rollout" }, - "fc.promo-codes": { + "at.promo": { + "enabled": true, + "variant": "on", + "payload": null, + "reason": "rollout" + }, + "at.city.aguai": { + "enabled": true, + "variant": "on", + "payload": null, + "reason": "segment" + }, + "at.android.only": { "enabled": false, "variant": "off", "payload": null, @@ -1062,27 +1072,33 @@ Authorization: Bearer ← opcional, mas recomendado } ``` -#### Como usar `flags` no app +#### Como usar `raw` no app (Swift) -Os flags são retornados em `flags` com chaves **camelCase** derivadas das chaves originais (prefixo `fc.` removido, hífen/underscore viram camelCase): +O app usa o campo **`raw`**, indexado pela chave original completa. O campo `flags` contém uma versão simplificada (pontos removidos), mas o app Swift usa `raw` para manter compatibilidade direta com os nomes de flag. -| Chave original | Chave em `flags` | -|---|---| -| `fc.ios` | `flags.ios` | -| `fc.android` | `flags.android` | -| `fc.promo` | `flags.promo` | -| `fc.promo-codes` | `flags.promoCodes` | -| `fc.city-aguai` | `flags.cityAguai` | +| Chave original | Acesso via `raw` | `flags` simplificado | +|---|---|---| +| `at.ios.only` | `raw["at.ios.only"]` | `flags["atiosonly"]` | +| `at.android.only` | `raw["at.android.only"]` | `flags["atandroidonly"]` | +| `at.promo` | `raw["at.promo"]` | `flags["atpromo"]` | +| `at.city.aguai` | `raw["at.city.aguai"]` | `flags["atcityaguai"]` | -**Regra de leitura:** -- `true` → flag habilitado -- `false` ou `"off"` → flag desabilitado -- Qualquer outro string → variante multivariate (ex: `"variant_a"`, `"variant_b"`) +> **Use sempre `raw`** para acessar flags no app — as chaves simplificadas em `flags` são geradas mecanicamente e menos legíveis. -**Exemplo Swift:** +**Regra de leitura em `raw`:** +- `raw["at.promo"].enabled == true` → flag habilitado +- `raw["at.promo"].variant == "on"` → variante ativa +- `raw["at.promo"].payload` → dados extras opcionais (JSON livre) + +**Exemplo Swift (padrão atual do app):** ```swift -if flags["ios"] as? Bool == true { - // mostrar funcionalidade exclusiva iOS +// FeatureFlagsState.isEnabled() já lê raw automaticamente +if appState.featureFlags.isEnabled("at.promo") { + // mostrar módulo de promoções +} + +if appState.featureFlags.isEnabled("at.ios.only") { + // funcionalidade exclusiva iOS } ``` @@ -1112,13 +1128,13 @@ Authorization: Bearer { "events": [ { - "featureKey": "fc.promo", + "featureKey": "at.promo", "variant": "on", "subjectType": "customer", "storeId": "store_1777215327582_akum6" }, { - "featureKey": "fc.ios", + "featureKey": "at.ios.only", "variant": "on", "subjectType": "customer" } @@ -1148,15 +1164,16 @@ Máximo de **100 eventos por request**. ### 3. Flags disponíveis (referência) +Padrão de nomenclatura: `at..` (pontos como separador, sem hífens). + | Flag | Descrição | Default | |---|---|---| -| `fc.ios` | Funcionalidades exclusivas iOS habilitadas | `true` | -| `fc.android` | Funcionalidades exclusivas Android habilitadas | `true` | -| `fc.promo` | Módulo de promoções ativo | `true` | -| `fc.promo-codes` | Cupons de desconto habilitados | `true` | -| `fc.city-aguai` | Expansão para cidade de Aguaí/SP | `true` | +| `at.ios.only` | Funcionalidades exclusivas iOS | `true` | +| `at.android.only` | Funcionalidades exclusivas Android | `true` | +| `at.promo` | Módulo de promoções ativo | `true` | +| `at.city.aguai` | Expansão para cidade de Aguaí/SP | `true` | -> Novos flags são criados pelo time Pedi Foods no painel `/feature-control`. Consulte o time antes de codificar um flag inexistente. +> Novos flags são criados pelo time Pedi Foods no painel `/feature-control`. Consulte o time antes de codificar um flag inexistente. A lista completa de flags ativos está disponível no painel admin → Feature Control. --- diff --git a/feature-control-bff/README.md b/feature-control-bff/README.md index db11f92..7b57000 100644 --- a/feature-control-bff/README.md +++ b/feature-control-bff/README.md @@ -27,11 +27,10 @@ Exemplo de `FEATURE_CONTROL_DEFAULTS_JSON`: ```json { - "fc.promo": { "enabled": true, "variant": "on" }, - "fc.promo-codes": { "enabled": true, "variant": "on" }, - "fc.android": { "enabled": true, "variant": "on" }, - "fc.city-aguai": { "enabled": true, "variant": "on" }, - "fc.ios": { "enabled": true, "variant": "on" } + "at.ios.only": { "enabled": true, "variant": "on" }, + "at.android.only": { "enabled": true, "variant": "on" }, + "at.promo": { "enabled": true, "variant": "on" }, + "at.city.aguai": { "enabled": true, "variant": "on" } } ``` @@ -40,7 +39,7 @@ Exemplo de `FEATURE_CONTROL_DEFAULTS_JSON`: ```json { "environment": "production", - "keys": ["fc.promo", "fc.promo-codes", "fc.android", "fc.city-aguai", "fc.ios"], + "keys": ["at.ios.only", "at.android.only", "at.promo", "at.city.aguai"], "context": { "subjectType": "customer", "subjectId": "cust_123", @@ -48,8 +47,7 @@ Exemplo de `FEATURE_CONTROL_DEFAULTS_JSON`: "platform": "ios", "appVersion": "2.3.1", "attributes": { - "city": "Belo Horizonte", - "tier": "gold" + "city": "Aguaí" } } } @@ -66,14 +64,19 @@ Se o app enviar `Authorization: Bearer `, o BFF tenta extrair `subjectId` d "configVersion": 7, "evaluatedAt": "2026-04-16T12:00:00.000Z", "flags": { - "promo": true, - "promoCodes": true, - "android": true, - "cityAguai": true, - "ios": true + "atiosonly": true, + "atandroidonly": false, + "atpromo": true, + "atcityaguai": true }, "raw": { - "fc.promo": { + "at.ios.only": { + "enabled": true, + "variant": "on", + "payload": null, + "reason": "rollout" + }, + "at.promo": { "enabled": true, "variant": "on", "payload": null, @@ -83,6 +86,9 @@ Se o app enviar `Authorization: Bearer `, o BFF tenta extrair `subjectId` d } ``` +> O app Swift usa o campo **`raw`** indexado pela chave original (ex: `raw["at.promo"]`). O campo `flags` é uma versão simplificada gerada mecanicamente (pontos removidos). +``` + Quando o upstream falha (ex.: `429`, `500`, timeout), o BFF devolve `fallback` com defaults estáticos. ## Execução local