# Create Datastore Preference

> Use when пользователь просит добавить или изменить типизированную настройку, флаг, идентификатор или timestamp в Preferences DataStore, предоставить для него read/write/Flow use case либо определить очистку при logout, смене пользователя или reset. Не используй для коллекций, связанных сущностей, очередей операций и данных, которым нужны запросы или транзакции Room; для них нужен Room-backed workflow. Не используй для полного экрана, который лишь потребляет уже существующую настройку.

- Skill: `michaelbel/create-datastore-preference` (Agent Skill)
- Install (CLI): `npx skillmds@latest add michaelbel/create-datastore-preference`
- Raw SKILL.md: https://api.skillmd.com/api/skills/michaelbel/create-datastore-preference/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: michaelbel (https://skillmd.com/u/michaelbel)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/michaelbel/create-datastore-preference

---


# Новая настройка DataStore

Добавляет минимальный законченный поток для небольшого сохраняемого значения: типизированный ключ,
доступ через существующий DataStore-класс, domain use case и явно выбранный жизненный цикл очистки.
Сохраняй принятую в целевом проекте структуру `PreferenceKey`, `SettingsDataStore` и DI; не создавай
вторую обёртку или новый DataStore-файл для одной настройки.

## Определи контракт

До правок зафиксируй:

- Kotlin-тип и допустимое отсутствие значения;
- семантику отсутствия: `null`, domain default или «ещё не задавалось»;
- нужен ли разовый read, наблюдаемый `Flow`, write, remove или несколько этих операций;
- срок жизни: установка приложения, устройство, авторизованная сессия, конкретный пользователь или
  временное решение фичи;
- при каких событиях значение очищается: logout, смена аккаунта, сброс настроек или никогда.

Не подменяй отсутствующее значение дефолтом в низкоуровневом DataStore-классе, если `null` несёт
domain-смысл. Выбирай default в конкретном use case, которому известна бизнес-семантика.

Для account-scoped значения выбери один контракт явно:

- session-only: храни owner id и value атомарно, считай несовпадение owner отсутствующим значением и
  очищай пару при account switch;
- remembered per-account: используй безопасно namespaced key только для малого ограниченного набора
  аккаунтов; для неограниченного множества и запросов по владельцу используй Room.

Один общий value key без owner недопустим: он может кратковременно отдать значение предыдущего
пользователя после смены аккаунта.

## Получи законченный результат

1. Добавь один типизированный `PreferenceKey<T>` с поддерживаемым Preferences DataStore типом.
   Строковое имя ключа является persisted schema: для существующего значения сохраняй его буквально,
   не переименовывай ради нового Kotlin-имени без явной миграции.
2. Используй существующие generic `getValue`, `getValueFlow`, `setValue` и `removeValue`, если они уже
   покрывают операцию. Расширяй `SettingsDataStore` только когда требуется новая атомарная операция,
   а не ради feature-specific метода.
3. Размести чтение, запись и бизнес-решения в конкретных `UseCase` / `FlowUseCase` из
   `shared/domain/usecase`; внедри `SettingsDataStore` напрямую. UI и ViewModel не должны знать
   DataStore key или обращаться к DataStore напрямую.
4. Для read-modify-write нескольких значений проверь, требуется ли одна атомарная `edit`-транзакция.
   Не собирай несколько независимых `setValue` в use case, если наблюдатель не должен видеть
   промежуточное состояние.
5. Подключи удаление к владельцу lifecycle-события. На logout очищай session-only значения, но не
   удаляй remembered per-account и device-scoped настройки. При смене пользователя сначала смени
   owner scope, затем разрешай чтение account-scoped значения.

## Границы реализации

- Используй разовый suspend read для решения, принимаемого один раз, и `FlowUseCase` для состояния,
  которое должно обновлять потребителя после записи.
- Не вводи blocking read в новую логику. Сохраняй существующий blocking API только там, где
  синхронную инициализацию уже требует инфраструктура приложения.
- Не сериализуй коллекцию или сложный изменяемый объект в строку только для обхода Room. Допускай
  кодированное значение лишь для небольшого стабильного типа и только если такой формат уже принят
  проектом.
- Не создавай Repository или Interactor и не переносись на Proto DataStore без отдельного запроса.
- Если несколько ключей разных типов очищаются вместе, операция очистки должна поддерживать их без
  небезопасного общего generic-типа.

## Проверка результата

Проверь cold start без значения, чтение после записи, обновление Flow, удаление на каждом выбранном
lifecycle-событии и сохранение ключей другого срока жизни. Для существующего ключа отдельно проверь,
что строковое persisted-имя не изменилось.

