package domain import ( "strings" "time" "github.com/google/uuid" "gorm.io/gorm" ) // User roles const ( RoleSuperAdmin = "super_admin" // 시스템 전역 관리자 RoleTenantAdmin = "tenant_admin" // 테넌트 관리자 RoleRPAdmin = "rp_admin" // 특정 앱(RP) 관리자 RoleUser = "user" // 일반 사용자 ) // NormalizeRole maps legacy/synonym role values to canonical role keys. func NormalizeRole(role string) string { normalized := strings.ToLower(strings.TrimSpace(role)) switch normalized { case "tenant_member": return RoleUser case "admin": // Legacy admin is treated as tenant admin for least-privilege compatibility. return RoleTenantAdmin default: return normalized } } // User represents the user model stored in PostgreSQL type User struct { ID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid()" json:"id"` Email string `gorm:"uniqueIndex;not null" json:"email"` PasswordHash *string `gorm:"column:password_hash" json:"-"` Name string `gorm:"column:name;not null" json:"name"` Phone string `gorm:"column:phone" json:"phone"` Role string `gorm:"column:role;default:'user';not null" json:"role"` // super_admin, tenant_admin, rp_admin, user AffiliationType string `gorm:"column:affiliation_type" json:"affiliationType"` CompanyCode string `gorm:"column:company_code;index" json:"companyCode"` TenantID *string `gorm:"column:tenant_id;type:uuid;index" json:"tenantId,omitempty"` Tenant *Tenant `gorm:"foreignKey:TenantID" json:"tenant,omitempty"` RelyingPartyID *string `gorm:"column:relying_party_id;type:uuid;index" json:"relyingPartyId,omitempty"` // RP Admin용 Department string `gorm:"column:department" json:"department"` Position string `gorm:"column:position" json:"position"` // 직급 (예: 수석, 책임, 선임) JobTitle string `gorm:"column:job_title" json:"jobTitle"` // 직무 (예: 프론트엔드 개발, 기획) Metadata JSONMap `gorm:"column:metadata;type:jsonb" json:"metadata,omitempty"` Status string `gorm:"column:status;default:'active'" json:"status"` CreatedAt time.Time `gorm:"column:created_at" json:"createdAt"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updatedAt"` DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"-"` } // BeforeCreate hook to generate UUID if not present func (u *User) BeforeCreate(tx *gorm.DB) (err error) { if u.ID == "" { u.ID = uuid.New().String() } return }