From 36258bf53cc17051e11526f3a2de5ce4fdf92a58 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Mon, 23 Mar 2026 00:11:03 +0100 Subject: [PATCH] Sort domains alphabetically - GetAllDomains: order by name ASC - GetUserAccessibleDomains: order by name ASC for both admin and regular users --- backend/internal/api/handlers/users.go | 2 ++ backend/internal/db/db.go | 13 ++++++------- backend/internal/db/domains.go | 2 +- backend/internal/db/imc_users.go | 3 ++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/backend/internal/api/handlers/users.go b/backend/internal/api/handlers/users.go index c8cbdb7..3571c3e 100644 --- a/backend/internal/api/handlers/users.go +++ b/backend/internal/api/handlers/users.go @@ -1,6 +1,7 @@ package handlers import ( + "log" "net/http" "strconv" @@ -138,6 +139,7 @@ func (h *UserHandler) Create(c *gin.Context) { user, err := h.db.CreateUserInDomain(req.Email, passwordHash, req.Quota, domain.ID) if err != nil { + log.Printf("CreateUserInDomain error: email=%s, domain=%s, err=%v", req.Email, domainName, err) Error(c, http.StatusInternalServerError, "failed to create user") return } diff --git a/backend/internal/db/db.go b/backend/internal/db/db.go index 3b17ad5..0106612 100644 --- a/backend/internal/db/db.go +++ b/backend/internal/db/db.go @@ -44,13 +44,12 @@ func (Domain) TableName() string { return "virtual_domains" } // User represents a mail user (e.g., "user@example.org"). // This corresponds to the existing ISPmail virtual_users table. type User struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - DomainID uint `gorm:"not null" json:"domainId"` // Foreign key to Domain - Email string `gorm:"uniqueIndex;size:100;not null" json:"email"` // Full email address, must be unique - Password string `gorm:"size:150;not null" json:"-"` // Mailbox password (bcrypt hash, - means exclude from JSON) - Quota int64 `gorm:"default:0" json:"quota"` // Mailbox size limit in bytes (0 = default) - Domain *Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"` // Associated domain - CreatedAt time.Time `json:"createdAt,omitempty"` // When the user was created + ID uint `gorm:"primaryKey" json:"id"` // Primary key + DomainID uint `gorm:"not null" json:"domainId"` // Foreign key to Domain + Email string `gorm:"uniqueIndex;size:100;not null" json:"email"` // Full email address, must be unique + Password string `gorm:"size:150;not null" json:"-"` // Mailbox password (bcrypt hash, - means exclude from JSON) + Quota int64 `gorm:"default:0" json:"quota"` // Mailbox size limit in bytes (0 = default) + Domain *Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"` // Associated domain } // TableName tells GORM to use the existing ISPmail table name. diff --git a/backend/internal/db/domains.go b/backend/internal/db/domains.go index f3b797b..5ccd230 100644 --- a/backend/internal/db/domains.go +++ b/backend/internal/db/domains.go @@ -2,7 +2,7 @@ package db func (d *DB) GetAllDomains() ([]DomainStats, error) { var domains []Domain - if err := d.Find(&domains).Error; err != nil { + if err := d.Order("name ASC").Find(&domains).Error; err != nil { return nil, err } diff --git a/backend/internal/db/imc_users.go b/backend/internal/db/imc_users.go index 2d46e43..98d7c22 100644 --- a/backend/internal/db/imc_users.go +++ b/backend/internal/db/imc_users.go @@ -99,7 +99,7 @@ func (d *DB) GetUserAccessibleDomains(userID uint, isAdmin bool) ([]Domain, erro // Admins get access to all domains. if isAdmin { var domains []Domain - if err := d.Find(&domains).Error; err != nil { + if err := d.Order("name ASC").Find(&domains).Error; err != nil { return nil, err } return domains, nil @@ -113,6 +113,7 @@ func (d *DB) GetUserAccessibleDomains(userID uint, isAdmin bool) ([]Domain, erro Select("virtual_domains.*"). // Select all columns from domains Joins("JOIN virtual_domains ON virtual_domains.id = imc_users2domains.domain_id"). // Join to get domain details Where("imc_users2domains.user_id = ?", userID). // Only this user's domains + Order("name ASC"). Find(&domains).Error if err != nil { return nil, err