Initial commit: Эфир мессенджер

This commit is contained in:
2026-04-06 14:57:36 +03:00
commit ff93679b6d
50 changed files with 5642 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
package service
import (
"context"
"errors"
"messenger/internal/models"
"messenger/internal/pkg/logger"
"messenger/internal/repository"
)
type AdminService struct {
userRepo repository.UserRepository
chatRepo repository.ChatRepository
messageRepo repository.MessageRepository
fileService *FileService
}
func NewAdminService(
userRepo repository.UserRepository,
chatRepo repository.ChatRepository,
messageRepo repository.MessageRepository,
fileService *FileService,
) *AdminService {
return &AdminService{
userRepo: userRepo,
chatRepo: chatRepo,
messageRepo: messageRepo,
fileService: fileService,
}
}
// DeleteUser удаляет пользователя (каскадно)
func (s *AdminService) DeleteUser(ctx context.Context, adminUserID, targetUserID int64) error {
// Проверяем, что администратор имеет права
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return err
}
if admin == nil || !admin.IsGlobalAdmin() {
return errors.New("only global admin can delete users")
}
// Нельзя удалить самого себя через эту функцию
if adminUserID == targetUserID {
return errors.New("cannot delete yourself")
}
// Проверяем существование пользователя
target, err := s.userRepo.FindByID(ctx, targetUserID)
if err != nil {
return err
}
if target == nil {
return errors.New("user not found")
}
// Удаляем пользователя (каскадное удаление сработает через foreign keys)
if err := s.userRepo.Delete(ctx, targetUserID); err != nil {
logger.Error("Failed to delete user", "error", err)
return errors.New("failed to delete user")
}
logger.Info("User deleted by admin", "admin_id", adminUserID, "target_user_id", targetUserID)
return nil
}
// DeleteMessage удаляет любое сообщение (админское право)
func (s *AdminService) DeleteMessage(ctx context.Context, adminUserID, messageID int64) error {
// Проверяем права администратора
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return err
}
if admin == nil || !admin.IsGlobalAdmin() {
return errors.New("only global admin can delete any message")
}
if err := s.messageRepo.Delete(ctx, messageID); err != nil {
logger.Error("Failed to delete message by admin", "error", err)
return errors.New("failed to delete message")
}
logger.Info("Message deleted by admin", "admin_id", adminUserID, "message_id", messageID)
return nil
}
// DeleteChat удаляет любой чат (админское право)
func (s *AdminService) DeleteChat(ctx context.Context, adminUserID, chatID int64) error {
// Проверяем права администратора
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return err
}
if admin == nil || !admin.IsGlobalAdmin() {
return errors.New("only global admin can delete any chat")
}
if err := s.chatRepo.Delete(ctx, chatID); err != nil {
logger.Error("Failed to delete chat by admin", "error", err)
return errors.New("failed to delete chat")
}
logger.Info("Chat deleted by admin", "admin_id", adminUserID, "chat_id", chatID)
return nil
}
// PromoteToAdmin повышает пользователя до глобального администратора
func (s *AdminService) PromoteToAdmin(ctx context.Context, adminUserID, targetUserID int64) error {
// Проверяем права администратора
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return err
}
if admin == nil || !admin.IsGlobalAdmin() {
return errors.New("only global admin can promote users")
}
if err := s.userRepo.UpdateRole(ctx, targetUserID, models.RoleGlobalAdmin); err != nil {
logger.Error("Failed to promote user to admin", "error", err)
return errors.New("failed to promote user")
}
logger.Info("User promoted to global admin", "admin_id", adminUserID, "target_user_id", targetUserID)
return nil
}
// DemoteFromAdmin понижает глобального администратора до обычного пользователя
func (s *AdminService) DemoteFromAdmin(ctx context.Context, adminUserID, targetUserID int64) error {
// Проверяем права администратора
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return err
}
if admin == nil || !admin.IsGlobalAdmin() {
return errors.New("only global admin can demote users")
}
// Нельзя понизить самого себя
if adminUserID == targetUserID {
return errors.New("cannot demote yourself")
}
if err := s.userRepo.UpdateRole(ctx, targetUserID, models.RoleUser); err != nil {
logger.Error("Failed to demote user", "error", err)
return errors.New("failed to demote user")
}
logger.Info("User demoted from global admin", "admin_id", adminUserID, "target_user_id", targetUserID)
return nil
}
// GetSystemStats возвращает системную статистику
func (s *AdminService) GetSystemStats(ctx context.Context, adminUserID int64) (map[string]interface{}, error) {
// Проверяем права администратора
admin, err := s.userRepo.FindByID(ctx, adminUserID)
if err != nil {
return nil, err
}
if admin == nil || !admin.IsGlobalAdmin() {
return nil, errors.New("only global admin can view system stats")
}
// Здесь можно добавить реальную статистику из БД
// Например, количество пользователей, сообщений, чатов и т.д.
stats := make(map[string]interface{})
// Это заглушка - в реальном коде нужно добавить методы в репозитории
stats["version"] = "1.0.0"
stats["status"] = "healthy"
logger.Info("System stats viewed by admin", "admin_id", adminUserID)
return stats, nil
}