Новая настройка 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 недопустим: он может кратковременно отдать значение предыдущего
пользователя после смены аккаунта.
Получи законченный результат
- Добавь один типизированный
PreferenceKey<T> с поддерживаемым Preferences DataStore типом.
Строковое имя ключа является persisted schema: для существующего значения сохраняй его буквально,
не переименовывай ради нового Kotlin-имени без явной миграции.
- Используй существующие generic
getValue, getValueFlow, setValue и removeValue, если они уже
покрывают операцию. Расширяй SettingsDataStore только когда требуется новая атомарная операция,
а не ради feature-specific метода.
- Размести чтение, запись и бизнес-решения в конкретных
UseCase / FlowUseCase из
shared/domain/usecase; внедри SettingsDataStore напрямую. UI и ViewModel не должны знать
DataStore key или обращаться к DataStore напрямую.
- Для read-modify-write нескольких значений проверь, требуется ли одна атомарная
edit-транзакция.
Не собирай несколько независимых setValue в use case, если наблюдатель не должен видеть
промежуточное состояние.
- Подключи удаление к владельцу 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-имя не изменилось.
1---2name: create-datastore-preference3description: Use when пользователь просит добавить или изменить типизированную настройку, флаг, идентификатор или timestamp в Preferences DataStore, предоставить для него read/write/Flow use case либо определить очистку при logout, смене пользователя или reset. Не используй для коллекций, связанных сущностей, очередей операций и данных, которым нужны запросы или транзакции Room; для них нужен Room-backed workflow. Не используй для полного экрана, который лишь потребляет уже существующую настройку.4---56# Новая настройка DataStore78Добавляет минимальный законченный поток для небольшого сохраняемого значения: типизированный ключ,9доступ через существующий DataStore-класс, domain use case и явно выбранный жизненный цикл очистки.10Сохраняй принятую в целевом проекте структуру `PreferenceKey`, `SettingsDataStore` и DI; не создавай11вторую обёртку или новый DataStore-файл для одной настройки.1213## Определи контракт1415До правок зафиксируй:1617- Kotlin-тип и допустимое отсутствие значения;18- семантику отсутствия: `null`, domain default или «ещё не задавалось»;19- нужен ли разовый read, наблюдаемый `Flow`, write, remove или несколько этих операций;20- срок жизни: установка приложения, устройство, авторизованная сессия, конкретный пользователь или21 временное решение фичи;22- при каких событиях значение очищается: logout, смена аккаунта, сброс настроек или никогда.2324Не подменяй отсутствующее значение дефолтом в низкоуровневом DataStore-классе, если `null` несёт25domain-смысл. Выбирай default в конкретном use case, которому известна бизнес-семантика.2627Для account-scoped значения выбери один контракт явно:2829- session-only: храни owner id и value атомарно, считай несовпадение owner отсутствующим значением и30 очищай пару при account switch;31- remembered per-account: используй безопасно namespaced key только для малого ограниченного набора32 аккаунтов; для неограниченного множества и запросов по владельцу используй Room.3334Один общий value key без owner недопустим: он может кратковременно отдать значение предыдущего35пользователя после смены аккаунта.3637## Получи законченный результат38391. Добавь один типизированный `PreferenceKey<T>` с поддерживаемым Preferences DataStore типом.40 Строковое имя ключа является persisted schema: для существующего значения сохраняй его буквально,41 не переименовывай ради нового Kotlin-имени без явной миграции.422. Используй существующие generic `getValue`, `getValueFlow`, `setValue` и `removeValue`, если они уже43 покрывают операцию. Расширяй `SettingsDataStore` только когда требуется новая атомарная операция,44 а не ради feature-specific метода.453. Размести чтение, запись и бизнес-решения в конкретных `UseCase` / `FlowUseCase` из46 `shared/domain/usecase`; внедри `SettingsDataStore` напрямую. UI и ViewModel не должны знать47 DataStore key или обращаться к DataStore напрямую.484. Для read-modify-write нескольких значений проверь, требуется ли одна атомарная `edit`-транзакция.49 Не собирай несколько независимых `setValue` в use case, если наблюдатель не должен видеть50 промежуточное состояние.515. Подключи удаление к владельцу lifecycle-события. На logout очищай session-only значения, но не52 удаляй remembered per-account и device-scoped настройки. При смене пользователя сначала смени53 owner scope, затем разрешай чтение account-scoped значения.5455## Границы реализации5657- Используй разовый suspend read для решения, принимаемого один раз, и `FlowUseCase` для состояния,58 которое должно обновлять потребителя после записи.59- Не вводи blocking read в новую логику. Сохраняй существующий blocking API только там, где60 синхронную инициализацию уже требует инфраструктура приложения.61- Не сериализуй коллекцию или сложный изменяемый объект в строку только для обхода Room. Допускай62 кодированное значение лишь для небольшого стабильного типа и только если такой формат уже принят63 проектом.64- Не создавай Repository или Interactor и не переносись на Proto DataStore без отдельного запроса.65- Если несколько ключей разных типов очищаются вместе, операция очистки должна поддерживать их без66 небезопасного общего generic-типа.6768## Проверка результата6970Проверь cold start без значения, чтение после записи, обновление Flow, удаление на каждом выбранном71lifecycle-событии и сохранение ключей другого срока жизни. Для существующего ключа отдельно проверь,72что строковое persisted-имя не изменилось.