refactor:项目架构重构和命名规范化

- 统一文件命名为snake_case格式(kebab-case  snake_case)
- 重构zulip模块为zulip_core,明确Core层职责
- 重构user-mgmt模块为user_mgmt,统一命名规范
- 调整模块依赖关系,优化架构分层
- 删除过时的文件和目录结构
- 更新相关文档和配置文件

本次重构涉及大量文件重命名和模块重组,
旨在建立更清晰的项目架构和统一的命名规范。
This commit is contained in:
moyin
2026-01-08 00:14:14 +08:00
parent 4fa4bd1a70
commit bb796a2469
178 changed files with 24767 additions and 3484 deletions

View File

@@ -1,8 +1,9 @@
import { NotFoundException } from '@nestjs/common';
import { NotFoundException, BadRequestException } from '@nestjs/common';
import { AdminService } from './admin.service';
import { AdminCoreService } from '../../core/admin_core/admin_core.service';
import { LogManagementService } from '../../core/utils/logger/log_management.service';
import { Users } from '../../core/db/users/users.entity';
import { UserStatus } from '../user_mgmt/user_status.enum';
describe('AdminService', () => {
let service: AdminService;
@@ -15,6 +16,7 @@ describe('AdminService', () => {
const usersServiceMock = {
findAll: jest.fn(),
findOne: jest.fn(),
update: jest.fn(),
};
const logManagementServiceMock: Pick<LogManagementService, 'getRuntimeLogTail' | 'getLogDirAbsolutePath'> = {
@@ -156,4 +158,111 @@ describe('AdminService', () => {
expect(service.getLogDirAbsolutePath()).toBe('/abs/logs');
expect(logManagementServiceMock.getLogDirAbsolutePath).toHaveBeenCalled();
});
// 测试新增的用户状态管理方法
describe('updateUserStatus', () => {
const mockUser = {
id: BigInt(1),
username: 'testuser',
status: UserStatus.ACTIVE
} as unknown as Users;
it('should update user status successfully', async () => {
usersServiceMock.findOne.mockResolvedValue(mockUser);
usersServiceMock.update.mockResolvedValue({ ...mockUser, status: UserStatus.INACTIVE });
const result = await service.updateUserStatus(BigInt(1), { status: UserStatus.INACTIVE, reason: 'test' });
expect(result.success).toBe(true);
expect(result.message).toBe('用户状态修改成功');
});
it('should throw NotFoundException when user not found', async () => {
usersServiceMock.findOne.mockResolvedValue(null);
await expect(service.updateUserStatus(BigInt(999), { status: UserStatus.INACTIVE, reason: 'test' }))
.rejects.toThrow(NotFoundException);
});
it('should return error when status unchanged', async () => {
usersServiceMock.findOne.mockResolvedValue({ ...mockUser, status: UserStatus.INACTIVE });
await expect(service.updateUserStatus(BigInt(1), { status: UserStatus.INACTIVE, reason: 'test' }))
.rejects.toThrow(BadRequestException);
});
});
describe('batchUpdateUserStatus', () => {
it('should batch update user status successfully', async () => {
const mockUsers = [
{ id: BigInt(1), username: 'user1', status: UserStatus.ACTIVE },
{ id: BigInt(2), username: 'user2', status: UserStatus.ACTIVE }
] as unknown as Users[];
usersServiceMock.findOne
.mockResolvedValueOnce(mockUsers[0])
.mockResolvedValueOnce(mockUsers[1]);
usersServiceMock.update
.mockResolvedValueOnce({ ...mockUsers[0], status: UserStatus.INACTIVE })
.mockResolvedValueOnce({ ...mockUsers[1], status: UserStatus.INACTIVE });
const result = await service.batchUpdateUserStatus({
userIds: ['1', '2'],
status: UserStatus.INACTIVE,
reason: 'batch test'
});
expect(result.success).toBe(true);
expect(result.data?.result.success_count).toBe(2);
expect(result.data?.result.failed_count).toBe(0);
});
it('should handle mixed success and failure', async () => {
usersServiceMock.findOne
.mockResolvedValueOnce({ id: BigInt(1), status: UserStatus.ACTIVE })
.mockResolvedValueOnce(null); // User not found
usersServiceMock.update.mockResolvedValueOnce({ id: BigInt(1), status: UserStatus.INACTIVE });
const result = await service.batchUpdateUserStatus({
userIds: ['1', '999'],
status: UserStatus.INACTIVE,
reason: 'mixed test'
});
expect(result.success).toBe(true);
expect(result.data?.result.success_count).toBe(1);
expect(result.data?.result.failed_count).toBe(1);
});
});
describe('getUserStatusStats', () => {
it('should return user status statistics', async () => {
const mockUsers = [
{ status: UserStatus.ACTIVE },
{ status: UserStatus.ACTIVE },
{ status: UserStatus.INACTIVE },
{ status: null } // Should default to active
] as unknown as Users[];
usersServiceMock.findAll.mockResolvedValue(mockUsers);
const result = await service.getUserStatusStats();
expect(result.success).toBe(true);
expect(result.data?.stats.active).toBe(3); // 2 active + 1 null (defaults to active)
expect(result.data?.stats.inactive).toBe(1);
expect(result.data?.stats.total).toBe(4);
});
it('should handle error when getting stats', async () => {
usersServiceMock.findAll.mockRejectedValue(new Error('Database error'));
const result = await service.getUserStatusStats();
expect(result.success).toBe(false);
expect(result.error_code).toBe('USER_STATUS_STATS_FAILED');
});
});
});