добавил пользователей для сервера и роли

добавил инвайт-ссылки с ролью оператор для сервера
добавил супер-админку для смены владельцев
добавил уведомления о смене ролей на серверах
добавил модалку для фото прям в черновике
добавил UI для редактирования прав
This commit is contained in:
2025-12-23 13:06:06 +03:00
parent 9441579a34
commit b4ce819931
21 changed files with 9244 additions and 418 deletions

View File

@@ -6,6 +6,15 @@ import (
"github.com/google/uuid"
)
// Роли пользователей
type Role string
const (
RoleOwner Role = "OWNER" // Создатель: Полный доступ + удаление сервера
RoleAdmin Role = "ADMIN" // Администратор: Редактирование, настройки, приглашение
RoleOperator Role = "OPERATOR" // Оператор: Только загрузка фото
)
// User - Пользователь системы (Telegram аккаунт)
type User struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
@@ -15,53 +24,94 @@ type User struct {
LastName string `gorm:"type:varchar(100)" json:"last_name"`
PhotoURL string `gorm:"type:text" json:"photo_url"`
IsAdmin bool `gorm:"default:false" json:"is_admin"`
// Связь с серверами
Servers []RMSServer `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"servers,omitempty"`
IsSystemAdmin bool `gorm:"default:false" json:"is_system_admin"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// RMSServer - Настройки подключения к iikoRMS
// ServerUser - Связь пользователя с сервером (здесь храним личные креды)
type ServerUser struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
ServerID uuid.UUID `gorm:"type:uuid;not null;index:idx_user_server,unique"`
UserID uuid.UUID `gorm:"type:uuid;not null;index:idx_user_server,unique"`
Role Role `gorm:"type:varchar(20);default:'OPERATOR'"`
IsActive bool `gorm:"default:false"` // Выбран ли этот сервер сейчас
// Персональные данные для подключения (могут быть null у операторов)
Login string `gorm:"type:varchar(100)"`
EncryptedPassword string `gorm:"type:text"`
Server RMSServer `gorm:"foreignKey:ServerID"`
User User `gorm:"foreignKey:UserID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// RMSServer - Инстанс сервера iiko
type RMSServer struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"`
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
Name string `gorm:"type:varchar(100);not null" json:"name"` // Название (напр. "Ресторан на Ленина")
// Уникальный URL (очищенный), определяет инстанс
BaseURL string `gorm:"type:varchar(255);not null;uniqueIndex" json:"base_url"`
// Credentials
BaseURL string `gorm:"type:varchar(255);not null" json:"base_url"`
Login string `gorm:"type:varchar(100);not null" json:"login"`
EncryptedPassword string `gorm:"type:text;not null" json:"-"` // Пароль храним зашифрованным
Name string `gorm:"type:varchar(100);not null" json:"name"`
MaxUsers int `gorm:"default:5" json:"max_users"` // Лимит пользователей
DefaultStoreID *uuid.UUID `gorm:"type:uuid" json:"default_store_id"` // Склад для подстановки
RootGroupGUID *uuid.UUID `gorm:"type:uuid" json:"root_group_guid"` // ID корневой папки для поиска товаров
AutoProcess bool `gorm:"default:false" json:"auto_process"` // Пытаться сразу проводить накладную
// Глобальные настройки сервера (общие для всех)
DefaultStoreID *uuid.UUID `gorm:"type:uuid" json:"default_store_id"`
RootGroupGUID *uuid.UUID `gorm:"type:uuid" json:"root_group_guid"`
AutoProcess bool `gorm:"default:false" json:"auto_process"`
// Billing / Stats
InvoiceCount int `gorm:"default:0" json:"invoice_count"` // Счетчик успешно отправленных накладных
IsActive bool `gorm:"default:true" json:"is_active"`
InvoiceCount int `gorm:"default:0" json:"invoice_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Repository интерфейс управления аккаунтами
// Repository интерфейс
type Repository interface {
// Users
GetOrCreateUser(telegramID int64, username, first, last string) (*User, error)
GetUserByTelegramID(telegramID int64) (*User, error)
// Servers
SaveServer(server *RMSServer) error
// ConnectServer - Основной метод подключения.
// Реализует логику: Новый URL -> Owner, Старый URL -> Operator.
ConnectServer(userID uuid.UUID, url, login, encryptedPass, name string) (*RMSServer, error)
SaveServerSettings(server *RMSServer) error
// SetActiveServer переключает активность в таблице ServerUser
SetActiveServer(userID, serverID uuid.UUID) error
GetActiveServer(userID uuid.UUID) (*RMSServer, error) // Получить активный (первый попавшийся или помеченный)
GetAllServers(userID uuid.UUID) ([]RMSServer, error)
// GetActiveServer ищет сервер, где у UserID стоит флаг IsActive=true
GetActiveServer(userID uuid.UUID) (*RMSServer, error)
// GetActiveConnectionCredentials возвращает актуальные логин/пароль для текущего юзера (личные или общие)
GetActiveConnectionCredentials(userID uuid.UUID) (url, login, passHash string, err error)
// GetAllAvailableServers возвращает все серверы, доступные пользователю (в любом статусе)
GetAllAvailableServers(userID uuid.UUID) ([]RMSServer, error)
DeleteServer(serverID uuid.UUID) error
// Billing
// GetUserRole возвращает роль пользователя на сервере (или ошибку доступа)
GetUserRole(userID, serverID uuid.UUID) (Role, error)
SetUserRole(serverID, targetUserID uuid.UUID, newRole Role) error
GetServerUsers(serverID uuid.UUID) ([]ServerUser, error)
// Invite System
AddUserToServer(serverID, userID uuid.UUID, role Role) error
RemoveUserFromServer(serverID, userID uuid.UUID) error
IncrementInvoiceCount(serverID uuid.UUID) error
// Super Admin Functions
GetAllServersSystemWide() ([]RMSServer, error)
TransferOwnership(serverID, newOwnerID uuid.UUID) error
// GetConnectionByID получает связь ServerUser по её ID (нужно для админки, чтобы сократить callback_data)
GetConnectionByID(id uuid.UUID) (*ServerUser, error)
}

View File

@@ -22,8 +22,8 @@ type DraftInvoice struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
// Привязка к аккаунту и серверу
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"`
RMSServerID uuid.UUID `gorm:"type:uuid;not null;index" json:"rms_server_id"`
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"` // Кто загрузил (автор)
RMSServerID uuid.UUID `gorm:"type:uuid;not null;index" json:"rms_server_id"` // К какому серверу относится
SenderPhotoURL string `gorm:"type:text" json:"photo_url"`
Status string `gorm:"type:varchar(50);default:'PROCESSING'" json:"status"`
@@ -73,5 +73,7 @@ type Repository interface {
CreateItem(item *DraftInvoiceItem) error
DeleteItem(itemID uuid.UUID) error
Delete(id uuid.UUID) error
GetActive(userID uuid.UUID) ([]DraftInvoice, error)
// GetActive возвращает активные черновики для СЕРВЕРА (а не юзера)
GetActive(serverID uuid.UUID) ([]DraftInvoice, error)
}