добавил приветственный бонус и README

This commit is contained in:
2025-12-26 07:02:01 +03:00
parent 5f35d7a75f
commit dfd855cb6e
4 changed files with 532 additions and 141 deletions

View File

@@ -72,27 +72,29 @@ func (r *pgRepository) GetUserByID(id uuid.UUID) (*account.User, error) {
// ConnectServer - Основная точка входа для добавления сервера
func (r *pgRepository) ConnectServer(userID uuid.UUID, rawURL, login, encryptedPass, name string) (*account.RMSServer, error) {
// 1. Нормализация URL (удаляем слеш в конце, приводим к нижнему регистру)
// Важно: мы не удаляем http/https, так как iiko может работать и так и так, но обычно это разные эндпоинты.
// Для надежности уникальности можно вырезать протокол, но пока оставим как есть, просто тримминг.
cleanURL := strings.TrimRight(strings.ToLower(strings.TrimSpace(rawURL)), "/")
var server account.RMSServer
var created bool
err := r.db.Transaction(func(tx *gorm.DB) error {
// 2. Ищем, существует ли сервер с таким URL
err := tx.Where("base_url = ?", cleanURL).First(&server).Error
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if err == gorm.ErrRecordNotFound {
// --- СЦЕНАРИЙ 1: НОВЫЙ СЕРВЕР ---
// --- СЦЕНАРИЙ 1: НОВЫЙ СЕРВЕР (Приветственный бонус) ---
trialDays := 30
welcomeBalance := 10
paidUntil := time.Now().AddDate(0, 0, trialDays)
server = account.RMSServer{
BaseURL: cleanURL,
Name: name,
MaxUsers: 5, // Дефолтное ограничение
BaseURL: cleanURL,
Name: name,
MaxUsers: 5,
Balance: welcomeBalance,
PaidUntil: &paidUntil,
}
if err := tx.Create(&server).Error; err != nil {
return err
@@ -100,11 +102,9 @@ func (r *pgRepository) ConnectServer(userID uuid.UUID, rawURL, login, encryptedP
created = true
} else {
// --- СЦЕНАРИЙ 2: СУЩЕСТВУЮЩИЙ СЕРВЕР ---
// Проверяем лимит пользователей
var userCount int64
tx.Model(&account.ServerUser{}).Where("server_id = ?", server.ID).Count(&userCount)
if userCount >= int64(server.MaxUsers) {
// Проверяем, может пользователь УЖЕ там есть? Тогда это не добавление, а обновление кредов
var exists int64
tx.Model(&account.ServerUser{}).Where("server_id = ? AND user_id = ?", server.ID, userID).Count(&exists)
if exists == 0 {
@@ -113,18 +113,24 @@ func (r *pgRepository) ConnectServer(userID uuid.UUID, rawURL, login, encryptedP
}
}
// 3. Определяем роль
targetRole := account.RoleOperator
if created {
targetRole = account.RoleOwner
}
// 4. Создаем или обновляем связь с пользователем
// Сбрасываем активность других серверов
if err := tx.Model(&account.ServerUser{}).Where("user_id = ?", userID).Update("is_active", false).Error; err != nil {
return err
}
var existingLink account.ServerUser
err = tx.Where("server_id = ? AND user_id = ?", server.ID, userID).First(&existingLink).Error
if err == nil {
existingLink.Login = login
existingLink.EncryptedPassword = encryptedPass
existingLink.IsActive = true
return tx.Save(&existingLink).Error
}
userLink := account.ServerUser{
ServerID: server.ID,
UserID: userID,
@@ -133,22 +139,6 @@ func (r *pgRepository) ConnectServer(userID uuid.UUID, rawURL, login, encryptedP
Login: login,
EncryptedPassword: encryptedPass,
}
// Upsert для связи (на случай если пользователь подключает уже подключенный сервер, обновляем пароль)
// Если пользователь уже был OWNER/ADMIN, роль НЕ понижаем.
// Поэтому используем хитрый Upsert: обновляем роль только если запись новая.
var existingLink account.ServerUser
err = tx.Where("server_id = ? AND user_id = ?", server.ID, userID).First(&existingLink).Error
if err == nil {
// Запись есть -> обновляем креды и делаем активным, роль НЕ меняем
existingLink.Login = login
existingLink.EncryptedPassword = encryptedPass
existingLink.IsActive = true
return tx.Save(&existingLink).Error
}
// Записи нет -> создаем с вычисленной ролью
return tx.Create(&userLink).Error
})