Skip to content

Commit 64de1ac

Browse files
authored
[Reputation Oracle] refactor: typeorm usage (#3154)
* fix: db entities usage bypassing repository * refactor: use typeorm Data Mapper instead of Active Record * refactor: cleanup typeorm configs * fix: entity schema out of datasource
1 parent b221003 commit 64de1ac

23 files changed

Lines changed: 94 additions & 103 deletions

packages/apps/reputation-oracle/server/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
"start:debug": "nest start --debug --watch",
1414
"start:prod": "node dist/src/main",
1515
"migration:create": "yarn build && typeorm-ts-node-commonjs migration:create",
16-
"migration:generate": "yarn build && typeorm-ts-node-commonjs migration:generate -d typeorm.config.ts",
17-
"migration:revert": "yarn build && typeorm-ts-node-commonjs migration:revert -d typeorm.config.ts",
18-
"migration:run": "yarn build && typeorm-ts-node-commonjs migration:run -d typeorm.config.ts",
19-
"migration:show": "yarn build && typeorm-ts-node-commonjs migration:show -d typeorm.config.ts",
16+
"migration:generate": "yarn build && typeorm-ts-node-commonjs migration:generate -d typeorm-migrations-datasource.ts",
17+
"migration:revert": "yarn build && typeorm-ts-node-commonjs migration:revert -d typeorm-migrations-datasource.ts",
18+
"migration:run": "yarn build && typeorm-ts-node-commonjs migration:run -d typeorm-migrations-datasource.ts",
19+
"migration:show": "yarn build && typeorm-ts-node-commonjs migration:show -d typeorm-migrations-datasource.ts",
2020
"docker:db:up": "docker compose up -d postgres && yarn migration:run",
2121
"docker:db:down": "docker compose down postgres",
2222
"setup:local": "ts-node ./test/setup.ts",

packages/apps/reputation-oracle/server/src/common/constants/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const NS = 'hmt';
1+
export const DATABASE_SCHEMA_NAME = 'hmt';
22
export const INITIAL_REPUTATION = 0;
33
export const JWT_STRATEGY_NAME = 'jwt-http';
44

packages/apps/reputation-oracle/server/src/database/base.entity.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
import {
2-
BaseEntity as OrmBaseEntity,
32
BeforeInsert,
43
BeforeUpdate,
54
Column,
65
PrimaryGeneratedColumn,
76
} from 'typeorm';
87

9-
export abstract class BaseEntity extends OrmBaseEntity {
8+
export abstract class BaseEntity {
109
@PrimaryGeneratedColumn()
11-
public id: number;
10+
id: number;
1211

1312
@Column({ type: 'timestamptz' })
14-
public createdAt: Date;
13+
createdAt: Date;
1514

1615
@Column({ type: 'timestamptz' })
17-
public updatedAt: Date;
16+
updatedAt: Date;
1817

1918
@BeforeInsert()
20-
public beforeInsert(): void {
19+
protected beforeInsert(): void {
2120
const date = new Date();
2221
this.createdAt = date;
2322
this.updatedAt = date;
2423
}
2524

2625
@BeforeUpdate()
27-
public beforeUpdate(): void {
26+
protected beforeUpdate(): void {
2827
const date = new Date();
2928
this.updatedAt = date;
3029
}

packages/apps/reputation-oracle/server/src/database/database.module.ts

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { Module } from '@nestjs/common';
22
import { TypeOrmModule } from '@nestjs/typeorm';
3-
import * as path from 'path';
43
import { LoggerOptions } from 'typeorm';
54
import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
65

7-
import { NS } from '../common/constants';
86
import { ReputationEntity } from '../modules/reputation/reputation.entity';
97
import { TokenEntity } from '../modules/auth/token.entity';
108
import { UserEntity } from '../modules/user/user.entity';
@@ -18,7 +16,6 @@ import { WebhookIncomingEntity } from '../modules/webhook/webhook-incoming.entit
1816
import { WebhookOutgoingEntity } from '../modules/webhook/webhook-outgoing.entity';
1917
import { EscrowCompletionEntity } from '../modules/escrow-completion/escrow-completion.entity';
2018
import { EscrowPayoutsBatchEntity } from '../modules/escrow-completion/escrow-payouts-batch.entity';
21-
import Environment from '../utils/environment';
2219

2320
import { TypeOrmLoggerModule, TypeOrmLoggerService } from './typeorm';
2421

@@ -37,9 +34,31 @@ import { TypeOrmLoggerModule, TypeOrmLoggerService } from './typeorm';
3734
? 'all'
3835
: ((loggerOptions as LoggerOptions) ?? false),
3936
);
37+
4038
return {
41-
name: 'default',
39+
name: 'default-connection',
4240
type: 'postgres',
41+
42+
...(databaseConfigService.url
43+
? {
44+
url: databaseConfigService.url,
45+
}
46+
: {
47+
host: databaseConfigService.host,
48+
port: databaseConfigService.port,
49+
username: databaseConfigService.user,
50+
password: databaseConfigService.password,
51+
database: databaseConfigService.database,
52+
}),
53+
ssl: databaseConfigService.ssl,
54+
55+
namingStrategy: new SnakeNamingStrategy(),
56+
/**
57+
* Schema synchronization should be done
58+
* via manually running migrations
59+
*/
60+
synchronize: false,
61+
migrationsRun: false,
4362
entities: [
4463
WebhookIncomingEntity,
4564
WebhookOutgoingEntity,
@@ -54,29 +73,9 @@ import { TypeOrmLoggerModule, TypeOrmLoggerService } from './typeorm';
5473
QualificationEntity,
5574
UserQualificationEntity,
5675
],
57-
// We are using migrations, synchronize should be set to false.
58-
synchronize: false,
59-
// Run migrations automatically,
60-
// you can disable this if you prefer running migration manually.
61-
migrationsTableName: NS,
62-
migrationsTransactionMode: 'each',
63-
namingStrategy: new SnakeNamingStrategy(),
76+
6477
logging: true,
65-
// Allow both start:prod and start:dev to use migrations
66-
// __dirname is either dist or server folder, meaning either
67-
// the compiled js in prod or the ts in dev.
68-
migrations: [path.join(__dirname, '/migrations/**/*{.ts,.js}')],
69-
//"migrations": ["dist/migrations/*{.ts,.js}"],
7078
logger: typeOrmLoggerService,
71-
url: databaseConfigService.url,
72-
host: databaseConfigService.host,
73-
port: databaseConfigService.port,
74-
username: databaseConfigService.user,
75-
password: databaseConfigService.password,
76-
database: databaseConfigService.database,
77-
keepConnectionAlive: Environment.isTest(),
78-
migrationsRun: false,
79-
ssl: databaseConfigService.ssl,
8079
};
8180
},
8281
}),

packages/apps/reputation-oracle/server/src/database/migrations/1694691302615-InitialMigration.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { NS } from '../../common/constants';
21
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
import { DATABASE_SCHEMA_NAME } from '../../common/constants';
33

44
export class InitialMigration1694776006387 implements MigrationInterface {
55
name = 'InitialMigration1694776006387';
66

77
public async up(queryRunner: QueryRunner): Promise<void> {
8-
await queryRunner.createSchema(NS, true);
8+
await queryRunner.createSchema(DATABASE_SCHEMA_NAME, true);
99
await queryRunner.query(
1010
`CREATE TYPE "hmt"."tokens_token_type_enum" AS ENUM('EMAIL', 'PASSWORD')`,
1111
);
@@ -61,6 +61,6 @@ export class InitialMigration1694776006387 implements MigrationInterface {
6161
await queryRunner.query(`DROP TYPE "hmt"."users_type_enum"`);
6262
await queryRunner.query(`DROP TABLE "hmt"."tokens"`);
6363
await queryRunner.query(`DROP TYPE "hmt"."tokens_token_type_enum"`);
64-
await queryRunner.dropSchema(NS);
64+
await queryRunner.dropSchema(DATABASE_SCHEMA_NAME);
6565
}
6666
}

packages/apps/reputation-oracle/server/src/modules/auth/auth.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ export class AuthService {
278278
);
279279

280280
if (existingToken) {
281-
await existingToken.remove();
281+
await this.tokenRepository.deleteOne(existingToken);
282282
}
283283

284284
const tokenEntity = new TokenEntity();

packages/apps/reputation-oracle/server/src/modules/auth/token.entity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99

1010
import { UserEntity } from '../user/user.entity';
1111
import { BaseEntity } from '../../database/base.entity';
12-
import { NS } from '../../common/constants';
12+
import { DATABASE_SCHEMA_NAME } from '../../common/constants';
1313
import { IBase } from '../../common/interfaces/base';
1414

1515
export enum TokenType {
@@ -23,7 +23,7 @@ export interface IToken extends IBase {
2323
type: TokenType;
2424
}
2525

26-
@Entity({ schema: NS, name: 'tokens' })
26+
@Entity({ schema: DATABASE_SCHEMA_NAME, name: 'tokens' })
2727
@Index(['type', 'userId'], { unique: true })
2828
export class TokenEntity extends BaseEntity implements IToken {
2929
@Column({ type: 'uuid', unique: true })

packages/apps/reputation-oracle/server/src/modules/auth/token.repository.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from '@nestjs/common';
22
import { BaseRepository } from '../../database/base.repository';
3-
import { DataSource, DeleteResult } from 'typeorm';
3+
import { DataSource } from 'typeorm';
44
import { TokenEntity, TokenType } from './token.entity';
55

66
@Injectable()
@@ -9,7 +9,7 @@ export class TokenRepository extends BaseRepository<TokenEntity> {
99
super(TokenEntity, dataSource);
1010
}
1111

12-
public async findOneByUuidAndType(
12+
async findOneByUuidAndType(
1313
uuid: string,
1414
type: TokenType,
1515
): Promise<TokenEntity | null> {
@@ -22,7 +22,7 @@ export class TokenRepository extends BaseRepository<TokenEntity> {
2222
});
2323
}
2424

25-
public async findOneByUserIdAndType(
25+
async findOneByUserIdAndType(
2626
userId: number,
2727
type: TokenType,
2828
): Promise<TokenEntity | null> {
@@ -35,10 +35,10 @@ export class TokenRepository extends BaseRepository<TokenEntity> {
3535
});
3636
}
3737

38-
public async deleteOneByTypeAndUserId(
38+
async deleteOneByTypeAndUserId(
3939
type: TokenType,
4040
userId: number,
41-
): Promise<DeleteResult> {
42-
return this.delete({ type, userId });
41+
): Promise<void> {
42+
await this.delete({ type, userId });
4343
}
4444
}

packages/apps/reputation-oracle/server/src/modules/cron-job/cron-job.entity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { BeforeInsert, Column, Entity, Index } from 'typeorm';
22

3-
import { NS } from '../../common/constants';
43
import { BaseEntity } from '../../database/base.entity';
4+
import { DATABASE_SCHEMA_NAME } from '../../common/constants';
55
import { ICronJob } from '../../common/interfaces/cron-job';
66
import { CronJobType } from '../../common/enums/cron-job';
77

8-
@Entity({ schema: NS, name: 'cron-jobs' })
8+
@Entity({ schema: DATABASE_SCHEMA_NAME, name: 'cron-jobs' })
99
@Index(['cronJobType'], { unique: true })
1010
export class CronJobEntity extends BaseEntity implements ICronJob {
1111
@Column({

packages/apps/reputation-oracle/server/src/modules/escrow-completion/escrow-completion.entity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Column, Entity, Index } from 'typeorm';
22

3-
import { NS } from '../../common/constants';
43
import { BaseEntity } from '../../database/base.entity';
4+
import { DATABASE_SCHEMA_NAME } from '../../common/constants';
55
import { EscrowCompletionStatus } from '../../common/enums';
66
import { ChainId } from '@human-protocol/sdk';
77

8-
@Entity({ schema: NS, name: 'escrow_completion_tracking' })
8+
@Entity({ schema: DATABASE_SCHEMA_NAME, name: 'escrow_completion_tracking' })
99
@Index(['escrowAddress', 'chainId'], { unique: true })
1010
export class EscrowCompletionEntity extends BaseEntity {
1111
@Column({ type: 'int' })

0 commit comments

Comments
 (0)