diff --git a/src/app.module.ts b/src/app.module.ts index ea50e85..9c40454 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -15,6 +15,9 @@ import { CurrentUserEnhancer } from './issue-enhancers/current-user-enhancer'; import { CustomFieldsEnhancer } from './issue-enhancers/custom-fields-enhancer'; import { PersonalNotificationsService } from './notifications/personal-notifications.service'; import { StatusChangeNotificationsService } from './notifications/status-change-notifications.service'; +import { ChangesCacheWriterService } from './changes-cache-writer/changes-cache-writer.service'; +import { Issues } from '@app/event-emitter/couchdb-datasources/issues'; +import { Users } from '@app/event-emitter/couchdb-datasources/users'; @Module({ imports: [ @@ -32,6 +35,7 @@ import { StatusChangeNotificationsService } from './notifications/status-change- StatusChangeNotificationsService, Changes, RedminePublicUrlConverter, + ChangesCacheWriterService, ], }) export class AppModule implements OnModuleInit { @@ -45,9 +49,14 @@ export class AppModule implements OnModuleInit { private customFieldsEnhancer: CustomFieldsEnhancer, private currentUserEnhancer: CurrentUserEnhancer, private statusChangeNotificationsService: StatusChangeNotificationsService, + private changesCacheWriterService: ChangesCacheWriterService, ) {} onModuleInit() { + Issues.getDatasource(); + Users.getDatasource(); + Changes.getDatasource(); + this.enhancerService.addEnhancer([ this.timestampEnhancer, this.customFieldsEnhancer, @@ -93,15 +102,25 @@ export class AppModule implements OnModuleInit { switchMap(async (saveResult) => { // eslint-disable-next-line prettier/prettier this.logger.debug(`statusChangeNotificationsService.getChanges started`); - await this.statusChangeNotificationsService.getChanges(saveResult); + const changes = + await this.statusChangeNotificationsService.getChanges(saveResult); // eslint-disable-next-line prettier/prettier this.logger.debug(`statusChangeNotificationsService.getChanges successed`); - return saveResult; + return { changes, saveResult }; + }), + switchMap(async (args) => { + this.logger.debug(`Save changes in couchdb started`); + const promises = args.changes.map((c) => + this.changesCacheWriterService.saveChange(c), + ); + await Promise.all(promises); + this.logger.debug('Save changes in couchdb successed'); + return args; }), ) - .subscribe(async (saveResult) => { + .subscribe(async (args) => { this.logger.debug( - `Save result process success finished, issue_id = ${saveResult.current.id}`, + `Save result process success finished, issue_id = ${args.saveResult.current.id}`, ); }); } diff --git a/src/changes-cache-writer/changes-cache-writer.service.ts b/src/changes-cache-writer/changes-cache-writer.service.ts new file mode 100644 index 0000000..375dad1 --- /dev/null +++ b/src/changes-cache-writer/changes-cache-writer.service.ts @@ -0,0 +1,54 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { randomUUID } from 'crypto'; +import nano from 'nano'; +import { Subject } from 'rxjs'; +import { Changes } from 'src/couchdb-datasources/changes'; +import { Change } from 'src/models/change.model'; + +@Injectable() +export class ChangesCacheWriterService { + private logger = new Logger(ChangesCacheWriterService.name); + + subject = new Subject(); + + constructor(private changes: Changes) {} + + async saveChange(change: Change): Promise { + this.logger.debug( + `saveChange started, ` + + `issue_id = ${change.issue_id}, ` + + `initiator.name = ${change.initiator.name}`, + ); + if (!change) { + this.logger.debug(`saveChange successed, no data for saving`); + return; + } + const changesDb = await this.changes.getDatasource(); + if (!changesDb) { + this.logger.error(`saveChange failed, changesDb is undefined or null`); + return; + } + const item: Change & nano.MaybeDocument = { ...change }; + item._id = this.getId(); + if (!item) { + this.logger.debug(`saveChange successed, no data for saving`); + return; + } + try { + await changesDb.insert(item); + } catch (ex) { + this.logger.error(`saveChange failed, error = ${ex}`); + return; + } + this.subject.next(change); + this.logger.debug( + `saveChange successed, ` + + `issue_id = ${change.issue_id}, ` + + `initiator.name = ${change.initiator.name}`, + ); + } + + private getId(): string { + return randomUUID(); + } +} diff --git a/src/couchdb-datasources/changes.ts b/src/couchdb-datasources/changes.ts index 5e742d5..c90a12b 100644 --- a/src/couchdb-datasources/changes.ts +++ b/src/couchdb-datasources/changes.ts @@ -1,6 +1,7 @@ import { CouchDb } from '@app/event-emitter/couchdb-datasources/couchdb'; import { Injectable, Logger } from '@nestjs/common'; import nano from 'nano'; +import { Change } from 'src/models/change.model'; import configuration from '../configs/app'; const config = configuration(); @@ -11,9 +12,7 @@ export class Changes { private static changesDb = null; private static initilized = false; - // TODO: Указать полные типы данных - - static async getDatasource(): Promise> { + static async getDatasource(): Promise> { if (Changes.initilized) { return Changes.changesDb; } @@ -25,11 +24,12 @@ export class Changes { await n.db.create(changesDbName); } Changes.changesDb = await n.db.use(changesDbName); + Changes.initilized = true; Changes.logger.log(`Connected to changes db - ${changesDbName}`); return Changes.changesDb; } - async getDatasource(): Promise> { + async getDatasource(): Promise> { return await Changes.getDatasource(); } }