Settings Patterns

mandatory

Convenção mestre de tela Settings em apps Koder: hierarquia canônica de grupos, ordem fixa, registro de cross-cutting settings (qual grupo, qual posição, qual controle, default state, persistence key), estrutura do tile (label/control/helper/icon) e widget SDK obrigatório (`KoderSettingsTile` em Flutter, `<koder-settings-tile>` em Web). Toda spec de feature cross-cutting que precisa de toggle em Settings registra-se aqui em vez de inventar tile próprio.

Spec — Settings Patterns

Convenção mestre da tela Settings em todo app Koder. Resolve a proliferação de tiles adhoc (cada feature crosscutting inventando seu próprio tile com labelposiçãodefault state diferentes).

Goals

  1. *onsistência visual*entre apps Koder e entre features dentro do

    mesmo app — todo tile parece tile.

  2. *iscoverability*— usuário sabe onde encontrar cada setting porque

    o grupo é canônico (Privacy sempre tem a mesma posição em qualquer app).

  3. *euso de SDK*— KoderSettingsTile / <koder-settings-tile>

    encapsulam controlepersistencei18n sem boilerplate por app.

  4. *uditabilidade*— koder.toml [settings] declara features

    esperadas; audit script verifica que app cumpre.

Hierarquia canônica de grupos

