Skip to content

Commit 77f914d

Browse files
committed
refactor(user): separate profile and settings logic / bump bug with imports
1 parent cf9ad22 commit 77f914d

9 files changed

Lines changed: 105 additions & 66 deletions

File tree

src/modules/auth/controller/recovery.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ApiBaseController } from '../../../shared/decorators';
22
import { Body, Post } from '@nestjs/common';
3-
import { AuthService } from '../services';
3+
import { AuthRecoveryService } from '../services';
44
import {
55
PostPasswordResetConfirmSwagger,
66
PostPasswordResetSwagger,
@@ -10,7 +10,7 @@ import { PasswordResetConfirmDto, ResetPasswordDto, VerifyResetCodeDto } from '.
1010

1111
@ApiBaseController('auth', 'Auth Recovery')
1212
export class AuthRecoveryController {
13-
constructor(private readonly facade: AuthService) {}
13+
constructor(private readonly facade: AuthRecoveryService) {}
1414

1515
@Post('password/reset')
1616
@PostPasswordResetSwagger()

src/modules/teams/controller/me.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Get, Query } from '@nestjs/common';
44
import { FindInvitesSwagger, FindTeamsSwagger } from './teams.swagger';
55
import type { JwtPayload } from '@core/modules/auth/types';
66

7-
@ApiBaseController('users/me', 'User Context in Teams', true)
7+
@ApiBaseController('users/me', 'Account Teams', true)
88
export class MeController {
99
constructor(private readonly facade: MeService) {}
1010

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { UserController } from './user.controller';
2+
export { UserSettingsController } from './settings.controller';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Body, Patch, UseGuards } from '@nestjs/common';
2+
import { UserSettingsService } from '../services';
3+
import { PatchMeNotificationsSwagger } from './user.swagger';
4+
import type { UpdateNotificationsDto } from '../dtos';
5+
import { ApiBaseController, GetUserId } from '../../../shared/decorators';
6+
import { BearerAuthGuard } from '@shared/guards';
7+
8+
@ApiBaseController('users/me', 'Account Settings')
9+
@UseGuards(BearerAuthGuard)
10+
export class UserSettingsController {
11+
constructor(private readonly facade: UserSettingsService) {}
12+
13+
@Patch('notifications')
14+
@PatchMeNotificationsSwagger()
15+
async updateNotifications(@Body() settings: UpdateNotificationsDto, @GetUserId() id: string) {
16+
return this.facade.updateNotifications(id, settings);
17+
}
18+
}

src/modules/user/controller/user.controller.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,41 @@
11
import { Body, Get, Patch, Post, Query, UseGuards } from '@nestjs/common';
2-
import { UserService } from '../user.service';
2+
import { UserService } from '../services';
33
import {
44
GetMeActivitySwagger,
55
GetMeSwagger,
6-
PatchMeNotificationsSwagger,
76
PatchMeSwagger,
87
PostMeAvatarSwagger,
98
} from './user.swagger';
10-
import { UpdateNotificationsDto, UpdateProfileDto } from '../dtos';
9+
import type { UpdateProfileDto } from '../dtos';
1110
import { ApiBaseController, ExtractFastifyFile, GetUserId } from '../../../shared/decorators';
1211
import { BearerAuthGuard } from '@shared/guards';
13-
import { PaginationDto } from '../../../shared/dtos';
14-
import { FileUploadDto } from '../../media/dtos';
12+
import type { PaginationDto } from '../../../shared/dtos';
13+
import type { FileUploadDto } from '../../media/dtos';
1514

16-
@ApiBaseController('users', 'Users')
15+
@ApiBaseController('users/me', 'Account Profile')
1716
@UseGuards(BearerAuthGuard)
1817
export class UserController {
1918
constructor(private readonly facade: UserService) {}
2019

21-
@Get('me')
20+
@Get()
2221
@GetMeSwagger()
2322
async getProfile(@GetUserId() id: string) {
2423
return this.facade.getProfile(id);
2524
}
2625

27-
@Patch('me')
26+
@Patch()
2827
@PatchMeSwagger()
2928
async updateProfile(@Body() dto: UpdateProfileDto, @GetUserId() id: string) {
3029
return this.facade.updateProfile(id, dto);
3130
}
3231

33-
@Patch('me/notifications')
34-
@PatchMeNotificationsSwagger()
35-
async updateNotifications(@Body() settings: UpdateNotificationsDto, @GetUserId() id: string) {
36-
return this.facade.updateNotifications(id, settings);
37-
}
38-
39-
@Get('me/activity')
32+
@Get('activity')
4033
@GetMeActivitySwagger()
4134
async getActivity(@Query() query: PaginationDto, @GetUserId() id: string) {
4235
return this.facade.getActivity(id, query.page, query.limit);
4336
}
4437

45-
@Post('me/avatar')
38+
@Post('avatar')
4639
@PostMeAvatarSwagger()
4740
async uploadAvatar(
4841
@ExtractFastifyFile() fileDto: FileUploadDto,

src/modules/user/services/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { UserSettingsService } from './settings.service';
2+
export { UserService } from './user.service';
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
Inject,
3+
Injectable,
4+
InternalServerErrorException,
5+
NotFoundException,
6+
} from '@nestjs/common';
7+
import { IUserRepository } from '../repository/user.repository.interface';
8+
import type { UpdateNotificationsDto } from '../dtos';
9+
import { createId } from '@paralleldrive/cuid2';
10+
11+
@Injectable()
12+
export class UserSettingsService {
13+
constructor(
14+
@Inject('IUserRepository')
15+
private readonly userRepo: IUserRepository,
16+
) {}
17+
18+
private throwUserNotFound() {
19+
throw new NotFoundException({
20+
code: 'USER_NOT_FOUND',
21+
message: 'Пользователь не найден в системе',
22+
});
23+
}
24+
25+
public updateNotifications = async (id: string, dto: UpdateNotificationsDto) => {
26+
const keysToUpdate = Object.keys(dto);
27+
if (keysToUpdate.length === 0) {
28+
return {
29+
success: true,
30+
message: 'Изменений не обнаружено',
31+
};
32+
}
33+
34+
const user = await this.userRepo.findById(id);
35+
if (!user) this.throwUserNotFound();
36+
37+
try {
38+
const isUpdated = await this.userRepo.updateNotifications(id, {
39+
email: dto.email,
40+
push: dto.push,
41+
});
42+
43+
if (!isUpdated) {
44+
throw new InternalServerErrorException(
45+
'Ошибка при сохранении настроек уведомлений',
46+
);
47+
}
48+
49+
await this.userRepo.logActivity({
50+
id: createId(),
51+
userId: id,
52+
eventType: 'NOTIFICATIONS_UPDATED',
53+
});
54+
55+
return {
56+
success: true,
57+
message: 'Настройки уведомлений обновлены',
58+
};
59+
} catch (error) {
60+
throw error;
61+
}
62+
};
63+
}
Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import {
44
InternalServerErrorException,
55
NotFoundException,
66
} from '@nestjs/common';
7-
import { IUserRepository } from './repository/user.repository.interface';
8-
import { UpdateNotificationsDto, UpdateProfileDto } from './dtos';
7+
import { IUserRepository } from '../repository/user.repository.interface';
8+
import type { UpdateProfileDto } from '../dtos';
99
import { createId } from '@paralleldrive/cuid2';
10-
import { IUserMedia, USER_MEDIA_TOKEN } from '../media/interfaces/user-media.interface';
11-
import { FileUploadDto } from '../media/dtos';
10+
import { IUserMedia, USER_MEDIA_TOKEN } from '../../media/interfaces/user-media.interface';
11+
import type { FileUploadDto } from '../../media/dtos';
1212

1313
@Injectable()
1414
export class UserService {
@@ -74,45 +74,6 @@ export class UserService {
7474
}
7575
};
7676

77-
public updateNotifications = async (id: string, dto: UpdateNotificationsDto) => {
78-
const keysToUpdate = Object.keys(dto);
79-
if (keysToUpdate.length === 0) {
80-
return {
81-
success: true,
82-
message: 'Изменений не обнаружено',
83-
};
84-
}
85-
86-
const user = await this.userRepo.findById(id);
87-
if (!user) this.throwUserNotFound();
88-
89-
try {
90-
const isUpdated = await this.userRepo.updateNotifications(id, {
91-
email: dto.email,
92-
push: dto.push,
93-
});
94-
95-
if (!isUpdated) {
96-
throw new InternalServerErrorException(
97-
'Ошибка при сохранении настроек уведомлений',
98-
);
99-
}
100-
101-
await this.userRepo.logActivity({
102-
id: createId(),
103-
userId: id,
104-
eventType: 'NOTIFICATIONS_UPDATED',
105-
});
106-
107-
return {
108-
success: true,
109-
message: 'Настройки уведомлений обновлены',
110-
};
111-
} catch (error) {
112-
throw error;
113-
}
114-
};
115-
11677
public getActivity = async (id: string, page: number, limit: number) => {
11778
const safeLimit = Math.min(limit, 50);
11879
const offset = (page - 1) * safeLimit;

src/modules/user/user.module.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Module } from '@nestjs/common';
2-
import { UserController } from './controller';
3-
import { UserService } from './user.service';
2+
import { UserController, UserSettingsController } from './controller';
3+
import { UserService } from './services/user.service';
44
import { UserRepository } from './repository/user.repository';
55
import { CreateUserCommand, FindOneUserCommand, UpdatePassUserCommand } from './commands';
66
import { MediaModule } from '../media/media.module';
7+
import { UserSettingsService } from './services';
78

89
const REPOSITORY = {
910
provide: 'IUserRepository',
@@ -14,8 +15,8 @@ const COMMANDS = [CreateUserCommand, FindOneUserCommand, UpdatePassUserCommand];
1415

1516
@Module({
1617
imports: [MediaModule],
17-
controllers: [UserController],
18-
providers: [...COMMANDS, REPOSITORY, UserService],
18+
controllers: [UserController, UserSettingsController],
19+
providers: [...COMMANDS, REPOSITORY, UserService, UserSettingsService],
1920
exports: [...COMMANDS],
2021
})
2122
export class UserModule {}

0 commit comments

Comments
 (0)