Skip to content

Руководство по конфигурации Storage (хранилища данных)

📖 Полное руководство по созданию и настройке хранилищ данных для гибкого управления настройками, лимитами, функциями и пользовательскими данными.

📑 Содержание


🎯 Назначение

Storage — это гибкая система хранилищ данных в формате key-value, которая позволяет:

  • Хранить настройки тенанта (лимиты, параметры, конфигурации)
  • Управлять функциями и возможностями тенанта
  • Хранить пользовательские данные и настройки
  • Гибко добавлять новые атрибуты без изменения схемы БД
  • Автоматически синхронизировать данные из конфигурации в БД

Преимущества:

  • ✅ Гибкость — можно добавлять новые атрибуты без миграций БД
  • ✅ Организация — данные группируются по логическим файлам (Tenant Storage) или по пользователям (User Storage)
  • ✅ Простота — простые типы данных (строки, числа, bool, массивы, объекты)
  • ✅ Автоматическое преобразование типов при чтении
  • ✅ Изоляция данных — данные пользователей изолированы по тенантам

🔀 Типы хранилищ

Система поддерживает два типа хранилищ:

Tenant Storage

  • Назначение: Хранение настроек и конфигураций тенанта
  • Структура: Группировка по group_key (settings, limits, features и т.д.)
  • Источник данных: YAML файлы в папке storage/ конфигурации тенанта
  • Синхронизация: Автоматическая синхронизация из конфигурации в БД
  • Ключ: (tenant_id, group_key, key)

User Storage

  • Назначение: Хранение пользовательских данных и настроек
  • Структура: Плоская структура без групп ({key: value})
  • Источник данных: Устанавливается программно через действия сценариев
  • Синхронизация: Не синхронизируется с конфигурацией, управляется только через действия
  • Ключ: (tenant_id, user_id, key)

Различия:

ХарактеристикаTenant StorageUser Storage
ГруппировкаПо group_keyБез групп
Источник данныхYAML файлыДействия сценариев
СинхронизацияАвтоматическая из конфигурацииРучное управление
Область примененияНастройки тенантаДанные пользователей
Структура{group_key: {key: value}}{key: value}

🏢 Tenant Storage

Структура хранилища

Расположение

Tenant Storage находится в папке storage/ внутри конфигурации тенанта:

tenant_101/
├── tg_bot.yaml
├── storage/               # Папка хранилища
│   ├── settings.yaml     # Группа настроек
│   ├── limits.yaml       # Группа лимитов
│   └── features.yaml      # Группа функций
└── scenarios/
    └── ...

Структура файлов

Каждый файл в папке storage/ содержит группы атрибутов. Название файла не влияет на группировку — это просто способ логической организации конфигурации.

Пример:

yaml
# storage/config.yaml - название файла не важно
settings:
  max_users: 100
  max_storage: 500
  default_language: "ru"

limits:
  daily_requests: 1000
  max_file_size: 10485760

Все файлы из папки storage/ объединяются при синхронизации конфигурации.

Синхронизация с базой данных

Механизм синхронизации

При синхронизации конфигурации Tenant Storage система выполняет следующие действия:

  1. Получение групп из БД — система получает список всех существующих групп в базе данных
  2. Определение групп для синхронизации — сравниваются группы из конфигурации с группами в БД
  3. Удаление синхронизируемых групп — удаляются только те группы, которые присутствуют в конфигурации
  4. Загрузка данных из конфига — все группы из конфигурации загружаются в базу данных

Важные особенности

  • Группы из конфигурации — полностью синхронизируются (удаляются старые данные, загружаются новые)
  • Группы, отсутствующие в конфиге — остаются нетронутыми в базе данных (не удаляются автоматически)
  • Новые группы — автоматически создаются при синхронизации
  • Полное соответствие конфигу — синхронизированные группы полностью соответствуют конфигурации

Пример:

Если в БД есть группы: settings, limits, features, old_group

И в конфиге есть только: settings, limits, features

То при синхронизации:

  • settings, limits, features — будут удалены и загружены заново из конфига
  • old_group — останется нетронутой в БД (не будет удалена)

Для удаления группы из БД используйте действие delete_storage в сценарии или удалите все записи группы вручную.

Организация файлов

