forked from baron/baron-sso
perf(admin): full-stack performance optimization for all list tables
- Implemented server-side search, infinite scrolling, and list virtualization for Tenants, Users, and Audit Logs. - Backend: Enhanced Repository, Service, and Handler layers to support 'search' and 'cursor' parameters. - Frontend: Integrated @tanstack/react-virtual and useInfiniteQuery for high-performance rendering. - Quality: Updated all unit tests and E2E tests to match the new asynchronous server-side search architecture. - i18n: Synced all translation keys and cleaned up unused resources.
This commit is contained in:
@@ -291,8 +291,8 @@ func (m *MockTenantServiceForUser) ListManageableTenants(ctx context.Context, us
|
||||
return args.Get(0).([]domain.Tenant), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockTenantServiceForUser) ListTenants(ctx context.Context, limit, offset int, parentID string) ([]domain.Tenant, int64, error) {
|
||||
args := m.Called(ctx, limit, offset, parentID)
|
||||
func (m *MockTenantServiceForUser) ListTenants(ctx context.Context, limit, offset int, parentID string, search string) ([]domain.Tenant, int64, error) {
|
||||
args := m.Called(ctx, limit, offset, parentID, search)
|
||||
if args.Get(0) == nil {
|
||||
return nil, args.Get(1).(int64), args.Error(2)
|
||||
}
|
||||
@@ -332,7 +332,7 @@ func TestUserHandler_ExportUsersCSV_UsesTenantSlugAliasAndOmitsRole(t *testing.T
|
||||
|
||||
createdAt := time.Date(2026, 4, 29, 12, 0, 0, 0, time.UTC)
|
||||
tenantID := "tenant-uuid"
|
||||
mockRepo.On("List", mock.Anything, 0, 10000, "", "test-tenant").
|
||||
mockRepo.On("List", mock.Anything, 0, 10000, "", []string(nil), "").
|
||||
Return([]domain.User{
|
||||
{
|
||||
ID: "u-1",
|
||||
@@ -349,7 +349,7 @@ func TestUserHandler_ExportUsersCSV_UsesTenantSlugAliasAndOmitsRole(t *testing.T
|
||||
JobTitle: "플랫폼 운영",
|
||||
CreatedAt: createdAt,
|
||||
},
|
||||
}, int64(1), nil).Maybe()
|
||||
}, int64(1), "", nil).Maybe()
|
||||
|
||||
req := httptest.NewRequest("GET", "/users/export?tenantSlug=test-tenant&includeIds=true", nil)
|
||||
resp, err := app.Test(req)
|
||||
@@ -380,7 +380,7 @@ func TestUserHandler_ExportUsersCSV_OmitsIDsAndUsesTenantSlug(t *testing.T) {
|
||||
|
||||
createdAt := time.Date(2026, 4, 29, 12, 0, 0, 0, time.UTC)
|
||||
tenantID := "tenant-uuid"
|
||||
mockRepo.On("List", mock.Anything, 0, 10000, "", "").
|
||||
mockRepo.On("List", mock.Anything, 0, 10000, "", mock.Anything, "").
|
||||
Return([]domain.User{
|
||||
{
|
||||
ID: "user-uuid",
|
||||
@@ -395,7 +395,7 @@ func TestUserHandler_ExportUsersCSV_OmitsIDsAndUsesTenantSlug(t *testing.T) {
|
||||
JobTitle: "플랫폼 운영",
|
||||
CreatedAt: createdAt,
|
||||
},
|
||||
}, int64(1), nil).Maybe()
|
||||
}, int64(1), "", nil).Maybe()
|
||||
|
||||
req := httptest.NewRequest("GET", "/users/export?includeIds=false", nil)
|
||||
resp, err := app.Test(req)
|
||||
@@ -1049,7 +1049,7 @@ func TestUserHandler_BulkCreateUsers_HanmacEmailPolicy(t *testing.T) {
|
||||
Slug: "hanmac",
|
||||
ParentID: &rootID,
|
||||
}, nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "").Return(tenants, int64(len(tenants)), nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "", "").Return(tenants, int64(len(tenants)), nil).Maybe()
|
||||
mockRepo.On("FindByTenantIDs", mock.Anything, []string{rootID, companyID, "external-id"}).Return([]domain.User{
|
||||
{Email: "cyhan@hanmaceng.co.kr", CompanyCode: "hanmac", TenantID: &companyID},
|
||||
{Email: "cyhan1@samaneng.com", CompanyCode: "hanmac", TenantID: &companyID},
|
||||
@@ -1117,7 +1117,7 @@ func TestUserHandler_BulkCreateUsers_HanmacEmailPolicy(t *testing.T) {
|
||||
|
||||
mockTenant.On("GetTenantBySlug", mock.Anything, "h-company").Return(&hTenants[1], nil).Maybe()
|
||||
mockTenant.On("GetTenant", mock.Anything, hCompanyID).Return(&hTenants[1], nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "").Return(hTenants, int64(len(hTenants)), nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "", "").Return(hTenants, int64(len(hTenants)), nil).Maybe()
|
||||
|
||||
mockRepo.On("FindByTenantIDs", mock.Anything, mock.MatchedBy(func(ids []string) bool {
|
||||
return slices.Contains(ids, hRootID) || slices.Contains(ids, hCompanyID)
|
||||
@@ -1188,7 +1188,7 @@ func TestUserHandler_CreateUser_HanmacEmailPolicyBlocksDuplicateLocalPart(t *tes
|
||||
ID: companyID,
|
||||
Slug: "hanmac",
|
||||
}, nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "").Return(tenants, int64(len(tenants)), nil).Maybe()
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "", "").Return(tenants, int64(len(tenants)), nil).Maybe()
|
||||
mockRepo.On("FindByTenantIDs", mock.Anything, []string{rootID, companyID}).Return([]domain.User{
|
||||
{Email: "han@hanmaceng.co.kr", CompanyCode: "hanmac", TenantID: &companyID},
|
||||
}, nil).Maybe()
|
||||
@@ -2146,7 +2146,7 @@ func TestUserHandler_CreateUser_UsesAdditionalAppointmentAsPrimaryTenant(t *test
|
||||
ID: tenantID,
|
||||
Slug: "saman",
|
||||
}, nil)
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "").Return([]domain.Tenant{}, int64(0), nil)
|
||||
mockTenant.On("ListTenants", mock.Anything, 10000, 0, "", "").Return([]domain.Tenant{}, int64(0), nil)
|
||||
mockOry.On("GetPasswordPolicy").Return(&domain.PasswordPolicy{MinLength: 8}, nil)
|
||||
mockOry.On("CreateUser", mock.Anything, mock.Anything).Return("some-id", nil).Maybe()
|
||||
mockKratos.On("GetIdentity", mock.Anything, "some-id").Return(&service.KratosIdentity{
|
||||
|
||||
Reference in New Issue
Block a user