forked from baron/baron-sso
adminfront 조직 통계오류 보정. Kratos Projection용 통계테이블 구조 추가
This commit is contained in:
@@ -20,14 +20,15 @@ import (
|
||||
)
|
||||
|
||||
type TenantHandler struct {
|
||||
DB *gorm.DB
|
||||
Service service.TenantService
|
||||
UserRepo repository.UserRepository
|
||||
Keto service.KetoService
|
||||
KetoOutbox repository.KetoOutboxRepository
|
||||
KratosAdmin service.KratosAdminService
|
||||
SharedLink service.SharedLinkService
|
||||
Worksmobile service.WorksmobileSyncer
|
||||
DB *gorm.DB
|
||||
Service service.TenantService
|
||||
UserRepo repository.UserRepository
|
||||
UserProjectionRepo repository.UserProjectionRepository
|
||||
Keto service.KetoService
|
||||
KetoOutbox repository.KetoOutboxRepository
|
||||
KratosAdmin service.KratosAdminService
|
||||
SharedLink service.SharedLinkService
|
||||
Worksmobile service.WorksmobileSyncer
|
||||
}
|
||||
|
||||
func seedTenantDeleteError(c *fiber.Ctx) error {
|
||||
@@ -47,15 +48,16 @@ func seedTenantSlugsForDeleteGuard() []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func NewTenantHandler(db *gorm.DB, svc service.TenantService, userRepo repository.UserRepository, keto service.KetoService, outbox repository.KetoOutboxRepository, kratos service.KratosAdminService, sharedLink service.SharedLinkService) *TenantHandler {
|
||||
func NewTenantHandler(db *gorm.DB, svc service.TenantService, userRepo repository.UserRepository, userProjectionRepo repository.UserProjectionRepository, keto service.KetoService, outbox repository.KetoOutboxRepository, kratos service.KratosAdminService, sharedLink service.SharedLinkService) *TenantHandler {
|
||||
return &TenantHandler{
|
||||
DB: db,
|
||||
Service: svc,
|
||||
UserRepo: userRepo,
|
||||
Keto: keto,
|
||||
KetoOutbox: outbox,
|
||||
KratosAdmin: kratos,
|
||||
SharedLink: sharedLink,
|
||||
DB: db,
|
||||
Service: svc,
|
||||
UserRepo: userRepo,
|
||||
UserProjectionRepo: userProjectionRepo,
|
||||
Keto: keto,
|
||||
KetoOutbox: outbox,
|
||||
KratosAdmin: kratos,
|
||||
SharedLink: sharedLink,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,31 +253,15 @@ func (h *TenantHandler) ListTenants(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch member counts for all tenants in one query using IDs
|
||||
tenantIDs := make([]string, 0, len(tenants))
|
||||
slugs := make([]string, 0, len(tenants))
|
||||
for _, t := range tenants {
|
||||
tenantIDs = append(tenantIDs, t.ID)
|
||||
slugs = append(slugs, t.Slug)
|
||||
memberCounts, err := h.countTenantMembersFromProjection(c.Context(), tenants)
|
||||
if err != nil {
|
||||
return errorJSON(c, fiber.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
idCounts, _ := h.UserRepo.CountByTenantIDs(c.Context(), tenantIDs)
|
||||
slugCounts, _ := h.UserRepo.CountByCompanyCodes(c.Context(), slugs)
|
||||
|
||||
items := make([]tenantSummary, 0, len(tenants))
|
||||
for _, t := range tenants {
|
||||
summary := mapTenantSummary(t)
|
||||
|
||||
// Combine counts from both ID and Slug (Max to avoid double counting if some have one or the other)
|
||||
idCount := idCounts[t.ID]
|
||||
slugCount := slugCounts[strings.ToLower(t.Slug)]
|
||||
|
||||
if idCount > slugCount {
|
||||
summary.MemberCount = idCount
|
||||
} else {
|
||||
summary.MemberCount = slugCount
|
||||
}
|
||||
|
||||
summary.MemberCount = memberCounts[t.ID]
|
||||
items = append(items, summary)
|
||||
}
|
||||
|
||||
@@ -939,19 +925,13 @@ func (h *TenantHandler) GetTenant(c *fiber.Ctx) error {
|
||||
return errorJSON(c, fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
idCounts, _ := h.UserRepo.CountByTenantIDs(c.Context(), []string{tenant.ID})
|
||||
slugCounts, _ := h.UserRepo.CountByCompanyCodes(c.Context(), []string{tenant.Slug})
|
||||
|
||||
idCount := idCounts[tenant.ID]
|
||||
slugCount := slugCounts[strings.ToLower(tenant.Slug)]
|
||||
|
||||
count := idCount
|
||||
if slugCount > idCount {
|
||||
count = slugCount
|
||||
memberCounts, err := h.countTenantMembersFromProjection(c.Context(), []domain.Tenant{tenant})
|
||||
if err != nil {
|
||||
return errorJSON(c, fiber.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
summary := mapTenantSummary(tenant)
|
||||
summary.MemberCount = count
|
||||
summary.MemberCount = memberCounts[tenant.ID]
|
||||
|
||||
return c.JSON(summary)
|
||||
}
|
||||
@@ -1595,6 +1575,27 @@ func mapTenantSummary(t domain.Tenant) tenantSummary {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *TenantHandler) countTenantMembersFromProjection(ctx context.Context, tenants []domain.Tenant) (map[string]int64, error) {
|
||||
counts := make(map[string]int64, len(tenants))
|
||||
for _, tenant := range tenants {
|
||||
counts[tenant.ID] = 0
|
||||
}
|
||||
if len(tenants) == 0 {
|
||||
return counts, nil
|
||||
}
|
||||
if h.UserProjectionRepo == nil {
|
||||
return nil, errors.New("user projection is not configured")
|
||||
}
|
||||
ready, err := h.UserProjectionRepo.IsReady(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user projection status unavailable: %w", err)
|
||||
}
|
||||
if !ready {
|
||||
return nil, errors.New("user projection is not ready")
|
||||
}
|
||||
return h.UserProjectionRepo.CountTenantMembers(ctx, tenants)
|
||||
}
|
||||
|
||||
func normalizeTenantStatus(value string) string {
|
||||
value = strings.ToLower(strings.TrimSpace(value))
|
||||
if value == "" {
|
||||
|
||||
Reference in New Issue
Block a user