Принципы организации

  1. Файлы для логической группировки — можно создавать любое количество файлов для удобства организации конфигурации
  2. Объединение файлов — все файлы из папки storage/ объединяются при синхронизации
  3. Группы атрибутов — внутри файла используйте структуру {group_key: {key: value}} для группировки связанных атрибутов
  4. Уникальность ключей — ключи должны быть уникальными в рамках группы (group_key)

Пример структуры

storage/
├── config.yaml          # Произвольное название файла
│   settings:
│     max_users: 100
│     default_language: "ru"
│   limits:
│     daily_requests: 1000
│     max_file_size: 10485760

└── additional.yaml     # Еще один файл для дополнительных настроек
    features:
      enable_premium: true
      enable_api: false

Пример использования

Файл: storage/config.yaml (название файла может быть любым)

yaml
# Основные настройки
settings:
  max_users: 100                          # Целое число
  max_storage: 500                        # Целое число
  default_language: "ru"                  # Строка
  allowed_languages: ["ru", "en", "de"]   # Массив строк
  enable_notifications: true              # Булево значение
  maintenance_mode: false                 # Булево значение

# Лимиты и ограничения
limits:
  daily_requests: 1000                     # Целое число
  max_file_size: 10485760                # Целое число (10 MB в байтах)
  rate_limit_per_minute: 30              # Целое число
  discount_percentage: 10.5               # Дробное число
  price_tiers: [9.99, 19.99, 29.99]      # Массив дробных чисел

# Функции и возможности
features:
  enable_premium: true                    # Булево значение
  enable_api: false                       # Булево значение
  enable_webhooks: false                 # Булево значение
  supported_regions: ["eu", "us", "asia"] # Массив строк

# Тарифы и цены
pricing:
  base_price: 9.99                        # Дробное число
  premium_price: 29.99                    # Дробное число
  trial_days: 14                          # Целое число

👤 User Storage

Назначение

User Storage — это хранилище данных пользователя, которое позволяет:

  • Хранить пользовательские настройки и предпочтения
  • Сохранять состояние пользователя между сессиями
  • Управлять персональными данными пользователя
  • Изолировать данные пользователей по тенантам

Структура

User Storage имеет плоскую структуру без групп:

{key: value}

Пример:

yaml
language: "ru"
theme: "dark"
messages_sent: 150
favorite_colors: ["red", "blue", "green"]
user_preferences:
  language: "ru"
  theme: "dark"
  notifications: true

Особенности

  • Изоляция по тенантам: Данные пользователя привязаны к tenant_id и user_id
  • Плоская структура: Нет группировки по group_key, только key: value
  • Программное управление: Данные устанавливаются и изменяются только через действия сценариев
  • Автоматический контекст: tenant_id и user_id автоматически доступны из контекста события

Пример использования

Установка значений через сценарий:

yaml
set_user_preferences:
  description: "Установить настройки пользователя"
  
  trigger:
    - event_type: "callback"
      callback_data: "set_preferences"
  
  step:
    - action: "set_user_storage"
      params:
        key: "language"
        value: "ru"
    
    - action: "set_user_storage"
      params:
        key: "theme"
        value: "dark"
    
    - action: "set_user_storage"
      params:
        key: "user_preferences"
        value:
          language: "ru"
          theme: "dark"
          notifications: true
    
    - action: "send_message"
      params:
        text: "✅ Настройки сохранены!"

Получение значений:

yaml
show_user_preferences:
  description: "Показать настройки пользователя"
  
  trigger:
    - event_type: "callback"
      callback_data: "show_preferences"
  
  step:
    # Получаем все значения одним запросом
    - action: "get_user_storage"
    
    - action: "send_message"
      params:
        text: |
          👤 <b>Ваши настройки</b>
          
          Язык: <code>{_cache.user_storage_values.language|fallback:не установлен}</code>
          Тема: <code>{_cache.user_storage_values.theme|fallback:не установлена}</code>

Примечание: При запросе конкретного ключа (key указан) возвращается прямое значение, доступное через {_cache.user_storage_values}. При запросе всех значений (без key) возвращается полная структура {key: value}, доступная через {_cache.user_storage_values.key}


🔢 Типы значений

Поддерживаемые типы

В обоих типах Storage можно использовать следующие типы данных:

  • Строки — текстовые значения
  • Целые числа — целые числа
  • Дробные числа — числа с плавающей точкой
  • Булевы значения — true/false
  • Массивы — списки значений (поддерживают простые типы и сложные структуры)
  • JSON объекты (словари) — вложенные структуры данных
  • Вложенные структуры — массивы словарей, словари с массивами, вложенные словари

