refactor
Some checks failed
continuous-integration/drone/pr Build is failing

This commit is contained in:
2026-02-17 00:22:42 +09:00
parent ca0c63a89c
commit 0fdad07d82
36 changed files with 4384 additions and 368 deletions

View File

@@ -19,7 +19,9 @@ class User(Base):
club_card_number = Column(String(50), unique=True, nullable=True, index=True) # Номер клубной карты
is_registered = Column(Boolean, default=False) # Прошел ли полную регистрацию
is_admin = Column(Boolean, default=False)
is_chat_banned = Column(Boolean, default=False) # Заблокирован ли в чате бота
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
last_activity = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) # Последняя активность
# Секретный код для верификации выигрыша (генерируется при регистрации)
verification_code = Column(String(10), unique=True, nullable=True)
@@ -242,4 +244,72 @@ class P2PMessage(Base):
reply_to = relationship("P2PMessage", remote_side=[id], backref="replies")
def __repr__(self):
return f"<P2PMessage(id={self.id}, from={self.sender_id}, to={self.recipient_id})>"
return f"<P2PMessage(id={self.id}, from={self.sender_id}, to={self.recipient_id})>"
class BroadcastChannel(Base):
"""Каналы и группы для рассылки"""
__tablename__ = "broadcast_channels"
id = Column(Integer, primary_key=True)
chat_id = Column(BigInteger, nullable=False, unique=True, index=True) # ID канала или группы
chat_type = Column(String(20), nullable=False) # 'channel' или 'group'
title = Column(String(255), nullable=False) # Название
username = Column(String(255), nullable=True) # Username (если есть)
description = Column(Text, nullable=True) # Описание
is_active = Column(Boolean, default=True, index=True) # Активен ли для рассылок
added_by = Column(Integer, ForeignKey("users.id"), nullable=False)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
# Связи
admin = relationship("User")
def __repr__(self):
return f"<BroadcastChannel(id={self.id}, title={self.title}, type={self.chat_type})>"
class BlockedUser(Base):
"""Пользователи, которые заблокировали бота или недоступны"""
__tablename__ = "blocked_users"
id = Column(Integer, primary_key=True)
telegram_id = Column(BigInteger, nullable=False, unique=True, index=True)
error_type = Column(String(100), nullable=False) # тип ошибки (blocked, deleted, deactivated, etc.)
error_message = Column(Text, nullable=True) # Полное сообщение об ошибке
first_blocked_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
last_attempt_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
attempt_count = Column(Integer, default=1) # Количество неудачных попыток
is_active = Column(Boolean, default=True, index=True) # Активна ли блокировка
def __repr__(self):
return f"<BlockedUser(telegram_id={self.telegram_id}, error={self.error_type})>"
class BroadcastLog(Base):
"""История рассылок"""
__tablename__ = "broadcast_logs"
id = Column(Integer, primary_key=True)
broadcast_type = Column(String(20), nullable=False, index=True) # 'direct', 'channel', 'group'
target_id = Column(BigInteger, nullable=True) # ID канала/группы (null для direct)
message_type = Column(String(20), nullable=False) # text, photo, video, etc.
message_text = Column(Text, nullable=True) # Текст сообщения
file_id = Column(String(255), nullable=True) # ID файла (если есть)
# Статистика
total_recipients = Column(Integer, default=0) # Всего получателей
success_count = Column(Integer, default=0) # Успешно доставлено
failed_count = Column(Integer, default=0) # Не доставлено
blocked_count = Column(Integer, default=0) # Заблокировали бота
# Метаданные
created_by = Column(Integer, ForeignKey("users.id"), nullable=False)
started_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
completed_at = Column(DateTime(timezone=True), nullable=True)
status = Column(String(20), default='pending', index=True) # pending, in_progress, completed, failed
# Связи
admin = relationship("User")
def __repr__(self):
return f"<BroadcastLog(id={self.id}, type={self.broadcast_type}, status={self.status})>"