feat: добавлена система чата с модерацией
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Реализована полнофункциональная система чата с двумя режимами работы: ## Режимы работы: - Broadcast: рассылка сообщений всем пользователям - Forward: пересылка сообщений в указанную группу/канал ## Функционал: - Поддержка всех типов сообщений: text, photo, video, document, animation, sticker, voice - Система банов: личные баны пользователей и глобальный бан чата - Модерация: удаление сообщений с отслеживанием в БД - История сообщений с сохранением ID пересланных сообщений ## Структура БД (миграция 005): - chat_settings: настройки чата (режим, ID канала, глобальный бан) - banned_users: история банов с причинами и информацией о модераторе - chat_messages: история сообщений с типами, файлами и картой доставки (JSONB) ## Сервисы: - ChatSettingsService: управление настройками чата - BanService: управление банами пользователей - ChatMessageService: работа с историей сообщений - ChatPermissionService: проверка прав на отправку сообщений ## Обработчики: - chat_handlers.py: обработка сообщений пользователей (7 типов контента) - admin_chat_handlers.py: админские команды управления чатом ## Админские команды: - /chat_mode - переключение режима (broadcast/forward) - /set_forward <chat_id> - установка ID канала для пересылки - /ban <user_id> [причина] - бан пользователя - /unban <user_id> - разбан пользователя - /banlist - список забаненных - /global_ban - включение/выключение глобального бана - /delete_msg - удаление сообщения (ответ на сообщение) - /chat_stats - статистика чата ## Документация: - docs/CHAT_SYSTEM.md: полное описание системы с примерами использования Изменено файлов: 7 (2 modified, 5 new) - main.py: подключены chat_router и admin_chat_router - src/core/models.py: добавлены модели ChatSettings, BannedUser, ChatMessage - migrations/versions/005_add_chat_system.py: миграция создания таблиц - src/core/chat_services.py: сервисный слой для чата (267 строк) - src/handlers/chat_handlers.py: обработчики сообщений (447 строк) - src/handlers/admin_chat_handlers.py: админские команды (369 строк) - docs/CHAT_SYSTEM.md: документация (390 строк)
This commit is contained in:
91
migrations/versions/005_add_chat_system.py
Normal file
91
migrations/versions/005_add_chat_system.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""Add chat system tables
|
||||
|
||||
Revision ID: 005
|
||||
Revises: 004
|
||||
Create Date: 2025-11-16 14:00:00.000000
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '005'
|
||||
down_revision = '004'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Таблица настроек чата
|
||||
op.create_table(
|
||||
'chat_settings',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('mode', sa.String(), nullable=False, server_default='broadcast'), # broadcast или forward
|
||||
sa.Column('forward_chat_id', sa.String(), nullable=True), # ID группы/канала для пересылки
|
||||
sa.Column('global_ban', sa.Boolean(), nullable=False, server_default='false'), # Глобальный бан чата
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
# Вставляем дефолтные настройки
|
||||
op.execute(
|
||||
"INSERT INTO chat_settings (id, mode, global_ban) VALUES (1, 'broadcast', false)"
|
||||
)
|
||||
|
||||
# Таблица забаненных пользователей
|
||||
op.create_table(
|
||||
'banned_users',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False), # ID пользователя в системе
|
||||
sa.Column('telegram_id', sa.BigInteger(), nullable=False), # Telegram ID
|
||||
sa.Column('banned_by', sa.Integer(), nullable=False), # ID админа
|
||||
sa.Column('reason', sa.Text(), nullable=True), # Причина бана
|
||||
sa.Column('banned_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False, server_default='true'), # Активен ли бан
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['banned_by'], ['users.id'], ondelete='SET NULL')
|
||||
)
|
||||
|
||||
# Индексы для быстрого поиска
|
||||
op.create_index('ix_banned_users_telegram_id', 'banned_users', ['telegram_id'])
|
||||
op.create_index('ix_banned_users_is_active', 'banned_users', ['is_active'])
|
||||
|
||||
# Таблица сообщений чата (для хранения истории и модерации)
|
||||
op.create_table(
|
||||
'chat_messages',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False), # Отправитель
|
||||
sa.Column('telegram_message_id', sa.Integer(), nullable=False), # ID сообщения в Telegram
|
||||
sa.Column('message_type', sa.String(), nullable=False), # text, photo, video, document, etc.
|
||||
sa.Column('text', sa.Text(), nullable=True), # Текст сообщения
|
||||
sa.Column('file_id', sa.String(), nullable=True), # ID файла в Telegram
|
||||
sa.Column('forwarded_message_ids', postgresql.JSONB(), nullable=True), # Список ID пересланных сообщений
|
||||
sa.Column('is_deleted', sa.Boolean(), nullable=False, server_default='false'),
|
||||
sa.Column('deleted_by', sa.Integer(), nullable=True), # Кто удалил
|
||||
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['deleted_by'], ['users.id'], ondelete='SET NULL')
|
||||
)
|
||||
|
||||
# Индексы
|
||||
op.create_index('ix_chat_messages_user_id', 'chat_messages', ['user_id'])
|
||||
op.create_index('ix_chat_messages_created_at', 'chat_messages', ['created_at'])
|
||||
op.create_index('ix_chat_messages_is_deleted', 'chat_messages', ['is_deleted'])
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_index('ix_chat_messages_is_deleted', table_name='chat_messages')
|
||||
op.drop_index('ix_chat_messages_created_at', table_name='chat_messages')
|
||||
op.drop_index('ix_chat_messages_user_id', table_name='chat_messages')
|
||||
op.drop_table('chat_messages')
|
||||
|
||||
op.drop_index('ix_banned_users_is_active', table_name='banned_users')
|
||||
op.drop_index('ix_banned_users_telegram_id', table_name='banned_users')
|
||||
op.drop_table('banned_users')
|
||||
|
||||
op.drop_table('chat_settings')
|
||||
Reference in New Issue
Block a user