Как указывать значения

В YAML файлах (для Tenant Storage) и при установке значений (для User Storage) можно писать значения в их естественном виде — система автоматически определит тип:

yaml
settings:
  max_users: 100                    # Целое число
  price: 9.99                       # Дробное число
  enable_feature: true              # Булево значение
  default_language: "ru"            # Строка
  allowed_languages: ["ru", "en", "de"]  # Массив строк
  price_tiers: [9.99, 19.99, 29.99]      # Массив чисел
  
  # JSON объекты (словари)
  admin_config:
    id: 1133574222
    name: "Admin"
    role: "admin"
    permissions: ["read", "write"]
  
  # Массивы словарей (массивы структур)
  users:
    - id: 1
      name: "User 1"
      role: "user"
    - id: 2
      name: "User 2"
      role: "admin"
  
  # Вложенные структуры
  nested_data:
    level1:
      level2:
        value: "deep nested"
        items: [1, 2, 3]

Булевы значения:

  • true, false (булевы значения в YAML)
  • "true", "false" (строки - будут преобразованы в булевы значения)

Массивы:

  • Могут содержать простые типы: строки, числа, float, bool
  • Могут содержать сложные структуры: словари, вложенные массивы
  • Элементы массива автоматически преобразуются в соответствующие типы при чтении
  • Доступ к элементам через плейсхолдеры: {_cache.storage_values.settings.allowed_languages[0]}

Словари (JSON объекты):

  • Могут содержать любые поддерживаемые типы значений
  • Поддерживают вложенность до 10 уровней глубины
  • Доступ к полям через точечную нотацию: {_cache.storage_values.settings.admin_config.name}
  • Комбинация с массивами: {_cache.storage_values.settings.users[0].name}

🎬 Использование в сценариях

Доступные действия

Tenant Storage

В сценариях доступны следующие действия для работы с Tenant Storage:

  • get_storage — получить значения storage тенанта (одно значение, группу или все значения). Поддерживает параметры group_key, key, group_key_pattern, key_pattern для гибкого поиска
  • get_storage_groups — получить список уникальных ключей групп для тенанта
  • set_storage — установить значения в storage тенанта. Поддерживает смешанный подход: полная структура через values или частичная через group_key/key/value
  • delete_storage — удалить значения или группы из storage тенанта. Поддерживает удаление конкретного значения, группы или по паттернам

User Storage

В сценариях доступны следующие действия для работы с User Storage:

  • get_user_storage — получить значения storage пользователя (одно значение или все значения). Поддерживает параметры key и key_pattern для гибкого поиска
  • set_user_storage — установить значения в storage пользователя. Поддерживает смешанный подход: полная структура через values или частичная через key/value
  • delete_user_storage — удалить значения из storage пользователя. Поддерживает удаление конкретного значения, всех значений или по паттерну

Важно:

  • Параметры tenant_id и user_id автоматически доступны из контекста события и не требуют явного указания в сценариях
  • Данные из response_data действий автоматически сохраняются в _cache (плоское кэширование по умолчанию)
  • Доступ к данным через плейсхолдеры: {_cache.storage_values} для Tenant Storage и {_cache.user_storage_values} для User Storage
  • Для Tenant Storage при запросе только группы (group_key указан, key не указан): возвращается структура группы {key: value} (без вложенности group_key), доступная через {_cache.storage_values.{key}}
  • Для Tenant Storage при запросе конкретного ключа (group_key и key указаны): возвращается прямое значение, доступное через {_cache.storage_values}
  • Для Tenant Storage при запросе всех значений (ничего не указано): возвращается полная структура {group_key: {key: value}}, доступная через {_cache.storage_values.{group_key}.{key}}
  • Для User Storage при запросе всех значений: {_cache.user_storage_values.{key}}
  • Для User Storage при запросе конкретного ключа: {_cache.user_storage_values} (прямое значение)

Пример 1: Получение и отображение значения

Простой пример — получение одного значения:

yaml
show_settings:
  description: "Показать настройки тенанта"
  
  trigger:
    - event_type: "message"
      event_text: "/settings"
  
  step:
    # Получаем значение из storage
    - action: "get_storage"
      params:
        group_key: "settings"
        key: "max_users"
    
    # Используем полученное значение в сообщении
    - action: "send_message"
      params:
        text: |
          📊 <b>Настройки</b>
          
          Максимум пользователей: <code>{_cache.storage_values}</code>