A tela Settings tem grupos *ixos em ordem* *stáveis nomenclatura* Apps com features que não se encaixam usam *Advanced`*ou criam sub-grupos dentro de grupo existente.

# Grupo (en-US) Grupo (pt-BR) Conteúdo típico
1 *eneral* Geral Idioma, fuso, locale, perfil ativo
2 *ccount* Conta Signin, badge, signout, multiaccount switch
3 *ppearance* Aparência Tema (light/dark), estilo de UI, cor accent, densidade
4 *otifications* Notificações Push, badge, som, "do not disturb"
5 *rivacy* Privacidade Telemetria, tracking, dados compartilhados
6 *pdates* Atualizações Auto-update toggle, canal (stable/beta), botão check now
7 *oice* Voz Wake word, talk mode, mic permissions
8 *torage* Armazenamento Cache, downloads, dados offline, limite de uso
9 *eporting* Relatórios Autoreport toggle, "Reportar problema" button, optin dados
10 *etwork* Rede Proxy, VPN, sync settings
11 *dvanced* Avançado Dev options, experimental flags, debug
12 *bout* Sobre Version, license, credits, links

*egras de ordem:*

  • Apps *mitem*grupos que não aplicam (ex.: app sem mic não tem Voice)
  • Apps *ão reordenam*os grupos restantes
  • Apps *ão criam grupos novos*sem extender esta spec primeiro

Estrutura do tile

Todo tile em Settings tem * campos*definidos:

Campo Required Tipo Exemplo
key sim string snake_case theme_mode
label sim i18n string "Theme" / "Tema"
control sim enum `toggle dropdown slider button text radio_group`
default_state sim depende false / "system" / 0.5
persistence_key sim string koder.theme
helper_text não i18n string "Choose how the app looks"
leading_icon não icon ref Icons.palette

Widget de SDK obrigatório

*lutter (engines/sdk/koder_kit v0.6.0+):*

KoderSettingsPage(
  groups: [
    KoderSettingsGroup(
      id: 'appearance',
      tiles: [
        KoderSettingsTile(
          key: 'theme_mode',
          label: l10n.settings.theme,
          control: KoderSettingsControl.toggle(...),
          defaultState: false,
          persistenceKey: 'koder.theme',
        ),
        // ...
      ],
    ),
  ],
)

*eb (engines/sdk/koder_web_kit v0.3.0+):*

<koder-settings-page>
  <koder-settings-group id="appearance">
    <koder-settings-tile
      key="theme_mode"
      label="..."
      control="toggle"
      default-state="false"
      persistence-key="koder.theme">
    </koder-settings-tile>
  </koder-settings-group>
</koder-settings-page>

*pp proibido de:*

  • Implementar tile via ListTile puro (Flutter) ou <div> ad-hoc (Web)

    quando o conteúdo é setting cross-cutting

  • Salvar preferência fora do persistence_key declarado pela spec da

    feature (rompe sync cross-device futuro)

  • Esconder toggle de feature obrigatória (ex.: omitir auto-update toggle)

Manifesto opcional em koder.toml

App pode declarar settings esperados em koder.toml:

[settings]
groups = ["general", "appearance", "privacy", "updates", "about"]

[[settings.tiles]]
group = "appearance"
key = "theme_mode"
spec = "themes/light-dark"   # cross-ref pra spec que define o tile

[[settings.tiles]]
group = "appearance"
key = "ui_style"
spec = "themes/ui-style"

[[settings.tiles]]
group = "updates"
key = "auto_update"
spec = "koder-app/behaviors#4"

/k-test-gen-ui consome esse manifesto pra gerar UI tests automáticos que verificam (1) cada tile renderizou, (2) controle interage, (3) estado persiste.

Cross-cutting features registradas (atual)

Specs de feature que *andam um tile em Settings* Cada uma é responsável por declarar group, key, default_state próprios:

Spec Group Key Control Default Required
themes/light-dark.kmd Appearance theme_mode toggle (sun/moon) follow OS sim
themes/ui-style.kmd Appearance ui_style dropdown (19 opções) material3 sim
koder-app/behaviors.kmd §1 Account sign_in KoderSignInButton sim (apps com auth)
koder-app/behaviors.kmd §4 Updates auto_update toggle true (ON) sim (apps com release)
errors/reporting.kmd Reporting auto_report toggle false (OFF) sim
errors/reporting.kmd Reporting report_problem button sim
voice/wake-word.kmd Voice voice.enabled toggle false sim (apps com mic)
voice/wake-word.kmd Voice voice.talkMode toggle false sim (apps com mic)
voice/wake-word.kmd Voice voice.hotWord text "kode" sim (apps com mic)
voice/wake-word.kmd Voice voice.backend dropdown "openWakeWord" sim (apps com mic)
voice/wake-word.kmd Voice voice.bargeIn toggle true sim (apps com mic)
voice/wake-word.kmd Voice voice.debugRecord toggle false dev builds only

Cada spec referenciada *eve*atualizar esta tabela ao introduzir novo tile (auditado pelo audit script).

Audit

/k-audit settings <module> (via koderspecaudit) verifica:

  1. *ettings page existe*se app tem capability humana (mobiledesktopweb/tv)
  2. *idget canônico em uso*— grep por KoderSettingsPage/<koder-settings-page>
  3. *rupos na ordem canônica*— extrair ordem de declaração e comparar
  4. *iles obrigatórios presentes*— pra cada spec aplicável da tabela

    acima, verificar que o tile existe no grupo correto

  5. *ersistence keys padronizadas*— prefs.getBool('koder.<feature>')

    ou equivalente

Falhas geram drift entries no JSON envelope do audit script.

Anti-patterns

*on't:*

  1. *nventar nome de grupo novo*sem estender esta spec
  2. *eordenar grupos canônicos*
  3. *mplementar tile com ListTile/div ad-hoc*quando feature é

    cross-cutting

  4. *isturar settings de feature local com cross-cutting*sem grupo

    "Advanced" ou sub-grupo claro

  5. *ardcodar default state em código*— sempre vem do spec da feature

*o:*

  1. *eclarar settings em koder.toml [settings]*se app tem ≥3 tiles
  2. *eutilizar persistence keys canônicas*— sync cross-device futuro

    depende disso

  3. *stender esta spec*quando aparece pattern novo (PR + audit)
  4. *est UI gerados via /k-test-gen-ui*lendo o manifesto

Origem

Spec criada durante o ticket KSTACK-101 ETAPA 2.1. Resolve a lacuna identificada na conversa de 20260501: cada crosscutting reinventava seu tile (KSTACK89 voice, errorsreporting, themeslightdark, koderapp/behaviors §4). Aplica princípios Meta First (#1) e SDK-first (#6) de policies/stack-principles.kmd.

Source: ../home/koder/dev/koder/meta/docs/stack/specs/settings/patterns.kmd