mirror of
https://github.com/FerraSoft/bottohelp.git
synced 2026-08-06 21:55:03 +00:00
Подготовка к релизу
This commit is contained in:
@@ -0,0 +1,374 @@
|
||||
"""
|
||||
Модели данных для телеграм-бота.
|
||||
Определяют структуру данных и их взаимосвязи.
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Optional, List, Any, Dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class Role:
|
||||
"""Модель роли пользователя"""
|
||||
id: int
|
||||
name: str
|
||||
display_name: str
|
||||
description: Optional[str] = None
|
||||
permissions: Optional[str] = None # JSON строка с разрешениями
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
"""Модель пользователя"""
|
||||
id: int
|
||||
telegram_id: int
|
||||
username: Optional[str] = None
|
||||
first_name: Optional[str] = None
|
||||
last_name: Optional[str] = None
|
||||
joined_date: datetime = None
|
||||
last_activity: datetime = None
|
||||
reputation: int = 0
|
||||
rank: str = "Новичок"
|
||||
warnings: int = 0
|
||||
is_active: bool = True
|
||||
role_id: int = 1 # Ссылка на таблицу roles, по умолчанию user
|
||||
|
||||
def __post_init__(self):
|
||||
if self.joined_date is None:
|
||||
self.joined_date = datetime.now()
|
||||
if self.last_activity is None:
|
||||
self.last_activity = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Score:
|
||||
"""Модель очков и статистики пользователя"""
|
||||
id: int
|
||||
user_id: int
|
||||
total_score: int = 0
|
||||
message_count: int = 0
|
||||
game_wins: int = 0
|
||||
donations_total: float = 0.0
|
||||
last_updated: datetime = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.last_updated is None:
|
||||
self.last_updated = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Error:
|
||||
"""Модель ошибки/отчета об ошибке"""
|
||||
id: int
|
||||
admin_id: int
|
||||
error_type: str
|
||||
title: str
|
||||
description: str
|
||||
status: str = "new"
|
||||
priority: str = "medium"
|
||||
created_at: datetime = None
|
||||
updated_at: datetime = None
|
||||
ai_analysis: Optional[str] = None
|
||||
todo_added: bool = False
|
||||
resolved_at: Optional[datetime] = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.created_at is None:
|
||||
self.created_at = datetime.now()
|
||||
if self.updated_at is None:
|
||||
self.updated_at = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScheduledPost:
|
||||
"""Модель запланированного поста"""
|
||||
id: int
|
||||
chat_id: int
|
||||
text: str
|
||||
image_path: Optional[str] = None
|
||||
schedule_time: datetime = None
|
||||
created_by: int = 0
|
||||
status: str = "pending"
|
||||
published_at: Optional[datetime] = None
|
||||
created_at: datetime = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.schedule_time is None:
|
||||
self.schedule_time = datetime.now()
|
||||
if self.created_at is None:
|
||||
self.created_at = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Achievement:
|
||||
"""Модель достижения"""
|
||||
id: int
|
||||
name: str
|
||||
description: str
|
||||
condition_type: str
|
||||
condition_value: Any
|
||||
badge: str
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
class UserAchievement:
|
||||
"""Модель разблокированного достижения пользователя"""
|
||||
id: int
|
||||
user_id: int
|
||||
achievement_id: int
|
||||
unlocked_at: datetime = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.unlocked_at is None:
|
||||
self.unlocked_at = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Trigger:
|
||||
"""Модель триггера"""
|
||||
id: int
|
||||
name: str
|
||||
pattern: str # Регулярное выражение для сопоставления текста
|
||||
description: Optional[str] = None
|
||||
response_text: Optional[str] = None
|
||||
response_sticker: Optional[str] = None
|
||||
response_gif: Optional[str] = None
|
||||
reaction_type: Optional[str] = None # "emoji" для реакции эмодзи
|
||||
action_data: Optional[str] = None # Данные действия, например emoji
|
||||
is_active: bool = True
|
||||
created_by: int = 0
|
||||
created_at: datetime = None
|
||||
trigger_count: int = 0 # Количество срабатываний
|
||||
last_triggered: Optional[datetime] = None
|
||||
chat_type: str = "group" # "group" или "private"
|
||||
|
||||
def __post_init__(self):
|
||||
if self.created_at is None:
|
||||
self.created_at = datetime.now()
|
||||
|
||||
@dataclass
|
||||
class Warning:
|
||||
"""Модель предупреждения пользователя"""
|
||||
id: int
|
||||
user_id: int
|
||||
reason: str
|
||||
admin_id: int
|
||||
created_at: datetime = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.created_at is None:
|
||||
self.created_at = datetime.now()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Donation:
|
||||
"""Модель доната пользователя"""
|
||||
id: int
|
||||
user_id: int
|
||||
amount: float
|
||||
year: int = None
|
||||
created_at: datetime = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.year is None:
|
||||
self.year = datetime.now().year
|
||||
if self.created_at is None:
|
||||
self.created_at = datetime.now()
|
||||
|
||||
|
||||
class DatabaseSchema:
|
||||
"""Схема базы данных"""
|
||||
|
||||
TABLES = {
|
||||
'roles': '''
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
permissions TEXT,
|
||||
is_active BOOLEAN DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''',
|
||||
|
||||
'users': '''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
telegram_id INTEGER UNIQUE NOT NULL,
|
||||
username TEXT,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
joined_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
last_activity DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
reputation INTEGER DEFAULT 0,
|
||||
rank TEXT DEFAULT 'Новичок',
|
||||
warnings INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT 1,
|
||||
role_id INTEGER DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (role_id) REFERENCES roles(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'scores': '''
|
||||
CREATE TABLE IF NOT EXISTS scores (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER UNIQUE NOT NULL,
|
||||
total_score INTEGER DEFAULT 0,
|
||||
message_count INTEGER DEFAULT 0,
|
||||
game_wins INTEGER DEFAULT 0,
|
||||
donations_total REAL DEFAULT 0.0,
|
||||
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'errors': '''
|
||||
CREATE TABLE IF NOT EXISTS errors (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
admin_id INTEGER NOT NULL,
|
||||
error_type TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT DEFAULT 'new',
|
||||
priority TEXT DEFAULT 'medium',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
ai_analysis TEXT,
|
||||
todo_added BOOLEAN DEFAULT 0,
|
||||
resolved_at DATETIME,
|
||||
FOREIGN KEY (admin_id) REFERENCES users(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'scheduled_posts': '''
|
||||
CREATE TABLE IF NOT EXISTS scheduled_posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
chat_id INTEGER NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
image_path TEXT,
|
||||
schedule_time DATETIME NOT NULL,
|
||||
created_by INTEGER DEFAULT 0,
|
||||
status TEXT DEFAULT 'pending',
|
||||
published_at DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''',
|
||||
|
||||
'achievements': '''
|
||||
CREATE TABLE IF NOT EXISTS achievements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
condition_type TEXT NOT NULL,
|
||||
condition_value TEXT NOT NULL,
|
||||
badge TEXT NOT NULL,
|
||||
is_active BOOLEAN DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''',
|
||||
|
||||
'user_achievements': '''
|
||||
CREATE TABLE IF NOT EXISTS user_achievements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
achievement_id INTEGER NOT NULL,
|
||||
unlocked_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (achievement_id) REFERENCES achievements(id),
|
||||
UNIQUE(user_id, achievement_id)
|
||||
)
|
||||
''',
|
||||
|
||||
'warnings': '''
|
||||
CREATE TABLE IF NOT EXISTS warnings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
admin_id INTEGER NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (admin_id) REFERENCES users(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'donations': '''
|
||||
CREATE TABLE IF NOT EXISTS donations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
amount REAL NOT NULL,
|
||||
year INTEGER NOT NULL DEFAULT (strftime('%Y', 'now')),
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'payments': '''
|
||||
CREATE TABLE IF NOT EXISTS payments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
amount REAL NOT NULL,
|
||||
currency TEXT DEFAULT 'RUB',
|
||||
provider TEXT NOT NULL, -- 'stripe' или 'yookassa'
|
||||
external_id TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'pending',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
processed_at DATETIME,
|
||||
metadata TEXT, -- JSON
|
||||
error_message TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'transactions': '''
|
||||
CREATE TABLE IF NOT EXISTS transactions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
payment_id INTEGER NOT NULL,
|
||||
type TEXT NOT NULL, -- 'payment', 'refund'
|
||||
amount REAL NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
external_transaction_id TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
details TEXT, -- JSON
|
||||
FOREIGN KEY (payment_id) REFERENCES payments(id)
|
||||
)
|
||||
''',
|
||||
|
||||
'triggers': '''
|
||||
CREATE TABLE IF NOT EXISTS triggers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
pattern TEXT NOT NULL,
|
||||
response_text TEXT,
|
||||
response_sticker TEXT,
|
||||
response_gif TEXT,
|
||||
reaction_type TEXT,
|
||||
action_data TEXT,
|
||||
is_active BOOLEAN DEFAULT 1,
|
||||
created_by INTEGER DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
trigger_count INTEGER DEFAULT 0,
|
||||
last_triggered DATETIME,
|
||||
chat_type TEXT DEFAULT 'group'
|
||||
)
|
||||
''',
|
||||
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_create_tables_sql(cls) -> List[str]:
|
||||
"""Получение SQL для создания всех таблиц"""
|
||||
return list(cls.TABLES.values())
|
||||
|
||||
@classmethod
|
||||
def get_table_names(cls) -> List[str]:
|
||||
"""Получение списка имен таблиц"""
|
||||
return list(cls.TABLES.keys())
|
||||
Reference in New Issue
Block a user