Skip to content

Commit

Permalink
9-implement-data-service (#10)
Browse files Browse the repository at this point in the history
* Fix remove sermicolon from file

* Add database config

* Add entities to database

* Add base repository

* Add DatabaseModule to nestjs

* Add entites to am module

* Fix entity imports and formatting in asset-management module

* Add new repository classes for asset exchange, asset, delivery data, exchange, and trading data

* Update testRegex in package.json to include both .test.ts and .spec.ts files

* Update base.repository.ts to include findOneBy method

* Add ExchangeService and ExchangeService test

* Fix imports and configuration in DatabaseModule

* Add ExchangeRepository to asset-management module

* Update ExchangeService test to include additional properties in create method

* Add asset management service tests and implementations
  • Loading branch information
danishjoseph authored Apr 20, 2024
1 parent 493ab98 commit 3565c93
Show file tree
Hide file tree
Showing 27 changed files with 603 additions and 14 deletions.
12 changes: 6 additions & 6 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DB_HOST="";
DB_PORT=;
DB_USERNAME="";
DB_PASSWORD="";
DB_NAME="";
SYNCHRONIZE=;
DB_HOST=""
DB_PORT=
DB_USERNAME=""
DB_PASSWORD=""
DB_NAME=""
SYNCHRONIZE=
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"testRegex": ".*\\.(test|spec)\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import { AssetManagementModule } from './asset-management/asset-management.module';
import { DatabaseModule } from './database.module';

@Module({
Expand All @@ -11,6 +12,7 @@ import { DatabaseModule } from './database.module';
envFilePath: ['.env'],
}),
DatabaseModule,
AssetManagementModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
37 changes: 37 additions & 0 deletions src/asset-management/asset-management.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AssetExchange } from './entities/asset-exchange.entity';
import { Asset } from './entities/asset.entity';
import { DeliveryData } from './entities/delivery-data.entity';
import { Exchange } from './entities/exchange.entity';
import { TradingData } from './entities/trading-data.entity';
import {
AssetExchangeRepository,
AssetRepository,
DeliveryDataRepository,
ExchangeRepository,
TradingDataRepository,
} from './repositories';
import { ExchangeService } from './services/exchange.service';

@Module({
imports: [
TypeOrmModule.forFeature([
Asset,
Exchange,
AssetExchange,
TradingData,
DeliveryData,
]),
],
providers: [
AssetRepository,
ExchangeRepository,
AssetExchangeRepository,
TradingDataRepository,
DeliveryDataRepository,
ExchangeService,
],
exports: [ExchangeService],
})
export class AssetManagementModule {}
23 changes: 23 additions & 0 deletions src/asset-management/entities/asset-exchange.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Entity, PrimaryGeneratedColumn, ManyToOne, OneToMany } from 'typeorm';
import { Asset } from './asset.entity';
import { Exchange } from './exchange.entity';
import { TradingData } from './trading-data.entity';
import { DeliveryData } from './delivery-data.entity';

@Entity()
export class AssetExchange {
@PrimaryGeneratedColumn()
id: number;

@ManyToOne(() => Asset, (asset) => asset.assetExchanges)
asset: Asset;

@ManyToOne(() => Exchange, (exchange) => exchange.assetExchanges)
exchange: Exchange;

@OneToMany(() => TradingData, (tradingData) => tradingData)
tradingData: TradingData[];

@OneToMany(() => DeliveryData, (deliveryData) => deliveryData)
deliveryData: DeliveryData[];
}
37 changes: 37 additions & 0 deletions src/asset-management/entities/asset.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Entity, Column, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { AssetExchange } from './asset-exchange.entity';

export enum AssetType {
EQUITY = 'EQUITY',
DEBT = 'DEBT',
}

@Entity('assets')
export class Asset {
@PrimaryGeneratedColumn()
id: number;

@Column({ type: 'varchar', length: 50, nullable: false, unique: true })
isin: string;

@Column({ type: 'varchar', length: 50, nullable: true })
symbol: string;

@Column({ type: 'varchar', length: 255, nullable: false })
name: string;

@Column({ type: 'varchar', length: 50, nullable: true })
assetExchangeCode: string;

@Column({ type: 'float', nullable: false })
faceValue: number;

@Column({ type: 'varchar', length: 50, nullable: true })
industry: string;

@Column({ type: 'varchar', length: 50, nullable: true })
sector: string;

@OneToMany(() => AssetExchange, (assetExchange) => assetExchange.asset)
assetExchanges: AssetExchange[];
}
26 changes: 26 additions & 0 deletions src/asset-management/entities/delivery-data.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Entity, Column, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { AssetExchange } from './asset-exchange.entity';

@Entity()
export class DeliveryData {
@PrimaryGeneratedColumn()
id: number;

@Column({ type: 'date' })
date: Date;

@Column({ type: 'int', nullable: true })
deliveryQuantity: number;

@Column({ type: 'int', nullable: true })
deliveryPercentage: number;

@ManyToOne(
() => AssetExchange,
(assetExchange) => assetExchange.tradingData,
{
onDelete: 'CASCADE',
},
)
assetExchange: AssetExchange;
}
24 changes: 24 additions & 0 deletions src/asset-management/entities/exchange.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
Unique,
OneToMany,
} from 'typeorm';
import { AssetExchange } from './asset-exchange.entity';