Доступ к значению:

  • При запросе конкретного ключа (group_key и key указаны) возвращается прямое значение (примитив или объект как есть), доступное через {_cache.storage_values}
  • В примере выше: {_cache.storage_values} вернет значение 100 (или другое значение max_users)
  • При запросе только группы (group_key указан, key не указан) возвращается структура группы {key: value}, доступная через {_cache.storage_values.{key}}

Пример 2: Получение группы значений

Получение всех значений группы одним запросом:

yaml
show_all_settings:
  description: "Показать все настройки"
  
  trigger:
    - event_type: "callback"
      callback_data: "show_settings"
  
  step:
    # Получаем всю группу settings одним запросом
    - action: "get_storage"
      params:
        group_key: "settings"
    
    # Используем все значения группы
    - action: "send_message"
      params:
        text: |
          ⚙️ <b>Все настройки</b>
          
          Максимум пользователей: <code>{_cache.storage_values.max_users}</code>
          Максимум хранилища: <code>{_cache.storage_values.max_storage}</code>
          Язык по умолчанию: <code>{_cache.storage_values.default_language}</code>
          
          Уведомления: {_cache.storage_values.enable_notifications|true|value:✅|fallback:❌}

Преимущества:

  • Один запрос вместо нескольких отдельных запросов
  • Все значения группы загружаются сразу
  • Эффективнее для отображения группы связанных настроек
  • При запросе только group_key возвращается структура группы {key: value} (без вложенности group_key), доступная через {_cache.storage_values.{key}}

Пример 3: Работа с User Storage

Получение и установка пользовательских данных:

yaml
# Установка пользовательских настроек
set_user_settings:
  description: "Установить настройки пользователя"
  
  trigger:
    - event_type: "callback"
      callback_data: "set_settings"
  
  step:
    - action: "set_user_storage"
      params:
        key: "language"
        value: "ru"
    
    - action: "set_user_storage"
      params:
        key: "theme"
        value: "dark"
    
    - action: "set_user_storage"
      params:
        key: "messages_sent"
        value: 0
    
    - action: "send_message"
      params:
        text: "✅ Настройки сохранены!"

# Получение всех данных пользователя
show_user_data:
  description: "Показать все данные пользователя"
  
  trigger:
    - event_type: "callback"
      callback_data: "show_data"
  
  step:
    - action: "get_user_storage"
    
    - action: "send_message"
      params:
        text: |
          👤 <b>Ваши данные</b>
          
          Язык: <code>{_cache.user_storage_values.language|fallback:не установлен}</code>
          Тема: <code>{_cache.user_storage_values.theme|fallback:не установлена}</code>
          Сообщений отправлено: <code>{_cache.user_storage_values.messages_sent|fallback:0}</code>

# Удаление пользовательских данных
delete_user_data:
  description: "Удалить данные пользователя"
  
  trigger:
    - event_type: "callback"
      callback_data: "delete_data"
  
  step:
    - action: "delete_user_storage"
      params:
        key: "language"
    
    - action: "send_message"
      params:
        text: "🗑️ Данные удалены!"

Особенности User Storage:

  • tenant_id и user_id автоматически доступны из контекста события
  • Данные изолированы по тенантам и пользователям
  • Нет группировки — плоская структура {key: value}
  • Данные устанавливаются только через действия сценариев

Пример 4: Форматирование YAML

Отображение данных в читаемом формате YAML:

yaml
show_formatted_storage:
  description: "Показать storage в формате YAML"
  
  trigger:
    - event_type: "callback"
      callback_data: "show_formatted"
  
  step:
    # Получение группы с форматированием
    - action: "get_storage"
      params:
        group_key: "settings"
        format: true
    
    - action: "send_message"
      params:
        text: |
          ⚙️ <b>Настройки (YAML формат)</b>
          
          <pre>{_cache.formatted_text}</pre>

Параметр format:

  • Доступен для всех действий получения данных (get_storage, get_user_storage)
  • При format: true в response_data добавляется поле formatted_text с данными в формате YAML
  • Доступ к отформатированному тексту через {_cache.formatted_text}
  • Удобно для отображения сложных структур данных пользователям

Coreness — Create. Automate. Scale.