Skip to content

Commit 529016d

Browse files
committed
feat: improve migrations
1 parent e07e8cc commit 529016d

18 files changed

+311
-160
lines changed

apps/api-gateway/src/modules/auth/auth.controller.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class LoginResponseBody {
1515
}
1616

1717
class RegisterRequestBody {
18-
@ApiProperty() username: string;
1918
@ApiProperty() email: string;
2019
@ApiProperty() password: string;
2120
@ApiProperty({ required: false }) name?: string;
@@ -25,22 +24,19 @@ class RegisterRequestBody {
2524

2625
class RegisterResponseBody {
2726
@ApiProperty() id: string;
28-
@ApiProperty() username: string;
2927
@ApiProperty({ required: false }) email?: string;
3028
@ApiProperty({ required: false }) name?: string;
3129
@ApiProperty({ required: false }) avatar?: string;
3230
@ApiProperty({ required: false }) bio?: string;
3331

3432
constructor(params: {
3533
id: string;
36-
username: string;
3734
email?: string;
3835
name?: string;
3936
avatar?: string;
4037
bio?: string;
4138
}) {
4239
this.id = params.id;
43-
this.username = params.username;
4440
this.email = params.email;
4541
this.name = params.name;
4642
this.avatar = params.avatar;
@@ -69,7 +65,7 @@ export class AuthController {
6965
const user = await this.authService.registerNewUser(body);
7066
return new RegisterResponseBody({
7167
id: user.id,
72-
username: user.username,
68+
email: user.email,
7369
name: user.name,
7470
avatar: user.avatar,
7571
bio: user.bio,

apps/api-gateway/src/modules/auth/auth.service.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ export class AuthService {
3030
public static PASSWORD_SALT_ROUNDS = 10;
3131

3232
async registerNewUser(params: {
33-
username: string;
33+
email: string;
3434
password: string;
3535
name?: string;
3636
avatar?: string;
3737
bio?: string;
3838
}): Promise<UserEntity> {
39-
const username = params.username?.trim();
39+
const email = params.email?.trim();
4040
const { password, name, avatar, bio } = params;
4141

42-
if (!username || username.length < 5) {
43-
throw new BadRequestException('Username must be of minimum 5 characters');
42+
if (!email || email.length < 5) {
43+
throw new BadRequestException('email must be of minimum 5 characters');
4444
}
4545

4646
if (!password || password.length < 8) {
@@ -53,16 +53,16 @@ export class AuthService {
5353
);
5454
}
5555

56-
const usernameAlreadyExists = await this.userRepo.findOne({
57-
where: { username },
56+
const alreadyExists = await this.userRepo.findOne({
57+
where: { email },
5858
});
5959

60-
if (usernameAlreadyExists) {
61-
throw new ConflictException('This username is already taken!');
60+
if (alreadyExists) {
61+
throw new ConflictException('This account is already exists!');
6262
}
6363

6464
const newUser = this.userRepo.create({
65-
username,
65+
email,
6666
name,
6767
avatar,
6868
bio,
@@ -79,15 +79,17 @@ export class AuthService {
7979
userId: string,
8080
password: string,
8181
): Promise<PasswordEntity> {
82-
const existing = await this.passwordRepo.findOne({ where: { userId } });
82+
const existing = await this.passwordRepo.findOne({
83+
where: { user_id: userId },
84+
});
8385
if (existing) {
8486
throw new UnauthorizedException(
8587
'This user already has a password, cannot set new password',
8688
);
8789
}
8890

8991
const newPassword = new PasswordEntity();
90-
newPassword.userId = userId;
92+
newPassword.user_id = userId;
9193
newPassword.password = await this.passToHash(password);
9294
return await this.passwordRepo.save(newPassword);
9395
}
@@ -96,24 +98,23 @@ export class AuthService {
9698
const user = await this.userRepo.findOne({ where: { email } });
9799

98100
if (!user) {
99-
throw new NotFoundException('Username does not exist');
101+
throw new NotFoundException('Account does not exist');
100102
}
101103
const userPassword = await this.passwordRepo.findOne({
102-
where: { userId: user.id },
104+
where: { user_id: user.id },
103105
});
104106
const passMatch = await this.matchPassHash(password, userPassword.password);
105107
if (!passMatch) {
106108
throw new UnauthorizedException('Password is wrong');
107109
}
108110
const session = new SessionsEntity();
109-
session.userId = userPassword.userId;
111+
session.userId = userPassword.user_id;
110112
const savedSession = await this.sessionRepo.save(session);
111113
await this.kafkaProducer.produce(
112114
{
113115
userId: user.id,
114116
email: user.email,
115117
sessionId: savedSession.id,
116-
username: user.username,
117118
loggedInAt: new Date().toISOString(),
118119
},
119120
KafkaTopics.UserLoggedIn,

apps/api-gateway/src/modules/auth/passwords.entity.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { UserEntity } from '../users/users.entity';
44

55
@Entity('passwords')
66
export class PasswordEntity extends YooBaseEntity {
7-
@Column()
8-
userId: string;
7+
@Column({ name: 'user_id' })
8+
user_id: string;
99

10-
@JoinColumn({ name: 'userId' })
10+
@JoinColumn({ name: 'user_id' })
1111
@OneToOne(() => UserEntity)
1212
user: UserEntity;
1313

apps/api-gateway/src/modules/commons/base.entity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
CreateDateColumn,
3+
PrimaryColumn,
34
PrimaryGeneratedColumn,
45
UpdateDateColumn,
56
} from 'typeorm';
@@ -8,7 +9,7 @@ import {
89
* Base entity which is extended by all entities in our application.
910
*/
1011
export abstract class YooBaseEntity {
11-
@PrimaryGeneratedColumn('uuid')
12+
@PrimaryColumn('uuid', { length: 36, unique: true })
1213
id: string;
1314

1415
@CreateDateColumn({ name: 'created_at' })

apps/api-gateway/src/modules/commons/db.config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TypeOrmModuleAsyncOptions,
1111
TypeOrmModuleOptions,
1212
} from '@nestjs/typeorm';
13+
import { migrations } from '../../../../../database/migrations';
1314

1415
export const entities = [
1516
UserEntity,
@@ -32,7 +33,10 @@ export const typeOrmConfig: TypeOrmModuleAsyncOptions = {
3233
username: configService.get<string>('DB_USER'),
3334
password: configService.get<string>('DB_PASSWORD'),
3435
database: configService.get<string>('DB_DATABASE_NAME'),
35-
synchronize: true,
36+
// Schema comes from migrations to avoid destructive sync updates
37+
synchronize: false,
38+
migrationsRun: true,
39+
migrations,
3640
logger: 'advanced-console',
3741
logging: 'all',
3842
namingStrategy: new SnakeNamingStrategy(),

apps/api-gateway/src/modules/commons/mocks/users.repository.mock.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export class MockUsersRepository extends Repository<UserEntity> {
66
async findOne() {
77
const mockUser: UserEntity = {
88
id: 'test-uuid',
9+
email: 'tE0xg@example.com',
910
name: 'John Doe',
1011
followeeCount: 1,
1112
followerCount: 1,

apps/api-gateway/src/modules/users/users.controller.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { CurrentUser } from '../commons/decorators/current-user.decorator';
2727
import { S3Service } from '../aws/s3.service';
2828

2929
class UserCreateRequestBody {
30-
@ApiProperty() username: string;
30+
@ApiProperty() email: string;
3131
@ApiProperty() password: string;
3232
@ApiPropertyOptional() name?: string;
3333
@ApiPropertyOptional() avatar?: string;
@@ -49,14 +49,14 @@ export class UsersController {
4949
private readonly s3Service: S3Service,
5050
) {}
5151

52-
@Get('/@:username')
53-
async getUserByUsername(@Param('username') username: string): Promise<any> {
54-
const user = await this.userService.getUserByUsername(username);
55-
if (!user) {
56-
throw new NotFoundException('User not found');
57-
}
58-
return user;
59-
}
52+
// @Get('/@:username')
53+
// async getUserByUsername(@Param('username') username: string): Promise<any> {
54+
// const user = await this.userService.getUserByUsername(username);
55+
// if (!user) {
56+
// throw new NotFoundException('User not found');
57+
// }
58+
// return user;
59+
// }
6060

6161
@Get('/:userid')
6262
async getUserByUserid(@Param('userid') userid: string): Promise<UserEntity> {

apps/api-gateway/src/modules/users/users.entity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { YooBaseEntity } from '../commons/base.entity';
44

55
@Entity('users')
66
export class UserEntity extends YooBaseEntity {
7-
@Column({ length: 30, nullable: false, unique: true })
7+
@Column({ length: 30, nullable: true, unique: true })
88
username: string;
99

1010
@Column({ length: 255, nullable: false, unique: true })

apps/api-gateway/src/modules/users/users.service.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class UsersService {
2727
* @description find a user with a given username
2828
* @returns {Promise<UserEntity>} user if found
2929
*/
30-
public async getUserByUsername(username: string): Promise<UserEntity> {
30+
public async getUserByEmail(username: string): Promise<UserEntity> {
3131
return await this.userRepo.findOne({ where: { username } });
3232
}
3333

@@ -54,9 +54,6 @@ export class UsersService {
5454
user: Partial<UserEntity>,
5555
password: string,
5656
): Promise<UserEntity> {
57-
if (user.username.length < 5)
58-
throw new BadRequestException('Username must be of minimum 5 characters');
59-
6057
if (password.length < 8)
6158
throw new BadRequestException('Password must be of minimum 8 characters');
6259

@@ -65,9 +62,9 @@ export class UsersService {
6562
'Password cannot contain the word password itself',
6663
);
6764

68-
const usernameAlreadyExists = await this.getUserByUsername(user.username);
69-
if (usernameAlreadyExists)
70-
throw new ConflictException('This username is already taken!');
65+
const alreadyExists = await this.getUserByEmail(user.email);
66+
if (alreadyExists)
67+
throw new ConflictException('Account already exists for this email');
7168

7269
const newUser = await this.userRepo.save(user);
7370

database/drop.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Logger } from '@nestjs/common';
2+
import dataSource from '../apps/api-gateway/src/modules/commons/data-source';
3+
4+
export const dropDatabase = async () => {
5+
const logger = new Logger('DBDrop');
6+
logger.verbose('db.drop.started');
7+
await dataSource.initialize();
8+
await dataSource.dropDatabase();
9+
await dataSource.destroy();
10+
logger.verbose('db.drop.finished');
11+
};

0 commit comments

Comments
 (0)