UNPKG

@dieugene/users-controller

Version:

Модуль для управления глобальным реестром пользователей сервиса и их данными через различные каналы коммуникации

294 lines (198 loc) 14.2 kB
# Users Controller Модуль для управления глобальным реестром пользователей сервиса и их данными через различные каналы коммуникации. ## Принципы работы с пользователями Модуль предусматривает ведение глобального реестра пользователей сервиса, безотносительно к тому, через какой канал происходит взаимодействие с сервисом. В то же время, на текущий момент настроена работа только через один канал - телеграм-боты. Пользователи могут взаимодействовать с системой через разные каналы, в которых у них свои идентификаторы и метаданные. Каждому пользователю присваивается глобальный UUID, и разные каналы коммуникаций связываются с этим ID. Особенность задачи в том, что при подключении каждого нового канала коммуникаций пользователь считается "новым", пока не будет выполнена связь с другими каналами. Когда пользователь выполняет привязку (через предоставление своего глобального ID), идентификатор "нового" канала переписывается. ## Типы хранилища Модуль предусматривает три типа хранилища: ### 1. Общий реестр пользователей - **Таблица**: `users_global` - **Модуль**: `UsersGlobal` - **Назначение**: Связывает идентификаторы каналов с глобальными UUID пользователей - **Структура**: тип канала, идентификатор в канале, глобальный идентификатор, дата регистрации ### 2. Пользовательские данные - **Хранилище**: Key-value база данных - **Модуль**: `UserData` - **Назначение**: Хранение объектов с различной пользовательской информацией - **Особенности**: Использует кэширование для оптимизации производительности ### 3. Пакетная обработка пользовательских данных - **Таблица**: `users_processing_{domain}` - **Модуль**: `UserProcessing` - **Назначение**: Временное хранение данных для пакетной обработки - **Оптимизация**: Создано для снижения затрат на операции чтения/записи ## Конфигурация базы данных ### Рекомендуемая структура С точки зрения структуры хранения данных рекомендуется иметь глобальную базу данных, в которой будут храниться данные по всем пользователям. Адрес к этой базе прописывается в переменной `GLOBAL_DB_ADDRESS`, либо указывается при инициализации. ### Альтернативная структура Также допускается, но не рекомендуется ситуация, что данные (таблицы) распределены по разным базам данных. В этом случае требуется выполнять раздельную инициализацию для каждого из используемых хранилищ. ## Правила именования для пакетной обработки При инициализации данных для пакетной обработки нужно соблюдать правила именования для параметра `domain`, поскольку его значение становится частью названия таблицы, в которой будет вестись работа. В частности, допустимы: - прописные латинские буквы (A-Z) - строчные латинские буквы (a-z) - цифры (0-9) - специальные символы: `.`, `-` и `_` ## Установка ```bash npm install @dieugene/users-controller ``` ## Зависимости - `@dieugene/key-value-db` - для работы с key-value хранилищем - `@dieugene/utils` - утилиты - `@dieugene/ydb-serverless` - для работы с YDB - `uuid` - генерация уникальных идентификаторов ## Дополнительная документация 📋 **[Руководство по работе с таблицами YDB](./YDB_TABLE_OPERATIONS_GUIDE.md)** - подробное руководство по CRUD операциям с использованием @dieugene/ydb-serverless, включая: - Оптимизацию стоимости операций (UPSERT vs INSERT vs UPDATE) - Рекомендации по индексации полей - Лучшие практики работы с YDB - Примеры кода для всех типов операций ## Быстрый старт ```javascript const users = require('@dieugene/users-controller'); // Инициализация с использованием переменной окружения GLOBAL_DB_ADDRESS users.init(); // Или с указанием адреса базы данных users.init('/region/folder-id/database-id'); ``` ## API ### Основная инициализация #### `init(users_database?)` Инициализирует все модули с указанной базой данных. **Параметры:** - `users_database` (string, optional) - адрес базы данных. По умолчанию используется `process.env.GLOBAL_DB_ADDRESS` ### Модуль UsersGlobal (`users.globals`) #### `init(users_database?)` Инициализирует модуль работы с глобальным реестром пользователей. #### `getUserUuid(channelType, inChannelId)` Получает глобальный UUID пользователя по данным канала. **Параметры:** - `channelType` (string) - тип канала коммуникации - `inChannelId` (string) - идентификатор пользователя в канале **Возвращает:** Promise<string|undefined> - глобальный UUID пользователя #### `setUser(channelType, inChannelId)` Создает нового пользователя в глобальном реестре. **Параметры:** - `channelType` (string) - тип канала коммуникации - `inChannelId` (string) - идентификатор пользователя в канале **Возвращает:** Promise<string> - новый глобальный UUID пользователя #### `getChannelUsers(channelType)` Получает список всех пользователей определенного канала. **Параметры:** - `channelType` (string) - тип канала коммуникации ### Модуль UserData (`users.data`) #### `init(database?)` Инициализирует модуль работы с пользовательскими данными. #### `set_user_data(user_uuid, data)` Сохраняет данные пользователя. **Параметры:** - `user_uuid` (string) - глобальный UUID пользователя - `data` (object) - данные для сохранения #### `get_user_data(user_uuid, forced?)` Получает данные пользователя. **Параметры:** - `user_uuid` (string) - глобальный UUID пользователя - `forced` (boolean, optional) - принудительное обновление кэша **Возвращает:** Promise<object> - данные пользователя ### Модуль UserProcessing (`users.processing`) #### `init(domain, users_database?)` Инициализирует модуль пакетной обработки. **Параметры:** - `domain` (string) - домен для именования таблицы (должен соответствовать правилам именования) - `users_database` (string, optional) - адрес базы данных #### `set(uuid_list)` Добавляет список UUID пользователей для обработки. **Параметры:** - `uuid_list` (string[]) - массив UUID пользователей #### `set_channel_users(channel)` Добавляет всех пользователей канала для обработки. **Параметры:** - `channel` (string) - тип канала #### `get(limit?)` Получает пакет пользователей для обработки. **Параметры:** - `limit` (number, optional) - количество пользователей (по умолчанию 50) **Возвращает:** Promise<string[]> - массив UUID пользователей #### `del(id_list)` Удаляет обработанных пользователей из очереди. **Параметры:** - `id_list` (string[]) - массив UUID пользователей для удаления ### Модуль TelegramUsers (`users.tg`) #### `get_user_uuid(ctx, tgId?)` Получает глобальный UUID пользователя Telegram. **Параметры:** - `ctx` - контекст Telegram бота - `tgId` (number, optional) - ID пользователя Telegram **Возвращает:** Promise<string> - глобальный UUID пользователя #### `stringify_user_data(userData)` Форматирует данные пользователя Telegram в строку. **Параметры:** - `userData` (object) - данные пользователя с полями `first_name`, `last_name`, `username` **Возвращает:** string - отформатированная строка #### `get_bot_users(botId)` Получает список пользователей конкретного Telegram бота. **Параметры:** - `botId` (string) - ID Telegram бота #### `set_telegram_data(user_data, ctx)` Обновляет пользовательские данные информацией из Telegram контекста. **Параметры:** - `user_data` (object) - объект данных пользователя - `ctx` - контекст Telegram бота **Возвращает:** object - обновленный объект данных пользователя **Заполняемые поля:** - `telegram_data.telegram_id` - ID пользователя в Telegram - `telegram_data.first_name` - имя пользователя - `telegram_data.last_name` - фамилия пользователя - `telegram_data.username` - никнейм пользователя - `telegram_data.language_code` - код языка пользователя - `telegram_data.is_bot` - флаг бота - `telegram_data.is_premium` - флаг Telegram Premium - `telegram_data.updated_at` - Unix timestamp последнего обновления ### Вспомогательные методы #### `set_user_data(user_uuid, data)` Прямой доступ к сохранению пользовательских данных. #### `get_user_data(user_uuid, forced?)` Прямой доступ к получению пользовательских данных. ## Примеры использования ### Работа с пользователями Telegram ```javascript const users = require('@dieugene/users-controller'); // Инициализация users.init(); // Получение UUID пользователя Telegram async function handleTelegramUser(ctx) { const userUuid = await users.tg.get_user_uuid(ctx); // Получение данных пользователя let userData = await users.get_user_data(userUuid); // Обновление данных из Telegram (имя, фамилия, username и т.д.) userData = users.tg.set_telegram_data(userData, ctx); // Добавление дополнительных данных userData.last_interaction = new Date(); userData.preferences = { language: 'ru' }; // Сохранение обновленных данных await users.set_user_data(userUuid, userData); } ``` ### Пакетная обработка пользователей ```javascript // Инициализация модуля пакетной обработки await users.processing.init('newsletter'); // Добавление всех пользователей Telegram для обработки await users.processing.set_channel_users('telegram_bot_id'); // Обработка пользователей пакетами async function processUsers() { const usersList = await users.processing.get(100); for (const userUuid of usersList) { // Обработка пользователя await processUser(userUuid); } // Удаление обработанных пользователей await users.processing.del(usersList); } ``` ## Переменные окружения - `GLOBAL_DB_ADDRESS` - адрес глобальной базы данных (формат: `/region/folder-id/database-id`) ## Лицензия ISC ## Автор Eugene Ditkovsky