1
0
forked from baron/baron-sso

조직현황 구조변경. 총괄센터삼안 실 조직 삽입확인

This commit is contained in:
2026-05-11 20:13:54 +09:00
parent d3853fac2a
commit 3063450ee0
59 changed files with 5086 additions and 549 deletions

View File

@@ -144,6 +144,27 @@ func metadataBoolFromMap(metadata map[string]any, keys ...string) (bool, bool) {
return false, false
}
func roleFromTraits(traits map[string]interface{}) string {
if role, ok := domain.NormalizeRoleAlias(extractTraitString(traits, "role")); ok {
return role
}
if role, ok := domain.NormalizeRoleAlias(extractTraitString(traits, "grade")); ok {
return role
}
return domain.RoleUser
}
func gradeFromTraits(traits map[string]interface{}) string {
value := strings.TrimSpace(extractTraitString(traits, "grade"))
if value == "" {
return ""
}
if _, ok := domain.NormalizeRoleAlias(value); ok {
return ""
}
return value
}
type userSummary struct {
ID string `json:"id"`
Email string `json:"email"`
@@ -158,6 +179,7 @@ type userSummary struct {
Tenant *domain.Tenant `json:"tenant,omitempty"`
JoinedTenants []domain.Tenant `json:"joinedTenants,omitempty"` // [New] 다중 소속 테넌트 목록
Department string `json:"department"`
Grade string `json:"grade"`
Position string `json:"position"`
JobTitle string `json:"jobTitle"`
CreatedAt string `json:"createdAt"`
@@ -429,6 +451,7 @@ func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
Role string `json:"role"`
CompanyCode string `json:"companyCode"`
Department string `json:"department"`
Grade string `json:"grade"`
Position string `json:"position"`
JobTitle string `json:"jobTitle"`
PrimaryTenantID string `json:"primaryTenantId"`
@@ -488,11 +511,11 @@ func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
attributes := map[string]interface{}{
"department": req.Department,
"grade": strings.TrimSpace(req.Grade),
"position": req.Position,
"jobTitle": req.JobTitle,
"affiliationType": "internal",
"companyCode": req.CompanyCode,
"grade": role,
}
// [Override with explicit LoginID if provided]
@@ -648,6 +671,7 @@ type bulkUserItem struct {
Role string `json:"role"`
TenantSlug string `json:"tenantSlug"`
Department string `json:"department"`
Grade string `json:"grade"`
Position string `json:"position"`
JobTitle string `json:"jobTitle"`
Metadata map[string]any `json:"metadata"`
@@ -820,12 +844,12 @@ func (h *UserHandler) BulkCreateUsers(c *fiber.Ctx) error {
attributes := map[string]interface{}{
"department": dept,
"grade": strings.TrimSpace(item.Grade),
"position": strings.TrimSpace(item.Position),
"jobTitle": strings.TrimSpace(item.JobTitle),
"affiliationType": "internal",
"companyCode": tenantSlug,
"tenant_id": tItem.ID,
"grade": role,
"role": role,
}
@@ -889,6 +913,7 @@ func (h *UserHandler) BulkCreateUsers(c *fiber.Ctx) error {
Status: "active",
CompanyCode: tenantSlug,
Department: dept,
Grade: strings.TrimSpace(item.Grade),
AffiliationType: "internal",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
@@ -1059,9 +1084,9 @@ func (h *UserHandler) ExportUsersCSV(c *fiber.Ctx) error {
// Header row
includeIDs := includeCSVIds(c)
header := []string{"Email", "Name", "Phone", "Status", "tenant_slug", "Position", "JobTitle", "CreatedAt"}
header := []string{"Email", "Name", "Phone", "Status", "tenant_slug", "Grade", "Position", "JobTitle", "CreatedAt"}
if includeIDs {
header = []string{"user_id", "Email", "Name", "Phone", "Status", "tenant_id", "tenant_slug", "Position", "JobTitle", "CreatedAt"}
header = []string{"user_id", "Email", "Name", "Phone", "Status", "tenant_id", "tenant_slug", "Grade", "Position", "JobTitle", "CreatedAt"}
}
// Collect all possible metadata keys for dynamic columns
@@ -1096,6 +1121,7 @@ func (h *UserHandler) ExportUsersCSV(c *fiber.Ctx) error {
u.Phone,
u.Status,
u.CompanyCode,
u.Grade,
u.Position,
u.JobTitle,
u.CreatedAt.Format(time.RFC3339),
@@ -1109,6 +1135,7 @@ func (h *UserHandler) ExportUsersCSV(c *fiber.Ctx) error {
u.Status,
tenantID,
u.CompanyCode,
u.Grade,
u.Position,
u.JobTitle,
u.CreatedAt.Format(time.RFC3339),
@@ -1142,6 +1169,7 @@ func (h *UserHandler) BulkUpdateUsers(c *fiber.Ctx) error {
Role *string `json:"role"`
CompanyCode *string `json:"companyCode"`
Department *string `json:"department"`
Grade *string `json:"grade"`
Position *string `json:"position"`
JobTitle *string `json:"jobTitle"`
}
@@ -1233,6 +1261,9 @@ func (h *UserHandler) BulkUpdateUsers(c *fiber.Ctx) error {
if req.Department != nil {
traits["department"] = *req.Department
}
if req.Grade != nil {
traits["grade"] = *req.Grade
}
if req.Position != nil {
traits["position"] = *req.Position
}
@@ -1258,7 +1289,7 @@ func (h *UserHandler) BulkUpdateUsers(c *fiber.Ctx) error {
// Sync to local DB
if h.UserRepo != nil {
localUser := h.mapToLocalUser(*identity)
oldRole := extractTraitString(identity.Traits, "grade")
oldRole := roleFromTraits(identity.Traits)
oldTenantID := extractTraitString(identity.Traits, "tenant_id")
if req.Role != nil {
@@ -1437,6 +1468,7 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
IsAddTenant bool `json:"isAddTenant"`
IsRemoveTenant bool `json:"isRemoveTenant"`
Department *string `json:"department"`
Grade *string `json:"grade"`
Position *string `json:"position"`
JobTitle *string `json:"jobTitle"`
PrimaryTenantID string `json:"primaryTenantId"`
@@ -1658,6 +1690,9 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
if req.Department != nil {
traits["department"] = strings.TrimSpace(*req.Department)
}
if req.Grade != nil {
traits["grade"] = strings.TrimSpace(*req.Grade)
}
if req.Position != nil {
traits["position"] = strings.TrimSpace(*req.Position)
}
@@ -1669,7 +1704,6 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
if role == "" {
role = domain.RoleUser
}
traits["grade"] = role
traits["role"] = role
}
@@ -1757,7 +1791,7 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
go func() {
bgCtx := context.Background()
h.syncKetoRole(bgCtx, updatedLocalUser.ID,
extractTraitString(updated.Traits, "grade"), oldRole, oldTenantID, updatedLocalUser.TenantID)
roleFromTraits(updated.Traits), oldRole, oldTenantID, updatedLocalUser.TenantID)
// Try to automatically sync UserGroup membership based on Department
if h.UserGroupRepo != nil && h.KetoOutboxRepo != nil {
@@ -1911,14 +1945,7 @@ func (h *UserHandler) DeleteUser(c *fiber.Ctx) error {
func (h *UserHandler) mapIdentitySummary(ctx context.Context, identity service.KratosIdentity) userSummary {
traits := identity.Traits
role := extractTraitString(traits, "grade")
if role == "" {
role = extractTraitString(traits, "role")
}
role = domain.NormalizeRole(role)
if role == "" {
role = domain.RoleUser
}
role := roleFromTraits(traits)
compCode := extractTraitString(traits, "companyCode")
slog.Debug("Mapping identity", "email", extractTraitString(traits, "email"), "compCode", compCode)
@@ -1947,6 +1974,7 @@ func (h *UserHandler) mapIdentitySummary(ctx context.Context, identity service.K
Status: normalizeStatus(identity.State),
CompanyCode: compCode,
Department: extractTraitString(traits, "department"),
Grade: gradeFromTraits(traits),
Position: extractTraitString(traits, "position"),
JobTitle: extractTraitString(traits, "jobTitle"),
Metadata: make(domain.JSONMap),
@@ -1997,14 +2025,7 @@ func (h *UserHandler) normalizePhoneNumber(phone string) string {
func (h *UserHandler) mapToLocalUser(identity service.KratosIdentity) *domain.User {
traits := identity.Traits
role := extractTraitString(traits, "grade")
if role == "" {
role = extractTraitString(traits, "role")
}
role = domain.NormalizeRole(role)
if role == "" {
role = domain.RoleUser
}
role := roleFromTraits(traits)
compCode := extractTraitString(traits, "companyCode")
if compCode == "" {
compCode = extractTraitString(traits, "company_code")
@@ -2019,6 +2040,7 @@ func (h *UserHandler) mapToLocalUser(identity service.KratosIdentity) *domain.Us
Status: normalizeStatus(identity.State),
CompanyCode: compCode,
Department: extractTraitString(traits, "department"),
Grade: gradeFromTraits(traits),
Position: extractTraitString(traits, "position"),
JobTitle: extractTraitString(traits, "jobTitle"),
AffiliationType: extractTraitString(traits, "affiliationType"),