docs/references/data/preference-schema-guide.md
src/shared/data/preference/preferenceSchemas.ts is generated. Never edit its
PreferenceSchemas interface or DefaultPreferences object by hand. Change the
generator inputs, run the generator, and commit the generated result.
| Kind of key | Source of truth |
|---|---|
| New v2 setting with no v1 source | v2-refactor-temp/tools/data-classify/data/target-key-definitions.json |
| Simple v1-to-v2 mapping | v2-refactor-temp/tools/data-classify/data/classification.json |
| Complex migration output | target-key-definitions.json, plus the transformer and complex mapping owned by the v2 migrator |
| Reusable TypeScript type | src/shared/data/preference/preferenceTypes.ts |
target-key-definitions.json entries with status: "classified" are emitted.
Entries with status: "pending" are not part of the generated Preference schema.
Preference keys use at least two dot-separated lowercase segments. Multi-word segments use underscores:
namespace.category.key_name
The data-schema-key/valid-key lint rule enforces
/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/.
Prefer an existing domain namespace. A new namespace should represent a real cross-application domain, not one call site.
app.spell_check.enabled
chat.message.font_size
feature.quick_assistant.enabled
shortcut.general.show_main_window
DefaultPreferences and the Preference seeder materializes missing rows.preferenceTypes.ts; reference them as PreferenceTypes.X in the generator
input.Example new key:
{
"targetKey": "feature.my_feature.enabled",
"type": "boolean",
"defaultValue": false,
"status": "classified",
"description": "Enable My Feature"
}
For a TypeScript expression rather than a JSON literal, use the generator's
VALUE: form:
{
"targetKey": "feature.my_feature.mode",
"type": "PreferenceTypes.MyFeatureMode",
"defaultValue": "VALUE: PreferenceTypes.MyFeatureMode.Auto",
"status": "classified",
"description": "My Feature mode"
}
Run the supported generator pipeline from its package directory:
cd v2-refactor-temp/tools/data-classify
npm run generate
This regenerates all four coupled outputs:
src/shared/data/preference/preferenceSchemas.tssrc/shared/data/bootConfig/bootConfigSchemas.tssrc/main/data/migration/v2/migrators/mappings/PreferencesMappings.tssrc/main/data/migration/v2/migrators/mappings/BootConfigMappings.tsThen consume the generated key through the normal Preference API:
import { usePreference } from '@data/hooks/usePreference'
const [enabled, setEnabled] = usePreference('feature.my_feature.enabled')
Run pnpm lint after changing a key. It checks generated types, key naming,
formatting, and all Preference call sites.
For a simple migrated value, update the corresponding classified entry in
classification.json with its legacy source and target key. For a value that
combines or transforms multiple legacy inputs:
target-key-definitions.json.src/main/data/migration/v2/migrators/transformers/PreferenceTransformers.ts.src/main/data/migration/v2/migrators/mappings/ComplexPreferenceMappings.ts.npm run generate.Do not add a v1 read fallback or a second runtime source of truth. Legacy data reaches the current Preference table only through the v2 migrator.