@Entity()
@Unique(['name', 'abbreviation'])
export class Exchange {
@PrimaryGeneratedColumn()
id: number;

@Column({ nullable: false })
name: string;

@Column({ nullable: false })
abbreviation: string;

@OneToMany(() => AssetExchange, (assetExchange) => assetExchange.exchange)
assetExchanges: AssetExchange[];
}
5 changes: 5 additions & 0 deletions src/asset-management/entities/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './asset.entity';
export * from './asset-exchange.entity';
export * from './delivery-data.entity';
export * from './exchange.entity';
export * from './trading-data.entity';
47 changes: 47 additions & 0 deletions src/asset-management/entities/trading-data.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Entity, Column, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { AssetExchange } from './asset-exchange.entity';

@Entity()
export class TradingData {
@PrimaryGeneratedColumn()
id: number;

@Column({ type: 'date' })
date: Date;

@Column({ type: 'float', nullable: false })
open: number;

@Column({ type: 'float', nullable: false })
high: number;

@Column({ type: 'float', nullable: false })
low: number;

@Column({ type: 'float', nullable: false })
close: number;

@Column({ type: 'float', nullable: false })
lastPrice: number;

@Column({ type: 'float', nullable: false })
previousClose: number;

@Column({ type: 'bigint', nullable: false })
volume: number;

@Column({ type: 'float', nullable: false })
turnover: number;

@Column({ type: 'int', nullable: true })
totalTrades: number;

@ManyToOne(
() => AssetExchange,
(assetExchange) => assetExchange.tradingData,
{
onDelete: 'CASCADE',
},
)
assetExchange: AssetExchange;
}
13 changes: 13 additions & 0 deletions src/asset-management/repositories/asset-exchange.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AssetExchange } from '../entities';
import { BaseRepository } from './base.repository';

export class AssetExchangeRepository extends BaseRepository<AssetExchange> {
constructor(
@InjectRepository(AssetExchange)
assetExchangeRepository: Repository<AssetExchange>,
) {
super(assetExchangeRepository);
}
}
13 changes: 13 additions & 0 deletions src/asset-management/repositories/asset.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Asset } from '../entities';
import { BaseRepository } from './base.repository';
import { Repository } from 'typeorm';

export class AssetRepository extends BaseRepository<Asset> {
constructor(
@InjectRepository(Asset)
assetRepository: Repository<Asset>,
) {
super(assetRepository);
}
}
53 changes: 53 additions & 0 deletions src/asset-management/repositories/base.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Repository,
FindOneOptions,
SelectQueryBuilder,
FindOptionsWhere,
} from 'typeorm';

export interface DatabaseRepository<T> {
findAll(): Promise<T[]>;
findById(id: any): Promise<T | null>;
create(item: T): Promise<T>;
update(id: string, item: T): Promise<T | null>;
delete(id: string): Promise<void>;
createQueryBuilder(alias: string): SelectQueryBuilder<T>;
}

export abstract class BaseRepository<T> implements DatabaseRepository<T> {
constructor(protected readonly repository: Repository<T>) {}

async findAll(): Promise<T[]> {
return this.repository.find();
}

async findById(id: any): Promise<T | null> {
return this.repository.findOne(id);
}

async findOneBy(props: FindOptionsWhere<T>): Promise<T | null> {
return this.repository.findOneBy(props);
}

async create(item: T): Promise<T> {
return this.repository.save(item);
}

async update(id: string, item: T): Promise<T | null> {
const existingItem = await this.repository.findOne(id as FindOneOptions<T>);
if (!existingItem) {
return null;
}
const updatedItem = { ...existingItem, ...item };
await this.repository.save(updatedItem);
return updatedItem;
}

async delete(id: string): Promise<void> {
await this.repository.delete(id);
}

createQueryBuilder(alias: string): SelectQueryBuilder<T> {
return this.repository.createQueryBuilder(alias);
}
}
13 changes: 13 additions & 0 deletions src/asset-management/repositories/delivery-data.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DeliveryData } from '../entities';
import { BaseRepository } from './base.repository';

export class DeliveryDataRepository extends BaseRepository<DeliveryData> {
constructor(
@InjectRepository(DeliveryData)
deliveryDataRepository: Repository<DeliveryData>,
) {
super(deliveryDataRepository);
}
}
13 changes: 13 additions & 0 deletions src/asset-management/repositories/exchange.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Exchange } from '../entities';
import { BaseRepository } from './base.repository';

export class ExchangeRepository extends BaseRepository<Exchange> {
constructor(
@InjectRepository(Exchange)
exchangeRepository: Repository<Exchange>,
) {
super(exchangeRepository);
}
}
6 changes: 6 additions & 0 deletions src/asset-management/repositories/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './base.repository';
export * from './exchange.repository';
export * from './asset.repository';
export * from './trading-data.repository';
export * from './delivery-data.repository';
export * from './asset-exchange.repository';
13 changes: 13 additions & 0 deletions src/asset-management/repositories/trading-data.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TradingData } from '../entities';
import { BaseRepository } from './base.repository';

export class TradingDataRepository extends BaseRepository<TradingData> {
constructor(
@InjectRepository(TradingData)
tradingDataRepository: Repository<TradingData>,
) {
super(tradingDataRepository);
}
}
Loading

0 comments on commit 3565c93

Please sign in to comment.