From 3dc9dfe59393e7d4b112e2c9188ab8d78a1cec1f Mon Sep 17 00:00:00 2001 From: okjodom Date: Mon, 25 Nov 2024 15:50:24 +0300 Subject: [PATCH] feat: persist shares in db --- apps/shares/.env.manual | 1 + apps/shares/src/db/index.ts | 2 ++ apps/shares/src/db/shares.repository.ts | 17 ++++++++++++ apps/shares/src/db/shares.schema.ts | 13 +++++++++ apps/shares/src/shares.module.ts | 10 +++++-- apps/shares/src/shares.service.ts | 29 +++++++++++++++------ libs/common/src/database/abstract.schema.ts | 1 - 7 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 apps/shares/src/db/index.ts create mode 100644 apps/shares/src/db/shares.repository.ts create mode 100644 apps/shares/src/db/shares.schema.ts diff --git a/apps/shares/.env.manual b/apps/shares/.env.manual index 5cd5134..a729cb1 100644 --- a/apps/shares/.env.manual +++ b/apps/shares/.env.manual @@ -1,2 +1,3 @@ NODE_ENV='development' SHARES_GRPC_URL='0.0.0.0:4070' +DATABASE_URL=mongodb://bs:password@mongodb:27017 diff --git a/apps/shares/src/db/index.ts b/apps/shares/src/db/index.ts new file mode 100644 index 0000000..2bf1629 --- /dev/null +++ b/apps/shares/src/db/index.ts @@ -0,0 +1,2 @@ +export * from './shares.repository'; +export * from './shares.schema'; diff --git a/apps/shares/src/db/shares.repository.ts b/apps/shares/src/db/shares.repository.ts new file mode 100644 index 0000000..4f229a8 --- /dev/null +++ b/apps/shares/src/db/shares.repository.ts @@ -0,0 +1,17 @@ +import { Model } from 'mongoose'; +import { InjectModel } from '@nestjs/mongoose'; +import { Injectable, Logger } from '@nestjs/common'; +import { AbstractRepository } from '@bitsacco/common'; +import { SharesDocument } from './shares.schema'; + +@Injectable() +export class SharesRepository extends AbstractRepository { + protected readonly logger = new Logger(SharesRepository.name); + + constructor( + @InjectModel(SharesDocument.name) + reservationModel: Model, + ) { + super(reservationModel); + } +} diff --git a/apps/shares/src/db/shares.schema.ts b/apps/shares/src/db/shares.schema.ts new file mode 100644 index 0000000..c791838 --- /dev/null +++ b/apps/shares/src/db/shares.schema.ts @@ -0,0 +1,13 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { AbstractDocument } from '@bitsacco/common'; + +@Schema({ versionKey: false }) +export class SharesDocument extends AbstractDocument { + @Prop({ type: String, required: true }) + userId: string; + + @Prop({ type: Number, required: true }) + quantity: number; +} + +export const SharesSchema = SchemaFactory.createForClass(SharesDocument); diff --git a/apps/shares/src/shares.module.ts b/apps/shares/src/shares.module.ts index ca94701..599b4e2 100644 --- a/apps/shares/src/shares.module.ts +++ b/apps/shares/src/shares.module.ts @@ -1,9 +1,10 @@ import * as Joi from 'joi'; import { Module } from '@nestjs/common'; -import { LoggerModule } from '@bitsacco/common'; +import { DatabaseModule, LoggerModule } from '@bitsacco/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { SharesController } from './shares.controller'; import { SharesService } from './shares.service'; +import { SharesDocument, SharesRepository, SharesSchema } from './db'; @Module({ imports: [ @@ -12,11 +13,16 @@ import { SharesService } from './shares.service'; validationSchema: Joi.object({ NODE_ENV: Joi.string().required(), SHARES_GRPC_URL: Joi.string().required(), + DATABASE_URL: Joi.string().required(), }), }), + DatabaseModule, + DatabaseModule.forFeature([ + { name: SharesDocument.name, schema: SharesSchema }, + ]), LoggerModule, ], controllers: [SharesController], - providers: [SharesService, ConfigService], + providers: [SharesService, ConfigService, SharesRepository], }) export class SharesModule {} diff --git a/apps/shares/src/shares.service.ts b/apps/shares/src/shares.service.ts index 8edc83f..4420977 100644 --- a/apps/shares/src/shares.service.ts +++ b/apps/shares/src/shares.service.ts @@ -1,11 +1,12 @@ import { Injectable, Logger } from '@nestjs/common'; import { BuySharesDto, ShareDetailResponse } from '@bitsacco/common'; +import { SharesRepository } from './db'; @Injectable() export class SharesService { private readonly logger = new Logger(SharesService.name); - constructor() { + constructor(private readonly shares: SharesRepository) { this.logger.log('SharesService created'); } @@ -15,15 +16,27 @@ export class SharesService { }: BuySharesDto): Promise { this.logger.debug(`Buying ${quantity} Bitsacco shares for ${userId}`); + await this.shares.create({ + userId, + quantity, + }); + + const allShares = await this.shares.find({ userId }); + const totalShares = allShares.reduce( + (sum, share) => sum + share.quantity, + 0, + ); + const shares = allShares + .map((share) => ({ + quantity: share.quantity, + purchasedAtUnix: Number(share.createdAt), + })) + .reverse(); + const res: ShareDetailResponse = { userId, - totalShares: quantity, - shares: [ - { - quantity, - purchasedAtUnix: new Date().getTime(), - }, - ], + totalShares, + shares, }; return Promise.resolve(res); diff --git a/libs/common/src/database/abstract.schema.ts b/libs/common/src/database/abstract.schema.ts index 80e15a0..6e7e3d3 100644 --- a/libs/common/src/database/abstract.schema.ts +++ b/libs/common/src/database/abstract.schema.ts @@ -1,7 +1,6 @@ import { v4 as uuidv4 } from 'uuid'; import { SchemaTypes } from 'mongoose'; import { Prop, Schema } from '@nestjs/mongoose'; -import { UUID } from 'crypto'; @Schema() export class AbstractDocument {