1
0
forked from baron/baron-sso

사용자 테넌트 소속 데이터 정리

This commit is contained in:
2026-05-13 18:23:39 +09:00
parent 8a6e41d74c
commit e36a973053
26 changed files with 348 additions and 387 deletions

View File

@@ -5,7 +5,6 @@ import (
"context"
"strings"
"github.com/lib/pq"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
@@ -152,33 +151,25 @@ func (r *userRepository) CountByCompanyCodes(ctx context.Context, codes []string
}
type result struct {
CompanyCode string
Count int64
TenantSlug string
Count int64
}
var results []result
lowerCodes := lowerStrings(codes)
// Combine singular company_code and array company_codes using a subquery
// to ensure we count each user accurately per company code they belong to.
query := `
SELECT LOWER(comp_code) as company_code, count(DISTINCT id) as count
FROM (
SELECT id, company_code as comp_code FROM users WHERE deleted_at IS NULL AND LOWER(company_code) = ANY($1)
UNION ALL
SELECT id, unnest(company_codes) as comp_code FROM users WHERE deleted_at IS NULL AND company_codes IS NOT NULL
) as combined
WHERE LOWER(comp_code) = ANY($1)
GROUP BY LOWER(comp_code)
`
err := r.db.WithContext(ctx).Raw(query, pq.Array(lowerCodes)).Scan(&results).Error
if err != nil {
if err := r.db.WithContext(ctx).Table("users").
Select("LOWER(tenants.slug) AS tenant_slug, count(DISTINCT users.id) AS count").
Joins("JOIN tenants ON users.tenant_id = tenants.id").
Where("users.deleted_at IS NULL AND LOWER(tenants.slug) IN ?", lowerCodes).
Group("LOWER(tenants.slug)").
Scan(&results).Error; err != nil {
return nil, err
}
counts := make(map[string]int64)
for _, res := range results {
counts[strings.ToLower(res.CompanyCode)] = res.Count
counts[strings.ToLower(res.TenantSlug)] = res.Count
}
// Ensure all requested codes are present in results (even if count is 0)
@@ -207,13 +198,13 @@ func (r *userRepository) List(ctx context.Context, offset, limit int, search str
if tenantSlug != "" {
db = db.Joins("LEFT JOIN tenants ON users.tenant_id = tenants.id").
Where("users.company_code = ? OR ? = ANY(users.company_codes) OR tenants.slug = ?", tenantSlug, tenantSlug, tenantSlug)
Where("tenants.slug = ?", tenantSlug)
}
if search != "" {
searchTerm := "%" + search + "%"
db = db.Where("(users.email LIKE ? OR users.name LIKE ? OR users.company_code LIKE ? OR ? = ANY(users.company_codes) OR users.metadata::text LIKE ?)",
searchTerm, searchTerm, searchTerm, search, searchTerm)
db = db.Where("(users.email LIKE ? OR users.name LIKE ? OR users.metadata::text LIKE ?)",
searchTerm, searchTerm, searchTerm)
}
if err := db.Count(&total).Error; err != nil {
@@ -281,6 +272,10 @@ func (r *userRepository) FindByTenantIDs(ctx context.Context, tenantIDs []string
func (r *userRepository) FindByCompanyCodes(ctx context.Context, codes []string) ([]domain.User, error) {
var users []domain.User
err := r.db.WithContext(ctx).Where("company_code IN ?", codes).Find(&users).Error
err := r.db.WithContext(ctx).
Joins("JOIN tenants ON users.tenant_id = tenants.id").
Where("LOWER(tenants.slug) IN ?", lowerStrings(codes)).
Preload("Tenant").
Find(&users).Error
return users, err
}