package domain import ( "time" "github.com/google/uuid" "gorm.io/gorm" ) // Tenant statuses const ( TenantStatusPending = "pending" TenantStatusActive = "active" TenantStatusSuspended = "suspended" TenantStatusDeleted = "deleted" ) // Tenant represents a tenant model stored in PostgreSQL. type Tenant struct { ID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid()" json:"id"` ParentID *string `gorm:"type:uuid;index" json:"parentId,omitempty"` // 부모 테넌트 ID TenantGroupID *string `gorm:"type:uuid;index" json:"tenantGroupId,omitempty"` TenantGroup *TenantGroup `gorm:"foreignKey:TenantGroupID" json:"tenantGroup,omitempty"` Name string `gorm:"not null" json:"name"` Slug string `gorm:"uniqueIndex;not null" json:"slug"` Description string `json:"description"` Status string `gorm:"default:'pending'" json:"status"` Domains []TenantDomain `gorm:"foreignKey:TenantID" json:"domains,omitempty"` Config JSONMap `gorm:"type:jsonb" json:"config,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` } func (t *Tenant) IsActive() bool { return t.Status == TenantStatusActive } // GetMergedConfig merges the group-level config with tenant-level config. // Tenant config takes precedence. func (t *Tenant) GetMergedConfig() JSONMap { merged := make(JSONMap) // 1. Apply Group Config (Base) if t.TenantGroup != nil && t.TenantGroup.Config != nil { for k, v := range t.TenantGroup.Config { merged[k] = v } } // 2. Apply Tenant Config (Overrides) if t.Config != nil { for k, v := range t.Config { merged[k] = v } } return merged } // BeforeCreate hook to generate UUID if not present. func (t *Tenant) BeforeCreate(tx *gorm.DB) (err error) { if t.ID == "" { t.ID = uuid.NewString() } return }