Telegram Shop — Database Schema
Единая SQLite-база (db/shop.db), используемая одновременно ботом (src/, better-sqlite3) и админ-панелью (admin-next/, Prisma). Источник истины схемы: admin-next/prisma/schema.prisma.
Миграции бота: src/migrations/ (001–014, runner: src/migrations/runner.js).
Схема
users — пользователи Telegram
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| telegram_id |
TEXT UNIQUE |
ID в Telegram |
| username |
TEXT? |
|
| country / city / district |
TEXT? |
География |
| status |
INTEGER (0) |
0=active, 2=blocked |
| total_balance |
REAL (0) |
Основной баланс |
| bonus_balance |
REAL (0) |
Бонусный баланс |
| language |
TEXT ('en') |
en / es / de |
| language_set |
INTEGER (0) |
Флаг выбора языка |
| notes |
TEXT? |
Заметки админа (миграция 014) |
| created_at |
DATETIME |
|
Связи: wallets, transactions, purchases.
crypto_wallets — криптокошельки
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| user_id |
INTEGER FK → users |
|
| wallet_type |
TEXT |
BTC / LTC / ETH / USDT / USDC |
| address |
TEXT |
|
| derivation_path |
TEXT? |
|
| mnemonic |
TEXT? |
Seed-фраза (зашифрована) |
| balance |
REAL (0) |
|
| created_at |
DATETIME |
|
Уникальность: (user_id, wallet_type) — один кошелёк каждого типа на пользователя.
transactions — транзакции
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| user_id |
INTEGER FK → users |
|
| wallet_type |
TEXT |
|
| tx_hash |
TEXT? |
|
| amount |
REAL |
|
| created_at |
DATETIME |
|
locations — локации
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| country |
TEXT |
|
| city |
TEXT |
|
| district |
TEXT ('') |
|
| is_active |
INTEGER (1) |
0/1 |
| created_at |
DATETIME |
|
Уникальность: (country, city, district).
categories — категории
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| location_id |
INTEGER FK → locations |
|
| name |
TEXT |
|
| is_active |
INTEGER (1) |
|
| created_at |
DATETIME |
|
Уникальность: (location_id, name).
subcategories — подкатегории
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| category_id |
INTEGER FK → categories |
|
| name |
TEXT |
|
| is_active |
INTEGER (1) |
|
| created_at |
DATETIME |
|
Уникальность: (category_id, name).
products — товары
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| location_id |
INTEGER FK → locations |
|
| category_id |
INTEGER FK → categories |
|
| subcategory_id |
INTEGER? FK → subcategories |
|
| name |
TEXT |
|
| description |
TEXT? |
|
| private_data |
TEXT? |
Скрытый контент (выдаётся после покупки) |
| price |
REAL |
|
| quantity_in_stock |
INTEGER (0) |
Для mono-товаров = 999999 |
| photo_url |
TEXT? |
Публичное фото |
| hidden_photo_url |
TEXT? |
Скрытое фото |
| hidden_coordinates |
TEXT? |
Скрытые координаты |
| hidden_description |
TEXT? |
Скрытое описание |
| is_mono |
INTEGER (0) |
1 = неограниченный товар |
| created_at |
DATETIME |
|
purchases — покупки
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| user_id |
INTEGER FK → users |
|
| product_id |
INTEGER FK → products |
|
| wallet_type |
TEXT? |
|
| tx_hash |
TEXT? |
|
| quantity |
INTEGER |
|
| total_price |
REAL |
|
| purchase_date |
DATETIME |
|
| status |
TEXT ('pending') |
pending / completed / cancelled |
commission_payments — комиссионные выплаты
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| total_balance_usd |
REAL |
|
| commission_rate |
REAL |
|
| commission_amount_usd |
REAL |
|
| paid_amount_usd |
REAL |
|
| wallet_count |
INTEGER |
|
| note |
TEXT? |
|
| created_at |
DATETIME |
|
audit_log — журнал аудита
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| action |
TEXT |
balance_adjust, operator_connect, seed_phrase_viewed, clear_all и др. |
| admin_id |
TEXT |
Роль или telegram_id |
| details |
TEXT? |
JSON-строка с контекстом |
| created_at |
DATETIME |
|
chat_sessions — чат-сессии (чатбот)
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| session_id |
TEXT UNIQUE |
|
| telegram_id |
TEXT? |
|
| lead_id |
INTEGER? FK → leads |
|
| messages |
TEXT |
JSON-массив {role, content, timestamp} |
| language |
TEXT ('en') |
|
| device / ip / country |
TEXT? |
|
| customer_profile |
TEXT? |
AI-профиль клиента (JSON) |
| is_active |
BOOLEAN (true) |
|
| operator_name |
TEXT? |
|
| auto_reply_disabled |
BOOLEAN (false) |
|
| operator_connected_at |
DATETIME? |
|
| created_at / updated_at |
DATETIME |
|
leads — лиды
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| telegram_id |
TEXT? UNIQUE |
|
| name / phone / email / telegram |
TEXT? |
|
| status |
TEXT ('new') |
new / contacted / qualified / lost / spam |
| verification |
TEXT ('pending') |
|
| notes |
TEXT? |
|
| custom_fields |
TEXT ('{}') |
JSON |
| geo_address |
TEXT? |
|
| ai_lead_score |
REAL? |
|
| created_at / updated_at |
DATETIME |
|
Связь: chatSessions.
site_settings — настройки (ключ-значение)
| Колонка |
Тип |
Описание |
| id |
INTEGER PK |
|
| key |
TEXT UNIQUE |
Например chatbot_* |
| value |
TEXT |
|
| created_at / updated_at |
DATETIME |
|
user_states — состояния пользователей бота
| Колонка |
Тип |
Описание |
| chat_id |
TEXT PK |
|
| state_data |
TEXT? |
JSON состояния |
| updated_at |
INTEGER |
Unix-время |
Связи (ER-сводка)
Примечания
- Бот и админка работают с одной БД: любые изменения мгновенно видны обеим сторонам
users и leads — отдельные таблицы, связываются по telegram_id (не внешний ключ)
mnemonic хранится зашифрованным (ключ ENCRYPTION_KEY)
- Каскадное удаление: wallets/transactions/purchases удаляются вместе с пользователем; products — вместе с location/category
- Миграции бота нумеруются
NNN_*.js; Prisma-схема админки должна отражать ту же структуру